PR26069, strip/objcopy misaligned address accesses
[deliverable/binutils-gdb.git] / bfd / elfxx-tilegx.c
CommitLineData
aa137e4d 1/* TILE-Gx-specific support for ELF.
b3adc24a 2 Copyright (C) 2011-2020 Free Software Foundation, Inc.
aa137e4d
NC
3
4 This file is part of BFD, the Binary File Descriptor library.
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
20
aa137e4d 21#include "sysdep.h"
691bf19c 22#include "bfd.h"
aa137e4d
NC
23#include "libbfd.h"
24#include "elf-bfd.h"
25#include "elf/tilegx.h"
26#include "opcode/tilegx.h"
27#include "libiberty.h"
28#include "elfxx-tilegx.h"
29
30#define ABI_64_P(abfd) \
31 (get_elf_backend_data (abfd)->s->elfclass == ELFCLASS64)
32
33#define TILEGX_ELF_WORD_BYTES(htab) \
34 ((htab)->bytes_per_word)
35
36/* The size of an external RELA relocation. */
37#define TILEGX_ELF_RELA_BYTES(htab) \
38 ((htab)->bytes_per_rela)
39
40/* Both 32-bit and 64-bit tilegx encode this in an identical manner,
41 so just take advantage of that. */
42#define TILEGX_ELF_R_TYPE(r_info) \
43 ((r_info) & 0xFF)
44
45#define TILEGX_ELF_R_INFO(htab, in_rel, index, type) \
46 ((htab)->r_info (in_rel, index, type))
47
48#define TILEGX_ELF_R_SYMNDX(htab, r_info) \
49 ((htab)->r_symndx(r_info))
50
51#define TILEGX_ELF_DTPOFF_RELOC(htab) \
52 ((htab)->dtpoff_reloc)
53
54#define TILEGX_ELF_DTPMOD_RELOC(htab) \
55 ((htab)->dtpmod_reloc)
56
57#define TILEGX_ELF_TPOFF_RELOC(htab) \
58 ((htab)->tpoff_reloc)
59
60#define TILEGX_ELF_PUT_WORD(htab, bfd, val, ptr) \
61 ((htab)->put_word (bfd, val, ptr))
62
63/* The name of the dynamic interpreter. This is put in the .interp
64 section. */
65
66#define ELF64_DYNAMIC_INTERPRETER "/lib/ld.so.1"
67#define ELF32_DYNAMIC_INTERPRETER "/lib32/ld.so.1"
68
69
70static reloc_howto_type tilegx_elf_howto_table [] =
71{
72 /* This reloc does nothing. */
73 HOWTO (R_TILEGX_NONE, /* type */
74 0, /* rightshift */
6346d5ca
AM
75 3, /* size (0 = byte, 1 = short, 2 = long) */
76 0, /* bitsize */
aa137e4d
NC
77 FALSE, /* pc_relative */
78 0, /* bitpos */
6346d5ca 79 complain_overflow_dont, /* complain_on_overflow */
aa137e4d
NC
80 bfd_elf_generic_reloc, /* special_function */
81 "R_TILEGX_NONE", /* name */
82 FALSE, /* partial_inplace */
83 0, /* src_mask */
84 0, /* dst_mask */
85 FALSE), /* pcrel_offset */
86#ifdef BFD64
87 /* A 64 bit absolute relocation. */
88 HOWTO (R_TILEGX_64, /* type */
89 0, /* rightshift */
90 4, /* size (0 = byte, 1 = short, 2 = long) */
91 64, /* bitsize */
92 FALSE, /* pc_relative */
93 0, /* bitpos */
94 complain_overflow_dont, /* complain_on_overflow */
95 bfd_elf_generic_reloc, /* special_function */
96 "R_TILEGX_64", /* name */
97 FALSE, /* partial_inplace */
98 0, /* src_mask */
99 0xffffffffffffffffULL, /* dst_mask */
100 FALSE), /* pcrel_offset */
101#endif
102 /* A 32 bit absolute relocation. */
103 HOWTO (R_TILEGX_32, /* type */
104 0, /* rightshift */
105 2, /* size (0 = byte, 1 = short, 2 = long) */
106 32, /* bitsize */
107 FALSE, /* pc_relative */
108 0, /* bitpos */
109 complain_overflow_dont, /* complain_on_overflow */
110 bfd_elf_generic_reloc, /* special_function */
111 "R_TILEGX_32", /* name */
112 FALSE, /* partial_inplace */
113 0, /* src_mask */
114 0xffffffff, /* dst_mask */
115 FALSE), /* pcrel_offset */
116
117 /* A 16 bit absolute relocation. */
118 HOWTO (R_TILEGX_16, /* type */
119 0, /* rightshift */
120 1, /* size (0 = byte, 1 = short, 2 = long) */
121 16, /* bitsize */
122 FALSE, /* pc_relative */
123 0, /* bitpos */
124 complain_overflow_bitfield, /* complain_on_overflow */
125 bfd_elf_generic_reloc, /* special_function */
126 "R_TILEGX_16", /* name */
127 FALSE, /* partial_inplace */
128 0, /* src_mask */
129 0xffff, /* dst_mask */
130 FALSE), /* pcrel_offset */
131
132 /* An 8 bit absolute relocation. */
133 HOWTO (R_TILEGX_8, /* type */
134 0, /* rightshift */
135 0, /* size (0 = byte, 1 = short, 2 = long) */
136 8, /* bitsize */
137 FALSE, /* pc_relative */
138 0, /* bitpos */
139 complain_overflow_unsigned, /* complain_on_overflow */
140 bfd_elf_generic_reloc, /* special_function */
141 "R_TILEGX_8", /* name */
142 FALSE, /* partial_inplace */
143 0, /* src_mask */
144 0xff, /* dst_mask */
145 FALSE), /* pcrel_offset */
146#ifdef BFD64
147 /* A 64 bit pc-relative relocation. */
148 HOWTO (R_TILEGX_64_PCREL,/* type */
149 0, /* rightshift */
150 4, /* size (0 = byte, 1 = short, 2 = long) */
151 64, /* bitsize */
152 TRUE, /* pc_relative */
153 0, /* bitpos */
154 complain_overflow_dont, /* complain_on_overflow */
155 bfd_elf_generic_reloc, /* special_function */
156 "R_TILEGX_32_PCREL", /* name */
157 FALSE, /* partial_inplace */
158 0, /* src_mask */
159 0xffffffffffffffffULL, /* dst_mask */
160 TRUE), /* pcrel_offset */
161#endif
162 /* A 32 bit pc-relative relocation. */
163 HOWTO (R_TILEGX_32_PCREL,/* type */
164 0, /* rightshift */
165 2, /* size (0 = byte, 1 = short, 2 = long) */
166 32, /* bitsize */
167 TRUE, /* pc_relative */
168 0, /* bitpos */
169 complain_overflow_dont, /* complain_on_overflow */
170 bfd_elf_generic_reloc, /* special_function */
171 "R_TILEGX_32_PCREL", /* name */
172 FALSE, /* partial_inplace */
173 0, /* src_mask */
174 0xffffffff, /* dst_mask */
175 TRUE), /* pcrel_offset */
176
177 /* A 16 bit pc-relative relocation. */
178 HOWTO (R_TILEGX_16_PCREL,/* type */
179 0, /* rightshift */
180 1, /* size (0 = byte, 1 = short, 2 = long) */
181 16, /* bitsize */
182 TRUE, /* pc_relative */
183 0, /* bitpos */
184 complain_overflow_signed, /* complain_on_overflow */
185 bfd_elf_generic_reloc, /* special_function */
186 "R_TILEGX_16_PCREL", /* name */
187 FALSE, /* partial_inplace */
188 0, /* src_mask */
189 0xffff, /* dst_mask */
190 TRUE), /* pcrel_offset */
191
192 /* An 8 bit pc-relative relocation. */
193 HOWTO (R_TILEGX_8_PCREL, /* type */
194 0, /* rightshift */
195 0, /* size (0 = byte, 1 = short, 2 = long) */
196 8, /* bitsize */
197 TRUE, /* pc_relative */
198 0, /* bitpos */
199 complain_overflow_signed, /* complain_on_overflow */
200 bfd_elf_generic_reloc, /* special_function */
201 "R_TILEGX_8_PCREL",/* name */
202 FALSE, /* partial_inplace */
203 0, /* src_mask */
204 0xff, /* dst_mask */
205 TRUE), /* pcrel_offset */
206
207 /* A 16 bit relocation without overflow. */
208 HOWTO (R_TILEGX_HW0, /* type */
209 0, /* rightshift */
210 1, /* size (0 = byte, 1 = short, 2 = long) */
211 16, /* bitsize */
212 FALSE, /* pc_relative */
213 0, /* bitpos */
214 complain_overflow_dont,/* complain_on_overflow */
215 bfd_elf_generic_reloc, /* special_function */
216 "R_TILEGX_HW0", /* name */
217 FALSE, /* partial_inplace */
218 0, /* src_mask */
219 0xffff, /* dst_mask */
220 FALSE), /* pcrel_offset */
221
222 /* A 16 bit relocation without overflow. */
223 HOWTO (R_TILEGX_HW1, /* type */
224 16, /* rightshift */
225 1, /* size (0 = byte, 1 = short, 2 = long) */
226 16, /* bitsize */
227 FALSE, /* pc_relative */
228 0, /* bitpos */
229 complain_overflow_dont,/* complain_on_overflow */
230 bfd_elf_generic_reloc, /* special_function */
231 "R_TILEGX_HW1", /* name */
232 FALSE, /* partial_inplace */
233 0, /* src_mask */
234 0xffff, /* dst_mask */
235 FALSE), /* pcrel_offset */
236
237 /* A 16 bit relocation without overflow. */
238 HOWTO (R_TILEGX_HW2, /* type */
239 32, /* rightshift */
240 1, /* size (0 = byte, 1 = short, 2 = long) */
241 16, /* bitsize */
242 FALSE, /* pc_relative */
243 0, /* bitpos */
244 complain_overflow_dont,/* complain_on_overflow */
245 bfd_elf_generic_reloc, /* special_function */
246 "R_TILEGX_HW2", /* name */
247 FALSE, /* partial_inplace */
248 0, /* src_mask */
249 0xffff, /* dst_mask */
250 FALSE), /* pcrel_offset */
251
252 /* A 16 bit relocation without overflow. */
253 HOWTO (R_TILEGX_HW3, /* type */
254 48, /* rightshift */
255 1, /* size (0 = byte, 1 = short, 2 = long) */
256 16, /* bitsize */
257 FALSE, /* pc_relative */
258 0, /* bitpos */
259 complain_overflow_dont,/* complain_on_overflow */
260 bfd_elf_generic_reloc, /* special_function */
261 "R_TILEGX_HW3", /* name */
262 FALSE, /* partial_inplace */
263 0, /* src_mask */
264 0xffff, /* dst_mask */
265 FALSE), /* pcrel_offset */
266
267 /* A 16 bit relocation with overflow. */
268 HOWTO (R_TILEGX_HW0_LAST, /* type */
269 0, /* rightshift */
270 1, /* size (0 = byte, 1 = short, 2 = long) */
271 16, /* bitsize */
272 FALSE, /* pc_relative */
273 0, /* bitpos */
274 complain_overflow_signed,/* complain_on_overflow */
275 bfd_elf_generic_reloc, /* special_function */
276 "R_TILEGX_HW0_LAST", /* name */
277 FALSE, /* partial_inplace */
278 0, /* src_mask */
279 0xffff, /* dst_mask */
280 FALSE), /* pcrel_offset */
281
282 /* A 16 bit relocation with overflow. */
283 HOWTO (R_TILEGX_HW1_LAST, /* type */
284 16, /* rightshift */
285 1, /* size (0 = byte, 1 = short, 2 = long) */
286 16, /* bitsize */
287 FALSE, /* pc_relative */
288 0, /* bitpos */
289 complain_overflow_signed,/* complain_on_overflow */
290 bfd_elf_generic_reloc, /* special_function */
291 "R_TILEGX_HW1_LAST", /* name */
292 FALSE, /* partial_inplace */
293 0, /* src_mask */
294 0xffff, /* dst_mask */
295 FALSE), /* pcrel_offset */
296
297 /* A 16 bit relocation with overflow. */
298 HOWTO (R_TILEGX_HW2_LAST, /* type */
299 32, /* rightshift */
300 1, /* size (0 = byte, 1 = short, 2 = long) */
301 16, /* bitsize */
302 FALSE, /* pc_relative */
303 0, /* bitpos */
304 complain_overflow_signed,/* complain_on_overflow */
305 bfd_elf_generic_reloc, /* special_function */
306 "R_TILEGX_HW2_LAST", /* name */
307 FALSE, /* partial_inplace */
308 0, /* src_mask */
309 0xffff, /* dst_mask */
310 FALSE), /* pcrel_offset */
311
312 HOWTO (R_TILEGX_COPY, /* type */
313 0, /* rightshift */
314 0, /* size (0 = byte, 1 = short, 2 = long) */
315 0, /* bitsize */
316 FALSE, /* pc_relative */
317 0, /* bitpos */
318 complain_overflow_dont, /* complain_on_overflow */
319 bfd_elf_generic_reloc, /* special_function */
320 "R_TILEGX_COPY", /* name */
321 FALSE, /* partial_inplace */
322 0, /* src_mask */
323 0, /* dst_mask */
324 TRUE), /* pcrel_offset */
325
326 HOWTO (R_TILEGX_GLOB_DAT, /* type */
327 0, /* rightshift */
328 0, /* size (0 = byte, 1 = short, 2 = long) */
329 0, /* bitsize */
330 FALSE, /* pc_relative */
331 0, /* bitpos */
332 complain_overflow_dont, /* complain_on_overflow */
333 bfd_elf_generic_reloc, /* special_function */
334 "R_TILEGX_GLOB_DAT", /* name */
335 FALSE, /* partial_inplace */
336 0, /* src_mask */
337 0, /* dst_mask */
338 TRUE), /* pcrel_offset */
339
340 HOWTO (R_TILEGX_JMP_SLOT, /* type */
341 0, /* rightshift */
342 0, /* size (0 = byte, 1 = short, 2 = long) */
343 0, /* bitsize */
344 FALSE, /* pc_relative */
345 0, /* bitpos */
346 complain_overflow_dont, /* complain_on_overflow */
347 bfd_elf_generic_reloc, /* special_function */
348 "R_TILEGX_JMP_SLOT", /* name */
349 FALSE, /* partial_inplace */
350 0, /* src_mask */
351 0, /* dst_mask */
352 TRUE), /* pcrel_offset */
353
354 HOWTO (R_TILEGX_RELATIVE, /* type */
355 0, /* rightshift */
356 0, /* size (0 = byte, 1 = short, 2 = long) */
357 0, /* bitsize */
358 FALSE, /* pc_relative */
359 0, /* bitpos */
360 complain_overflow_dont, /* complain_on_overflow */
361 bfd_elf_generic_reloc, /* special_function */
362 "R_TILEGX_RELATIVE", /* name */
363 FALSE, /* partial_inplace */
364 0, /* src_mask */
365 0, /* dst_mask */
366 TRUE), /* pcrel_offset */
367
368 HOWTO (R_TILEGX_BROFF_X1, /* type */
369 TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, /* rightshift */
370 2, /* size (0 = byte, 1 = short, 2 = long) */
371 17, /* bitsize */
372 TRUE, /* pc_relative */
373 0, /* bitpos */
374 complain_overflow_signed, /* complain_on_overflow */
375 bfd_elf_generic_reloc, /* special_function */
376 "R_TILEGX_BROFF_X1", /* name */
377 FALSE, /* partial_inplace */
378 0, /* src_mask */
379 -1, /* dst_mask */
380 TRUE), /* pcrel_offset */
381
382 HOWTO (R_TILEGX_JUMPOFF_X1, /* type */
383 TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, /* rightshift */
384 2, /* size (0 = byte, 1 = short, 2 = long) */
385 27, /* bitsize */
386 TRUE, /* pc_relative */
387 0, /* bitpos */
388 complain_overflow_signed,/* complain_on_overflow */
389 bfd_elf_generic_reloc, /* special_function */
390 "R_TILEGX_JUMPOFF_X1", /* name */
391 FALSE, /* partial_inplace */
392 0, /* src_mask */
393 -1, /* dst_mask */
07d6d2b8 394 TRUE), /* pcrel_offset */
aa137e4d
NC
395
396 HOWTO (R_TILEGX_JUMPOFF_X1_PLT, /* type */
397 TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, /* rightshift */
398 2, /* size (0 = byte, 1 = short, 2 = long) */
399 27, /* bitsize */
400 TRUE, /* pc_relative */
401 0, /* bitpos */
402 complain_overflow_signed,/* complain_on_overflow */
403 bfd_elf_generic_reloc, /* special_function */
404 "R_TILEGX_JUMPOFF_X1_PLT", /* name */
405 FALSE, /* partial_inplace */
406 0, /* src_mask */
407 -1, /* dst_mask */
07d6d2b8 408 TRUE), /* pcrel_offset */
aa137e4d
NC
409
410#define TILEGX_IMM_HOWTO(name, size, bitsize) \
411 HOWTO (name, 0, size, bitsize, FALSE, 0, \
07d6d2b8
AM
412 complain_overflow_signed, bfd_elf_generic_reloc, \
413 #name, FALSE, 0, -1, FALSE)
aa137e4d
NC
414
415#define TILEGX_UIMM_HOWTO(name, size, bitsize) \
416 HOWTO (name, 0, size, bitsize, FALSE, 0, \
07d6d2b8
AM
417 complain_overflow_unsigned, bfd_elf_generic_reloc, \
418 #name, FALSE, 0, -1, FALSE)
aa137e4d
NC
419
420 TILEGX_IMM_HOWTO(R_TILEGX_IMM8_X0, 0, 8),
421 TILEGX_IMM_HOWTO(R_TILEGX_IMM8_Y0, 0, 8),
422 TILEGX_IMM_HOWTO(R_TILEGX_IMM8_X1, 0, 8),
423 TILEGX_IMM_HOWTO(R_TILEGX_IMM8_Y1, 0, 8),
424 TILEGX_IMM_HOWTO(R_TILEGX_DEST_IMM8_X1, 0, 8),
425
426 TILEGX_UIMM_HOWTO(R_TILEGX_MT_IMM14_X1, 1, 14),
427 TILEGX_UIMM_HOWTO(R_TILEGX_MF_IMM14_X1, 1, 14),
428
429 TILEGX_UIMM_HOWTO(R_TILEGX_MMSTART_X0, 0, 6),
430 TILEGX_UIMM_HOWTO(R_TILEGX_MMEND_X0, 0, 6),
431
432 TILEGX_UIMM_HOWTO(R_TILEGX_SHAMT_X0, 0, 6),
433 TILEGX_UIMM_HOWTO(R_TILEGX_SHAMT_X1, 0, 6),
434 TILEGX_UIMM_HOWTO(R_TILEGX_SHAMT_Y0, 0, 6),
435 TILEGX_UIMM_HOWTO(R_TILEGX_SHAMT_Y1, 0, 6),
436
437#define TILEGX_IMM16_HOWTO(name, rshift) \
438 HOWTO (name, rshift, 1, 16, FALSE, 0, \
07d6d2b8
AM
439 complain_overflow_dont, bfd_elf_generic_reloc, \
440 #name, FALSE, 0, 0xffff, FALSE)
aa137e4d
NC
441
442 TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW0, 0),
443 TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW0, 0),
444 TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW1, 16),
445 TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW1, 16),
446 TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW2, 32),
447 TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW2, 32),
448 TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW3, 48),
449 TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW3, 48),
450
451#define TILEGX_IMM16_HOWTO_LAST(name, rshift) \
452 HOWTO (name, rshift, 1, 16, FALSE, 0, \
07d6d2b8
AM
453 complain_overflow_signed, bfd_elf_generic_reloc, \
454 #name, FALSE, 0, 0xffff, FALSE)
aa137e4d
NC
455
456 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW0_LAST, 0),
457 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW0_LAST, 0),
458 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW1_LAST, 16),
459 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW1_LAST, 16),
460 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW2_LAST, 32),
461 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW2_LAST, 32),
462
463 /* PC-relative offsets. */
464
465#define TILEGX_IMM16_HOWTO_PCREL(name, rshift) \
466 HOWTO (name, rshift, 1, 16, TRUE, 0, \
07d6d2b8
AM
467 complain_overflow_dont, bfd_elf_generic_reloc, \
468 #name, FALSE, 0, 0xffff, TRUE)
aa137e4d
NC
469
470 TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW0_PCREL, 0),
471 TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW0_PCREL, 0),
472 TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW1_PCREL, 16),
473 TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW1_PCREL, 16),
474 TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW2_PCREL, 32),
475 TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW2_PCREL, 32),
476 TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW3_PCREL, 48),
477 TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW3_PCREL, 48),
478
479#define TILEGX_IMM16_HOWTO_LAST_PCREL(name, rshift) \
480 HOWTO (name, rshift, 1, 16, TRUE, 0, \
07d6d2b8
AM
481 complain_overflow_signed, bfd_elf_generic_reloc, \
482 #name, FALSE, 0, 0xffff, TRUE)
aa137e4d
NC
483
484 TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X0_HW0_LAST_PCREL, 0),
485 TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X1_HW0_LAST_PCREL, 0),
486 TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X0_HW1_LAST_PCREL, 16),
487 TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X1_HW1_LAST_PCREL, 16),
488 TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X0_HW2_LAST_PCREL, 32),
489 TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X1_HW2_LAST_PCREL, 32),
490
491 TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW0_GOT, 0),
492 TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW0_GOT, 0),
e5b95258
WL
493
494 TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW0_PLT_PCREL, 0),
495 TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW0_PLT_PCREL, 0),
496 TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW1_PLT_PCREL, 16),
497 TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW1_PLT_PCREL, 16),
498 TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW2_PLT_PCREL, 32),
499 TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW2_PLT_PCREL, 32),
aa137e4d
NC
500
501 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW0_LAST_GOT, 0),
502 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW0_LAST_GOT, 0),
503 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW1_LAST_GOT, 16),
504 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW1_LAST_GOT, 16),
e5b95258
WL
505
506 TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X0_HW3_PLT_PCREL, 48),
507 TILEGX_IMM16_HOWTO_PCREL (R_TILEGX_IMM16_X1_HW3_PLT_PCREL, 48),
aa137e4d
NC
508
509 TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW0_TLS_GD, 0),
510 TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW0_TLS_GD, 0),
6f7be959
WL
511
512 TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X0_HW0_TLS_LE, 0),
513 TILEGX_IMM16_HOWTO (R_TILEGX_IMM16_X1_HW0_TLS_LE, 0),
514 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE, 0),
515 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE, 0),
516 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE, 16),
517 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE, 16),
aa137e4d
NC
518
519 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD, 0),
520 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD, 0),
521 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD, 16),
522 TILEGX_IMM16_HOWTO_LAST (R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD, 16),
6f7be959
WL
523 EMPTY_HOWTO (90),
524 EMPTY_HOWTO (91),
aa137e4d
NC
525
526#define TILEGX_IMM16_HOWTO_TLS_IE(name, rshift) \
527 HOWTO (name, rshift, 1, 16, FALSE, 0, \
07d6d2b8
AM
528 complain_overflow_dont, bfd_elf_generic_reloc, \
529 #name, FALSE, 0, 0xffff, TRUE)
aa137e4d
NC
530
531 TILEGX_IMM16_HOWTO_TLS_IE (R_TILEGX_IMM16_X0_HW0_TLS_IE, 0),
532 TILEGX_IMM16_HOWTO_TLS_IE (R_TILEGX_IMM16_X1_HW0_TLS_IE, 0),
e5b95258
WL
533
534 TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL, 0),
535 TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL, 0),
536 TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL, 16),
537 TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL, 16),
538 TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL, 32),
539 TILEGX_IMM16_HOWTO_LAST_PCREL (R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL, 32),
aa137e4d
NC
540
541#define TILEGX_IMM16_HOWTO_LAST_TLS_IE(name, rshift) \
542 HOWTO (name, rshift, 1, 16, FALSE, 0, \
07d6d2b8
AM
543 complain_overflow_signed, bfd_elf_generic_reloc, \
544 #name, FALSE, 0, 0xffff, TRUE)
aa137e4d
NC
545
546 TILEGX_IMM16_HOWTO_LAST_TLS_IE (R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE, 0),
547 TILEGX_IMM16_HOWTO_LAST_TLS_IE (R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE, 0),
548 TILEGX_IMM16_HOWTO_LAST_TLS_IE (R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE, 16),
549 TILEGX_IMM16_HOWTO_LAST_TLS_IE (R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE, 16),
6f7be959
WL
550 EMPTY_HOWTO (104),
551 EMPTY_HOWTO (105),
aa137e4d
NC
552
553 HOWTO(R_TILEGX_TLS_DTPMOD64, 0, 0, 0, FALSE, 0, complain_overflow_dont,
07d6d2b8
AM
554 bfd_elf_generic_reloc, "R_TILEGX_TLS_DTPMOD64",
555 FALSE, 0, 0, TRUE),
aa137e4d 556 HOWTO(R_TILEGX_TLS_DTPOFF64, 0, 4, 64, FALSE, 0, complain_overflow_bitfield,
07d6d2b8
AM
557 bfd_elf_generic_reloc, "R_TILEGX_TLS_DTPOFF64",
558 FALSE, 0, -1, TRUE),
aa137e4d 559 HOWTO(R_TILEGX_TLS_TPOFF64, 0, 0, 0, FALSE, 0, complain_overflow_dont,
07d6d2b8
AM
560 bfd_elf_generic_reloc, "R_TILEGX_TLS_TPOFF64",
561 FALSE, 0, 0, TRUE),
aa137e4d
NC
562
563 HOWTO(R_TILEGX_TLS_DTPMOD32, 0, 0, 0, FALSE, 0, complain_overflow_dont,
07d6d2b8
AM
564 bfd_elf_generic_reloc, "R_TILEGX_TLS_DTPMOD32",
565 FALSE, 0, 0, TRUE),
aa137e4d 566 HOWTO(R_TILEGX_TLS_DTPOFF32, 0, 4, 32, FALSE, 0, complain_overflow_bitfield,
07d6d2b8
AM
567 bfd_elf_generic_reloc, "R_TILEGX_TLS_DTPOFF32",
568 FALSE, 0, -1, TRUE),
aa137e4d 569 HOWTO(R_TILEGX_TLS_TPOFF32, 0, 0, 0, FALSE, 0, complain_overflow_dont,
07d6d2b8
AM
570 bfd_elf_generic_reloc, "R_TILEGX_TLS_TPOFF32",
571 FALSE, 0, 0, TRUE),
6f7be959
WL
572
573 HOWTO (R_TILEGX_TLS_GD_CALL, /* type */
574 TILEGX_LOG2_BUNDLE_ALIGNMENT_IN_BYTES, /* rightshift */
575 2, /* size (0 = byte, 1 = short, 2 = long) */
576 27, /* bitsize */
577 TRUE, /* pc_relative */
578 0, /* bitpos */
579 complain_overflow_signed,/* complain_on_overflow */
580 bfd_elf_generic_reloc, /* special_function */
581 "R_TILEGX_TLS_GD_CALL", /* name */
582 FALSE, /* partial_inplace */
583 0, /* src_mask */
584 -1, /* dst_mask */
07d6d2b8 585 TRUE), /* pcrel_offset */
6f7be959
WL
586
587 TILEGX_IMM_HOWTO(R_TILEGX_IMM8_X0_TLS_GD_ADD, 0, 8),
588 TILEGX_IMM_HOWTO(R_TILEGX_IMM8_X1_TLS_GD_ADD, 0, 8),
589 TILEGX_IMM_HOWTO(R_TILEGX_IMM8_Y0_TLS_GD_ADD, 0, 8),
590 TILEGX_IMM_HOWTO(R_TILEGX_IMM8_Y1_TLS_GD_ADD, 0, 8),
591 TILEGX_IMM_HOWTO(R_TILEGX_TLS_IE_LOAD, 0, 8),
592 TILEGX_IMM_HOWTO(R_TILEGX_IMM8_X0_TLS_ADD, 0, 8),
593 TILEGX_IMM_HOWTO(R_TILEGX_IMM8_X1_TLS_ADD, 0, 8),
594 TILEGX_IMM_HOWTO(R_TILEGX_IMM8_Y0_TLS_ADD, 0, 8),
595 TILEGX_IMM_HOWTO(R_TILEGX_IMM8_Y1_TLS_ADD, 0, 8),
aa137e4d
NC
596};
597
598static reloc_howto_type tilegx_elf_howto_table2 [] =
599{
600 /* GNU extension to record C++ vtable hierarchy */
601 HOWTO (R_TILEGX_GNU_VTINHERIT, /* type */
07d6d2b8
AM
602 0, /* rightshift */
603 4, /* size (0 = byte, 1 = short, 2 = long) */
604 0, /* bitsize */
605 FALSE, /* pc_relative */
606 0, /* bitpos */
607 complain_overflow_dont, /* complain_on_overflow */
608 NULL, /* special_function */
609 "R_TILEGX_GNU_VTINHERIT", /* name */
610 FALSE, /* partial_inplace */
611 0, /* src_mask */
612 0, /* dst_mask */
613 FALSE), /* pcrel_offset */
aa137e4d
NC
614
615 /* GNU extension to record C++ vtable member usage */
07d6d2b8
AM
616 HOWTO (R_TILEGX_GNU_VTENTRY, /* type */
617 0, /* rightshift */
618 4, /* size (0 = byte, 1 = short, 2 = long) */
619 0, /* bitsize */
620 FALSE, /* pc_relative */
621 0, /* bitpos */
622 complain_overflow_dont, /* complain_on_overflow */
623 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
624 "R_TILEGX_GNU_VTENTRY", /* name */
625 FALSE, /* partial_inplace */
626 0, /* src_mask */
627 0, /* dst_mask */
628 FALSE), /* pcrel_offset */
aa137e4d
NC
629
630};
631\f
632/* Map BFD reloc types to TILEGX ELF reloc types. */
633
634typedef struct tilegx_reloc_map
635{
636 bfd_reloc_code_real_type bfd_reloc_val;
07d6d2b8
AM
637 unsigned int tilegx_reloc_val;
638 reloc_howto_type * table;
aa137e4d
NC
639} reloc_map;
640
641static const reloc_map tilegx_reloc_map [] =
642{
643#define TH_REMAP(bfd, tilegx) \
644 { bfd, tilegx, tilegx_elf_howto_table },
645
646 /* Standard relocations. */
07d6d2b8
AM
647 TH_REMAP (BFD_RELOC_NONE, R_TILEGX_NONE)
648 TH_REMAP (BFD_RELOC_64, R_TILEGX_64)
649 TH_REMAP (BFD_RELOC_32, R_TILEGX_32)
650 TH_REMAP (BFD_RELOC_16, R_TILEGX_16)
651 TH_REMAP (BFD_RELOC_8, R_TILEGX_8)
652 TH_REMAP (BFD_RELOC_64_PCREL, R_TILEGX_64_PCREL)
653 TH_REMAP (BFD_RELOC_32_PCREL, R_TILEGX_32_PCREL)
654 TH_REMAP (BFD_RELOC_16_PCREL, R_TILEGX_16_PCREL)
655 TH_REMAP (BFD_RELOC_8_PCREL, R_TILEGX_8_PCREL)
aa137e4d
NC
656
657#define SIMPLE_REMAP(t) TH_REMAP (BFD_RELOC_##t, R_##t)
658
659 /* Custom relocations. */
660 SIMPLE_REMAP (TILEGX_HW0)
661 SIMPLE_REMAP (TILEGX_HW1)
662 SIMPLE_REMAP (TILEGX_HW2)
663 SIMPLE_REMAP (TILEGX_HW3)
664 SIMPLE_REMAP (TILEGX_HW0_LAST)
665 SIMPLE_REMAP (TILEGX_HW1_LAST)
666 SIMPLE_REMAP (TILEGX_HW2_LAST)
667 SIMPLE_REMAP (TILEGX_COPY)
668 SIMPLE_REMAP (TILEGX_GLOB_DAT)
669 SIMPLE_REMAP (TILEGX_JMP_SLOT)
670 SIMPLE_REMAP (TILEGX_RELATIVE)
671 SIMPLE_REMAP (TILEGX_BROFF_X1)
672 SIMPLE_REMAP (TILEGX_JUMPOFF_X1)
673 SIMPLE_REMAP (TILEGX_JUMPOFF_X1_PLT)
674 SIMPLE_REMAP (TILEGX_IMM8_X0)
675 SIMPLE_REMAP (TILEGX_IMM8_Y0)
676 SIMPLE_REMAP (TILEGX_IMM8_X1)
677 SIMPLE_REMAP (TILEGX_IMM8_Y1)
678 SIMPLE_REMAP (TILEGX_DEST_IMM8_X1)
679 SIMPLE_REMAP (TILEGX_MT_IMM14_X1)
680 SIMPLE_REMAP (TILEGX_MF_IMM14_X1)
681 SIMPLE_REMAP (TILEGX_MMSTART_X0)
682 SIMPLE_REMAP (TILEGX_MMEND_X0)
683 SIMPLE_REMAP (TILEGX_SHAMT_X0)
684 SIMPLE_REMAP (TILEGX_SHAMT_X1)
685 SIMPLE_REMAP (TILEGX_SHAMT_Y0)
686 SIMPLE_REMAP (TILEGX_SHAMT_Y1)
687 SIMPLE_REMAP (TILEGX_IMM16_X0_HW0)
688 SIMPLE_REMAP (TILEGX_IMM16_X1_HW0)
689 SIMPLE_REMAP (TILEGX_IMM16_X0_HW1)
690 SIMPLE_REMAP (TILEGX_IMM16_X1_HW1)
691 SIMPLE_REMAP (TILEGX_IMM16_X0_HW2)
692 SIMPLE_REMAP (TILEGX_IMM16_X1_HW2)
693 SIMPLE_REMAP (TILEGX_IMM16_X0_HW3)
694 SIMPLE_REMAP (TILEGX_IMM16_X1_HW3)
695 SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST)
696 SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST)
697 SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST)
698 SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST)
699 SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_LAST)
700 SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_LAST)
701 SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_PCREL)
702 SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_PCREL)
703 SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_PCREL)
704 SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_PCREL)
705 SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_PCREL)
706 SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_PCREL)
707 SIMPLE_REMAP (TILEGX_IMM16_X0_HW3_PCREL)
708 SIMPLE_REMAP (TILEGX_IMM16_X1_HW3_PCREL)
709 SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_PCREL)
710 SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_PCREL)
711 SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_PCREL)
712 SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_PCREL)
713 SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_LAST_PCREL)
714 SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_LAST_PCREL)
715 SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_GOT)
716 SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_GOT)
e5b95258
WL
717 SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_PLT_PCREL)
718 SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_PLT_PCREL)
719 SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_PLT_PCREL)
720 SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_PLT_PCREL)
721 SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_PLT_PCREL)
722 SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_PLT_PCREL)
aa137e4d
NC
723 SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_GOT)
724 SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_GOT)
725 SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_GOT)
726 SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_GOT)
e5b95258
WL
727 SIMPLE_REMAP (TILEGX_IMM16_X0_HW3_PLT_PCREL)
728 SIMPLE_REMAP (TILEGX_IMM16_X1_HW3_PLT_PCREL)
aa137e4d
NC
729 SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_TLS_GD)
730 SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_TLS_GD)
6f7be959
WL
731 SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_TLS_LE)
732 SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_TLS_LE)
733 SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_TLS_LE)
734 SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_TLS_LE)
735 SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_TLS_LE)
736 SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_TLS_LE)
aa137e4d
NC
737 SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_TLS_GD)
738 SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_TLS_GD)
739 SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_TLS_GD)
740 SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_TLS_GD)
aa137e4d
NC
741 SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_TLS_IE)
742 SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_TLS_IE)
e5b95258
WL
743 SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL)
744 SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL)
745 SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL)
746 SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL)
747 SIMPLE_REMAP (TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL)
748 SIMPLE_REMAP (TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL)
aa137e4d
NC
749 SIMPLE_REMAP (TILEGX_IMM16_X0_HW0_LAST_TLS_IE)
750 SIMPLE_REMAP (TILEGX_IMM16_X1_HW0_LAST_TLS_IE)
751 SIMPLE_REMAP (TILEGX_IMM16_X0_HW1_LAST_TLS_IE)
752 SIMPLE_REMAP (TILEGX_IMM16_X1_HW1_LAST_TLS_IE)
aa137e4d
NC
753
754 SIMPLE_REMAP (TILEGX_TLS_DTPMOD64)
755 SIMPLE_REMAP (TILEGX_TLS_DTPOFF64)
756 SIMPLE_REMAP (TILEGX_TLS_TPOFF64)
757
758 SIMPLE_REMAP (TILEGX_TLS_DTPMOD32)
759 SIMPLE_REMAP (TILEGX_TLS_DTPOFF32)
760 SIMPLE_REMAP (TILEGX_TLS_TPOFF32)
761
6f7be959
WL
762 SIMPLE_REMAP (TILEGX_TLS_GD_CALL)
763 SIMPLE_REMAP (TILEGX_IMM8_X0_TLS_GD_ADD)
764 SIMPLE_REMAP (TILEGX_IMM8_X1_TLS_GD_ADD)
765 SIMPLE_REMAP (TILEGX_IMM8_Y0_TLS_GD_ADD)
766 SIMPLE_REMAP (TILEGX_IMM8_Y1_TLS_GD_ADD)
767 SIMPLE_REMAP (TILEGX_TLS_IE_LOAD)
768 SIMPLE_REMAP (TILEGX_IMM8_X0_TLS_ADD)
769 SIMPLE_REMAP (TILEGX_IMM8_X1_TLS_ADD)
770 SIMPLE_REMAP (TILEGX_IMM8_Y0_TLS_ADD)
771 SIMPLE_REMAP (TILEGX_IMM8_Y1_TLS_ADD)
772
aa137e4d
NC
773#undef SIMPLE_REMAP
774#undef TH_REMAP
775
07d6d2b8
AM
776 { BFD_RELOC_VTABLE_INHERIT, R_TILEGX_GNU_VTINHERIT, tilegx_elf_howto_table2 },
777 { BFD_RELOC_VTABLE_ENTRY, R_TILEGX_GNU_VTENTRY, tilegx_elf_howto_table2 },
aa137e4d
NC
778};
779
780
781
aa137e4d
NC
782/* TILEGX ELF linker hash entry. */
783
784struct tilegx_elf_link_hash_entry
785{
786 struct elf_link_hash_entry elf;
787
aa137e4d
NC
788#define GOT_UNKNOWN 0
789#define GOT_NORMAL 1
790#define GOT_TLS_GD 2
791#define GOT_TLS_IE 4
792 unsigned char tls_type;
793};
794
795#define tilegx_elf_hash_entry(ent) \
796 ((struct tilegx_elf_link_hash_entry *)(ent))
797
798struct _bfd_tilegx_elf_obj_tdata
799{
800 struct elf_obj_tdata root;
801
802 /* tls_type for each local got entry. */
803 char *local_got_tls_type;
804};
805
806#define _bfd_tilegx_elf_tdata(abfd) \
807 ((struct _bfd_tilegx_elf_obj_tdata *) (abfd)->tdata.any)
808
809#define _bfd_tilegx_elf_local_got_tls_type(abfd) \
810 (_bfd_tilegx_elf_tdata (abfd)->local_got_tls_type)
811
812#define is_tilegx_elf(bfd) \
813 (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
814 && elf_tdata (bfd) != NULL \
815 && elf_object_id (bfd) == TILEGX_ELF_DATA)
816
817#include "elf/common.h"
818#include "elf/internal.h"
819
820struct tilegx_elf_link_hash_table
821{
822 struct elf_link_hash_table elf;
823
824 int bytes_per_word;
825 int word_align_power;
826 int bytes_per_rela;
827 int dtpmod_reloc;
828 int dtpoff_reloc;
829 int tpoff_reloc;
830 bfd_vma (*r_info) (Elf_Internal_Rela *, bfd_vma, bfd_vma);
831 bfd_vma (*r_symndx) (bfd_vma);
832 void (*put_word) (bfd *, bfd_vma, void *);
833 const char *dynamic_interpreter;
834
6f7be959
WL
835 /* Whether LE transition has been disabled for some of the
836 sections. */
837 bfd_boolean disable_le_transition;
838
aa137e4d
NC
839 /* Small local sym to section mapping cache. */
840 struct sym_cache sym_cache;
841};
842
843
844/* Get the Tile ELF linker hash table from a link_info structure. */
845#define tilegx_elf_hash_table(p) \
846 (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
847 == TILEGX_ELF_DATA ? ((struct tilegx_elf_link_hash_table *) ((p)->hash)) : NULL)
848
849#ifdef BFD64
850static bfd_vma
851tilegx_elf_r_info_64 (Elf_Internal_Rela *in_rel ATTRIBUTE_UNUSED,
852 bfd_vma rel_index,
853 bfd_vma type)
854{
855 return ELF64_R_INFO (rel_index, type);
856}
857
858static bfd_vma
859tilegx_elf_r_symndx_64 (bfd_vma r_info)
860{
861 return ELF64_R_SYM (r_info);
862}
863
864static void
865tilegx_put_word_64 (bfd *abfd, bfd_vma val, void *ptr)
866{
867 bfd_put_64 (abfd, val, ptr);
868}
869#endif /* BFD64 */
870
871static bfd_vma
872tilegx_elf_r_info_32 (Elf_Internal_Rela *in_rel ATTRIBUTE_UNUSED,
873 bfd_vma rel_index,
874 bfd_vma type)
875{
876 return ELF32_R_INFO (rel_index, type);
877}
878
879static bfd_vma
880tilegx_elf_r_symndx_32 (bfd_vma r_info)
881{
882 return ELF32_R_SYM (r_info);
883}
884
885static void
886tilegx_put_word_32 (bfd *abfd, bfd_vma val, void *ptr)
887{
888 bfd_put_32 (abfd, val, ptr);
889}
890
891reloc_howto_type *
f3185997 892tilegx_reloc_type_lookup (bfd * abfd,
aa137e4d
NC
893 bfd_reloc_code_real_type code)
894{
895 unsigned int i;
896
0ba38529 897 for (i = ARRAY_SIZE (tilegx_reloc_map); i--;)
aa137e4d
NC
898 {
899 const reloc_map * entry;
900
901 entry = tilegx_reloc_map + i;
902
903 if (entry->bfd_reloc_val == code)
904 return entry->table + (entry->tilegx_reloc_val
905 - entry->table[0].type);
906 }
907
f3185997 908 /* xgettext:c-format */
e8f5af78 909 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
f3185997
NC
910 abfd, (int) code);
911 bfd_set_error (bfd_error_bad_value);
aa137e4d
NC
912 return NULL;
913}
914
915reloc_howto_type *
916tilegx_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
917 const char *r_name)
918{
919 unsigned int i;
920
921 for (i = 0;
922 i < (sizeof (tilegx_elf_howto_table)
07d6d2b8 923 / sizeof (tilegx_elf_howto_table[0]));
aa137e4d
NC
924 i++)
925 if (tilegx_elf_howto_table[i].name != NULL
07d6d2b8 926 && strcasecmp (tilegx_elf_howto_table[i].name, r_name) == 0)
aa137e4d
NC
927 return &tilegx_elf_howto_table[i];
928
929 return NULL;
930}
931
f3185997 932bfd_boolean
aa137e4d
NC
933tilegx_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
934 arelent *cache_ptr,
935 Elf_Internal_Rela *dst)
936{
937 unsigned int r_type = TILEGX_ELF_R_TYPE (dst->r_info);
938
6f7be959 939 if (r_type <= (unsigned int) R_TILEGX_IMM8_Y1_TLS_ADD)
aa137e4d
NC
940 cache_ptr->howto = &tilegx_elf_howto_table [r_type];
941 else if (r_type - R_TILEGX_GNU_VTINHERIT
f3185997
NC
942 <= ((unsigned int) R_TILEGX_GNU_VTENTRY
943 - (unsigned int) R_TILEGX_GNU_VTINHERIT))
aa137e4d
NC
944 cache_ptr->howto
945 = &tilegx_elf_howto_table2 [r_type - R_TILEGX_GNU_VTINHERIT];
946 else
f3185997
NC
947 {
948 /* xgettext:c-format */
949 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
950 abfd, r_type);
951 bfd_set_error (bfd_error_bad_value);
952 return FALSE;
953 }
954 return TRUE;
aa137e4d
NC
955}
956
957typedef tilegx_bundle_bits (*tilegx_create_func)(int);
958
959static const tilegx_create_func reloc_to_create_func[] =
960{
961 /* The first twenty relocation types don't correspond to operands */
962 NULL,
963 NULL,
964 NULL,
965 NULL,
966 NULL,
967 NULL,
968 NULL,
969 NULL,
970 NULL,
971 NULL,
972 NULL,
973 NULL,
974 NULL,
975 NULL,
976 NULL,
977 NULL,
978 NULL,
979 NULL,
980 NULL,
981 NULL,
982
983 /* The remaining relocations are used for immediate operands */
984 create_BrOff_X1,
985 create_JumpOff_X1,
986 create_JumpOff_X1,
987 create_Imm8_X0,
988 create_Imm8_Y0,
989 create_Imm8_X1,
990 create_Imm8_Y1,
991 create_Dest_Imm8_X1,
992 create_MT_Imm14_X1,
993 create_MF_Imm14_X1,
994 create_BFStart_X0,
995 create_BFEnd_X0,
996 create_ShAmt_X0,
997 create_ShAmt_X1,
998 create_ShAmt_Y0,
999 create_ShAmt_Y1,
1000 create_Imm16_X0,
1001 create_Imm16_X1,
1002 create_Imm16_X0,
1003 create_Imm16_X1,
1004 create_Imm16_X0,
1005 create_Imm16_X1,
1006 create_Imm16_X0,
1007 create_Imm16_X1,
1008 create_Imm16_X0,
1009 create_Imm16_X1,
1010 create_Imm16_X0,
1011 create_Imm16_X1,
1012 create_Imm16_X0,
1013 create_Imm16_X1,
1014 create_Imm16_X0,
1015 create_Imm16_X1,
1016 create_Imm16_X0,
1017 create_Imm16_X1,
1018 create_Imm16_X0,
1019 create_Imm16_X1,
1020 create_Imm16_X0,
1021 create_Imm16_X1,
1022 create_Imm16_X0,
1023 create_Imm16_X1,
1024 create_Imm16_X0,
1025 create_Imm16_X1,
1026 create_Imm16_X0,
1027 create_Imm16_X1,
1028 create_Imm16_X0,
1029 create_Imm16_X1,
1030 create_Imm16_X0,
1031 create_Imm16_X1,
1032 create_Imm16_X0,
1033 create_Imm16_X1,
1034 create_Imm16_X0,
1035 create_Imm16_X1,
1036 create_Imm16_X0,
1037 create_Imm16_X1,
1038 create_Imm16_X0,
1039 create_Imm16_X1,
1040 create_Imm16_X0,
1041 create_Imm16_X1,
1042 create_Imm16_X0,
1043 create_Imm16_X1,
1044 create_Imm16_X0,
1045 create_Imm16_X1,
e5b95258
WL
1046 create_Imm16_X0,
1047 create_Imm16_X1,
1048 create_Imm16_X0,
1049 create_Imm16_X1,
1050 create_Imm16_X0,
1051 create_Imm16_X1,
aa137e4d
NC
1052 create_Imm16_X0,
1053 create_Imm16_X1,
6f7be959
WL
1054 NULL,
1055 NULL,
e5b95258
WL
1056 create_Imm16_X0,
1057 create_Imm16_X1,
1058 create_Imm16_X0,
1059 create_Imm16_X1,
1060 create_Imm16_X0,
1061 create_Imm16_X1,
1062 create_Imm16_X0,
1063 create_Imm16_X1,
aa137e4d
NC
1064 create_Imm16_X0,
1065 create_Imm16_X1,
1066 create_Imm16_X0,
1067 create_Imm16_X1,
aa137e4d
NC
1068};
1069
1070static void
1071tilegx_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
1072{
1073 const struct elf_backend_data *bed;
1074 bfd_byte *loc;
1075
1076 bed = get_elf_backend_data (abfd);
1077 loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
1078 bed->s->swap_reloca_out (abfd, rel, loc);
1079}
1080
1081/* PLT/GOT stuff */
1082
1083/* The procedure linkage table starts with the following header:
1084
07d6d2b8
AM
1085 ld_add r28, r27, 8
1086 ld r27, r27
aa137e4d 1087 {
07d6d2b8
AM
1088 jr r27
1089 info 10 ## SP not offset, return PC in LR
aa137e4d
NC
1090 }
1091
1092 Subsequent entries are the following, jumping to the header at the end:
1093
1094 {
07d6d2b8
AM
1095 moveli r28, <_GLOBAL_OFFSET_TABLE_ - 1f + MY_GOT_OFFSET>
1096 lnk r26
aa137e4d
NC
1097 }
10981:
1099 {
07d6d2b8
AM
1100 moveli r27, <_GLOBAL_OFFSET_TABLE_ - 1b>
1101 shl16insli r28, r28, <_GLOBAL_OFFSET_TABLE_ - 1b + MY_GOT_OFFSET>
aa137e4d
NC
1102 }
1103 {
07d6d2b8
AM
1104 add r28, r26, r28
1105 shl16insli r27, r27, <_GLOBAL_OFFSET_TABLE_ - 1b>
aa137e4d
NC
1106 }
1107 {
07d6d2b8
AM
1108 add r27, r26, r27
1109 ld r28, r28
1110 info 10 ## SP not offset, return PC in LR
aa137e4d
NC
1111 }
1112 {
07d6d2b8
AM
1113 shl16insli r29, zero, MY_PLT_INDEX
1114 jr r28
aa137e4d
NC
1115 }
1116
1117 This code sequence lets the code at at the start of the PLT determine
1118 which PLT entry was executed by examining 'r29'.
1119
1120 Note that MY_PLT_INDEX skips over the header entries, so the first
1121 actual jump table entry has index zero.
1122
1123 If the offset fits in 16 bits,
1124
07d6d2b8 1125 lnk r26
aa137e4d
NC
11261:
1127 {
07d6d2b8
AM
1128 addli r28, r26, <_GLOBAL_OFFSET_TABLE_ - 1b + MY_GOT_OFFSET>
1129 moveli r27, <_GLOBAL_OFFSET_TABLE_ - 1b>
aa137e4d
NC
1130 }
1131 {
07d6d2b8
AM
1132 shl16insli r29, zero, MY_PLT_INDEX
1133 ld r28, r28
aa137e4d
NC
1134 }
1135 {
07d6d2b8
AM
1136 add r27, r26, r27
1137 jr r28
aa137e4d 1138 }
07d6d2b8 1139 info 10 ## SP not offset, return PC in LR
aa137e4d
NC
1140
1141 For the purpose of backtracing, the procedure linkage table ends with the
1142 following tail entry:
1143
07d6d2b8 1144 info 10 ## SP not offset, return PC in LR
aa137e4d
NC
1145
1146 The 32-bit versions are similar, with ld4s replacing ld, and offsets into
1147 the GOT being multiples of 4 instead of 8.
1148
1149*/
1150
1151#define PLT_HEADER_SIZE_IN_BUNDLES 3
1152#define PLT_ENTRY_SIZE_IN_BUNDLES 5
1153#define PLT_TAIL_SIZE_IN_BUNDLES 1
1154
1155#define PLT_HEADER_SIZE \
1156 (PLT_HEADER_SIZE_IN_BUNDLES * TILEGX_BUNDLE_SIZE_IN_BYTES)
1157#define PLT_ENTRY_SIZE \
1158 (PLT_ENTRY_SIZE_IN_BUNDLES * TILEGX_BUNDLE_SIZE_IN_BYTES)
1159#define PLT_TAIL_SIZE \
1160 (PLT_TAIL_SIZE_IN_BUNDLES * TILEGX_BUNDLE_SIZE_IN_BYTES)
1161
1162#define GOT_ENTRY_SIZE(htab) TILEGX_ELF_WORD_BYTES (htab)
1163
1164#define GOTPLT_HEADER_SIZE(htab) (2 * GOT_ENTRY_SIZE (htab))
1165
1166static const bfd_byte
1167tilegx64_plt0_entry[PLT_HEADER_SIZE] =
1168{
1169 0x00, 0x30, 0x48, 0x51,
1170 0x6e, 0x43, 0xa0, 0x18, /* { ld_add r28, r27, 8 } */
1171 0x00, 0x30, 0xbc, 0x35,
1172 0x00, 0x40, 0xde, 0x9e, /* { ld r27, r27 } */
1173 0xff, 0xaf, 0x30, 0x40,
1174 0x60, 0x73, 0x6a, 0x28, /* { info 10 ; jr r27 } */
1175};
1176
1177static const bfd_byte
1178tilegx64_long_plt_entry[PLT_ENTRY_SIZE] =
1179{
1180 0xdc, 0x0f, 0x00, 0x10,
1181 0x0d, 0xf0, 0x6a, 0x28, /* { moveli r28, 0 ; lnk r26 } */
1182 0xdb, 0x0f, 0x00, 0x10,
1183 0x8e, 0x03, 0x00, 0x38, /* { moveli r27, 0 ; shl16insli r28, r28, 0 } */
1184 0x9c, 0xc6, 0x0d, 0xd0,
1185 0x6d, 0x03, 0x00, 0x38, /* { add r28, r26, r28 ; shl16insli r27, r27, 0 } */
1186 0x9b, 0xb6, 0xc5, 0xad,
1187 0xff, 0x57, 0xe0, 0x8e, /* { add r27, r26, r27 ; info 10 ; ld r28, r28 } */
1188 0xdd, 0x0f, 0x00, 0x70,
1189 0x80, 0x73, 0x6a, 0x28, /* { shl16insli r29, zero, 0 ; jr r28 } */
1190};
1191
1192static const bfd_byte
1193tilegx64_short_plt_entry[PLT_ENTRY_SIZE] =
1194{
1195 0x00, 0x30, 0x48, 0x51,
1196 0x0d, 0xf0, 0x6a, 0x28, /* { lnk r26 } */
1197 0x9c, 0x06, 0x00, 0x90,
1198 0xed, 0x07, 0x00, 0x00, /* { addli r28, r26, 0 ; moveli r27, 0 } */
1199 0xdd, 0x0f, 0x00, 0x70,
1200 0x8e, 0xeb, 0x6a, 0x28, /* { shl16insli r29, zero, 0 ; ld r28, r28 } */
1201 0x9b, 0xb6, 0x0d, 0x50,
1202 0x80, 0x73, 0x6a, 0x28, /* { add r27, r26, r27 ; jr r28 } */
1203 0x00, 0x30, 0x48, 0xd1,
1204 0xff, 0x57, 0x18, 0x18, /* { info 10 } */
1205};
1206
1207/* Reuse an existing info 10 bundle. */
0e4894b9 1208static const bfd_byte *const tilegx64_plt_tail_entry =
aa137e4d
NC
1209 &tilegx64_short_plt_entry[4 * TILEGX_BUNDLE_SIZE_IN_BYTES];
1210
1211static const bfd_byte
1212tilegx32_plt0_entry[PLT_HEADER_SIZE] =
1213{
1214 0x00, 0x30, 0x48, 0x51,
1215 0x6e, 0x23, 0x58, 0x18, /* { ld4s_add r28, r27, 4 } */
1216 0x00, 0x30, 0xbc, 0x35,
1217 0x00, 0x40, 0xde, 0x9c, /* { ld4s r27, r27 } */
1218 0xff, 0xaf, 0x30, 0x40,
1219 0x60, 0x73, 0x6a, 0x28, /* { info 10 ; jr r27 } */
1220};
1221
1222static const bfd_byte
1223tilegx32_long_plt_entry[PLT_ENTRY_SIZE] =
1224{
1225 0xdc, 0x0f, 0x00, 0x10,
1226 0x0d, 0xf0, 0x6a, 0x28, /* { moveli r28, 0 ; lnk r26 } */
1227 0xdb, 0x0f, 0x00, 0x10,
1228 0x8e, 0x03, 0x00, 0x38, /* { moveli r27, 0 ; shl16insli r28, r28, 0 } */
1229 0x9c, 0xc6, 0x0d, 0xd0,
1230 0x6d, 0x03, 0x00, 0x38, /* { add r28, r26, r28 ; shl16insli r27, r27, 0 } */
1231 0x9b, 0xb6, 0xc5, 0xad,
1232 0xff, 0x57, 0xe0, 0x8c, /* { add r27, r26, r27 ; info 10 ; ld4s r28, r28 } */
1233 0xdd, 0x0f, 0x00, 0x70,
1234 0x80, 0x73, 0x6a, 0x28, /* { shl16insli r29, zero, 0 ; jr r28 } */
1235};
1236
1237static const bfd_byte
1238tilegx32_short_plt_entry[PLT_ENTRY_SIZE] =
1239{
1240 0x00, 0x30, 0x48, 0x51,
1241 0x0d, 0xf0, 0x6a, 0x28, /* { lnk r26 } */
1242 0x9c, 0x06, 0x00, 0x90,
1243 0xed, 0x07, 0x00, 0x00, /* { addli r28, r26, 0 ; moveli r27, 0 } */
1244 0xdd, 0x0f, 0x00, 0x70,
1245 0x8e, 0x9b, 0x6a, 0x28, /* { shl16insli r29, zero, 0 ; ld4s r28, r28 } */
1246 0x9b, 0xb6, 0x0d, 0x50,
1247 0x80, 0x73, 0x6a, 0x28, /* { add r27, r26, r27 ; jr r28 } */
1248 0x00, 0x30, 0x48, 0xd1,
1249 0xff, 0x57, 0x18, 0x18, /* { info 10 } */
1250};
1251
1252/* Reuse an existing info 10 bundle. */
0e4894b9 1253static const bfd_byte *const tilegx32_plt_tail_entry =
aa137e4d
NC
1254 &tilegx64_short_plt_entry[4 * TILEGX_BUNDLE_SIZE_IN_BYTES];
1255
1256static int
1257tilegx_plt_entry_build (bfd *output_bfd,
1258 struct tilegx_elf_link_hash_table *htab,
1259 asection *splt, asection *sgotplt,
1260 bfd_vma offset, bfd_vma *r_offset)
1261{
1262 int plt_index = (offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
1263 int got_offset = (plt_index * GOT_ENTRY_SIZE (htab)
1264 + GOTPLT_HEADER_SIZE (htab));
1265 tilegx_bundle_bits *pc;
1266
1267 /* Compute the distance from the got entry to the lnk. */
1268 bfd_signed_vma dist_got_entry = sgotplt->output_section->vma
1269 + sgotplt->output_offset
1270 + got_offset
1271 - splt->output_section->vma
1272 - splt->output_offset
1273 - offset
1274 - TILEGX_BUNDLE_SIZE_IN_BYTES;
1275
1276 /* Compute the distance to GOTPLT[0]. */
1277 bfd_signed_vma dist_got0 = dist_got_entry - got_offset;
1278
1279 /* Check whether we can use the short plt entry with 16-bit offset. */
1280 bfd_boolean short_plt_entry =
1281 (dist_got_entry <= 0x7fff && dist_got0 >= -0x8000);
1282
1283 const tilegx_bundle_bits *plt_entry = (tilegx_bundle_bits *)
1284 (ABI_64_P (output_bfd) ?
1285 (short_plt_entry ? tilegx64_short_plt_entry : tilegx64_long_plt_entry) :
1286 (short_plt_entry ? tilegx32_short_plt_entry : tilegx32_long_plt_entry));
1287
1288 /* Copy the plt entry template. */
1289 memcpy (splt->contents + offset, plt_entry, PLT_ENTRY_SIZE);
1290
1291 /* Write the immediate offsets. */
1292 pc = (tilegx_bundle_bits *)(splt->contents + offset);
1293
1294 if (short_plt_entry)
1295 {
1296 /* { lnk r28 } */
1297 pc++;
1298
1299 /* { addli r28, r28, &GOTPLT[MY_GOT_INDEX] ; moveli r27, &GOTPLT[0] } */
1300 *pc++ |= create_Imm16_X0 (dist_got_entry)
1301 | create_Imm16_X1 (dist_got0);
1302
1303 /* { shl16insli r29, zero, MY_PLT_INDEX ; ld r28, r28 } */
1304 *pc++ |= create_Imm16_X0 (plt_index);
1305 }
1306 else
1307 {
1308 /* { moveli r28, &GOTPLT[MY_GOT_INDEX] ; lnk r26 } */
1309 *pc++ |= create_Imm16_X0 (dist_got_entry >> 16);
1310
1311 /* { moveli r27, &GOTPLT[0] ;
1312 shl16insli r28, r28, &GOTPLT[MY_GOT_INDEX] } */
1313 *pc++ |= create_Imm16_X0 (dist_got0 >> 16)
1314 | create_Imm16_X1 (dist_got_entry);
1315
1316 /* { add r28, r26, r28 ; shl16insli r27, r27, &GOTPLT[0] } */
1317 *pc++ |= create_Imm16_X1 (dist_got0);
1318
1319 /* { add r27, r26, r27 ; info 10 ; ld r28, r28 } */
1320 pc++;
1321
1322 /* { shl16insli r29, zero, MY_GOT_INDEX ; jr r28 } */
1323 *pc++ |= create_Imm16_X0 (plt_index);
1324 }
1325
1326 /* Set the relocation offset. */
1327 *r_offset = got_offset;
1328
1329 return plt_index;
1330}
1331
1332/* Create an entry in an TILEGX ELF linker hash table. */
1333
1334static struct bfd_hash_entry *
1335link_hash_newfunc (struct bfd_hash_entry *entry,
1336 struct bfd_hash_table *table, const char *string)
1337{
1338 /* Allocate the structure if it has not already been allocated by a
1339 subclass. */
1340 if (entry == NULL)
1341 {
1342 entry =
07d6d2b8
AM
1343 bfd_hash_allocate (table,
1344 sizeof (struct tilegx_elf_link_hash_entry));
aa137e4d
NC
1345 if (entry == NULL)
1346 return entry;
1347 }
1348
1349 /* Call the allocation method of the superclass. */
1350 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
1351 if (entry != NULL)
1352 {
1353 struct tilegx_elf_link_hash_entry *eh;
1354
1355 eh = (struct tilegx_elf_link_hash_entry *) entry;
aa137e4d
NC
1356 eh->tls_type = GOT_UNKNOWN;
1357 }
1358
1359 return entry;
1360}
1361
1362/* Create a TILEGX ELF linker hash table. */
1363
1364struct bfd_link_hash_table *
1365tilegx_elf_link_hash_table_create (bfd *abfd)
1366{
1367 struct tilegx_elf_link_hash_table *ret;
986f0783 1368 size_t amt = sizeof (struct tilegx_elf_link_hash_table);
aa137e4d
NC
1369
1370 ret = (struct tilegx_elf_link_hash_table *) bfd_zmalloc (amt);
1371 if (ret == NULL)
1372 return NULL;
1373
1374#ifdef BFD64
1375 if (ABI_64_P (abfd))
1376 {
1377 ret->bytes_per_word = 8;
1378 ret->word_align_power = 3;
1379 ret->bytes_per_rela = sizeof (Elf64_External_Rela);
1380 ret->dtpoff_reloc = R_TILEGX_TLS_DTPOFF64;
1381 ret->dtpmod_reloc = R_TILEGX_TLS_DTPMOD64;
1382 ret->tpoff_reloc = R_TILEGX_TLS_TPOFF64;
1383 ret->r_info = tilegx_elf_r_info_64;
1384 ret->r_symndx = tilegx_elf_r_symndx_64;
1385 ret->dynamic_interpreter = ELF64_DYNAMIC_INTERPRETER;
1386 ret->put_word = tilegx_put_word_64;
1387 }
1388 else
1389#endif
1390 {
1391 ret->bytes_per_word = 4;
1392 ret->word_align_power = 2;
1393 ret->bytes_per_rela = sizeof (Elf32_External_Rela);
1394 ret->dtpoff_reloc = R_TILEGX_TLS_DTPOFF32;
1395 ret->dtpmod_reloc = R_TILEGX_TLS_DTPMOD32;
1396 ret->tpoff_reloc = R_TILEGX_TLS_TPOFF32;
1397 ret->r_info = tilegx_elf_r_info_32;
1398 ret->r_symndx = tilegx_elf_r_symndx_32;
1399 ret->dynamic_interpreter = ELF32_DYNAMIC_INTERPRETER;
1400 ret->put_word = tilegx_put_word_32;
1401 }
1402
1403 if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
1404 sizeof (struct tilegx_elf_link_hash_entry),
1405 TILEGX_ELF_DATA))
1406 {
1407 free (ret);
1408 return NULL;
1409 }
1410
1411 return &ret->elf.root;
1412}
1413
1414/* Create the .got section. */
1415
1416static bfd_boolean
1417tilegx_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
1418{
1419 flagword flags;
1420 asection *s, *s_got;
1421 struct elf_link_hash_entry *h;
1422 const struct elf_backend_data *bed = get_elf_backend_data (abfd);
1423 struct elf_link_hash_table *htab = elf_hash_table (info);
1424
1425 /* This function may be called more than once. */
ce558b89 1426 if (htab->sgot != NULL)
aa137e4d
NC
1427 return TRUE;
1428
1429 flags = bed->dynamic_sec_flags;
1430
3d4d4302
AM
1431 s = bfd_make_section_anyway_with_flags (abfd,
1432 (bed->rela_plts_and_copies_p
1433 ? ".rela.got" : ".rel.got"),
1434 (bed->dynamic_sec_flags
1435 | SEC_READONLY));
aa137e4d 1436 if (s == NULL
fd361982 1437 || !bfd_set_section_alignment (s, bed->s->log_file_align))
aa137e4d
NC
1438 return FALSE;
1439 htab->srelgot = s;
1440
3d4d4302 1441 s = s_got = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
aa137e4d 1442 if (s == NULL
fd361982 1443 || !bfd_set_section_alignment (s, bed->s->log_file_align))
aa137e4d
NC
1444 return FALSE;
1445 htab->sgot = s;
1446
1447 /* The first bit of the global offset table is the header. */
1448 s->size += bed->got_header_size;
1449
1450 if (bed->want_got_plt)
1451 {
3d4d4302 1452 s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
aa137e4d 1453 if (s == NULL
fd361982 1454 || !bfd_set_section_alignment (s, bed->s->log_file_align))
aa137e4d
NC
1455 return FALSE;
1456 htab->sgotplt = s;
1457
1458 /* Reserve room for the header. */
1459 s->size += GOTPLT_HEADER_SIZE (tilegx_elf_hash_table (info));
1460 }
1461
1462 if (bed->want_got_sym)
1463 {
1464 /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
1465 section. We don't do this in the linker script because we don't want
1466 to define the symbol if we are not creating a global offset
1467 table. */
1468 h = _bfd_elf_define_linkage_sym (abfd, info, s_got,
1469 "_GLOBAL_OFFSET_TABLE_");
1470 elf_hash_table (info)->hgot = h;
1471 if (h == NULL)
1472 return FALSE;
1473 }
1474
1475 return TRUE;
1476}
1477
1478/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
1479 .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
1480 hash table. */
1481
1482bfd_boolean
1483tilegx_elf_create_dynamic_sections (bfd *dynobj,
1484 struct bfd_link_info *info)
1485{
aa137e4d
NC
1486 if (!tilegx_elf_create_got_section (dynobj, info))
1487 return FALSE;
1488
9d19e4fd 1489 return _bfd_elf_create_dynamic_sections (dynobj, info);
aa137e4d
NC
1490}
1491
1492/* Copy the extra info we tack onto an elf_link_hash_entry. */
1493
1494void
1495tilegx_elf_copy_indirect_symbol (struct bfd_link_info *info,
1496 struct elf_link_hash_entry *dir,
1497 struct elf_link_hash_entry *ind)
1498{
1499 struct tilegx_elf_link_hash_entry *edir, *eind;
1500
1501 edir = (struct tilegx_elf_link_hash_entry *) dir;
1502 eind = (struct tilegx_elf_link_hash_entry *) ind;
1503
190eb1dd 1504 if (ind->dyn_relocs != NULL)
aa137e4d 1505 {
190eb1dd 1506 if (dir->dyn_relocs != NULL)
aa137e4d 1507 {
3bf083ed
AM
1508 struct elf_dyn_relocs **pp;
1509 struct elf_dyn_relocs *p;
aa137e4d
NC
1510
1511 /* Add reloc counts against the indirect sym to the direct sym
1512 list. Merge any entries against the same section. */
190eb1dd 1513 for (pp = &ind->dyn_relocs; (p = *pp) != NULL; )
aa137e4d 1514 {
3bf083ed 1515 struct elf_dyn_relocs *q;
aa137e4d 1516
190eb1dd 1517 for (q = dir->dyn_relocs; q != NULL; q = q->next)
aa137e4d
NC
1518 if (q->sec == p->sec)
1519 {
1520 q->pc_count += p->pc_count;
1521 q->count += p->count;
1522 *pp = p->next;
1523 break;
1524 }
1525 if (q == NULL)
1526 pp = &p->next;
1527 }
190eb1dd 1528 *pp = dir->dyn_relocs;
aa137e4d
NC
1529 }
1530
190eb1dd
L
1531 dir->dyn_relocs = ind->dyn_relocs;
1532 ind->dyn_relocs = NULL;
aa137e4d
NC
1533 }
1534
1535 if (ind->root.type == bfd_link_hash_indirect
1536 && dir->got.refcount <= 0)
1537 {
1538 edir->tls_type = eind->tls_type;
1539 eind->tls_type = GOT_UNKNOWN;
1540 }
1541 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
1542}
1543
6f7be959
WL
1544static int
1545tilegx_tls_translate_to_le (int r_type)
1546{
1547 switch (r_type)
1548 {
1549 case R_TILEGX_IMM16_X0_HW0_TLS_GD:
1550 case R_TILEGX_IMM16_X0_HW0_TLS_IE:
1551 return R_TILEGX_IMM16_X0_HW0_TLS_LE;
1552
1553 case R_TILEGX_IMM16_X1_HW0_TLS_GD:
1554 case R_TILEGX_IMM16_X1_HW0_TLS_IE:
1555 return R_TILEGX_IMM16_X1_HW0_TLS_LE;
1556
1557 case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
1558 case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
1559 return R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE;
1560
1561 case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
1562 case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
1563 return R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE;
1564
1565 case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
1566 case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
1567 return R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE;
1568
1569 case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
1570 case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
1571 return R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE;
1572 }
1573 return r_type;
1574}
1575
1576static int
1577tilegx_tls_translate_to_ie (int r_type)
1578{
1579 switch (r_type)
1580 {
1581 case R_TILEGX_IMM16_X0_HW0_TLS_GD:
1582 case R_TILEGX_IMM16_X0_HW0_TLS_IE:
1583 return R_TILEGX_IMM16_X0_HW0_TLS_IE;
1584
1585 case R_TILEGX_IMM16_X1_HW0_TLS_GD:
1586 case R_TILEGX_IMM16_X1_HW0_TLS_IE:
1587 return R_TILEGX_IMM16_X1_HW0_TLS_IE;
1588
1589 case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
1590 case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
1591 return R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE;
1592
1593 case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
1594 case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
1595 return R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE;
1596
1597 case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
1598 case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
1599 return R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE;
1600
1601 case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
1602 case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
1603 return R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE;
1604 }
1605 return r_type;
1606}
1607
1608static int
1609tilegx_elf_tls_transition (struct bfd_link_info *info, int r_type,
1610 int is_local, bfd_boolean disable_le_transition)
1611{
28095894 1612 if (!bfd_link_executable (info))
6f7be959
WL
1613 return r_type;
1614
1615 if (is_local && !disable_le_transition)
1616 return tilegx_tls_translate_to_le (r_type);
1617 else
1618 return tilegx_tls_translate_to_ie (r_type);
1619}
1620
aa137e4d
NC
1621/* Look through the relocs for a section during the first phase, and
1622 allocate space in the global offset table or procedure linkage
1623 table. */
1624
1625bfd_boolean
1626tilegx_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
1627 asection *sec, const Elf_Internal_Rela *relocs)
1628{
1629 struct tilegx_elf_link_hash_table *htab;
1630 Elf_Internal_Shdr *symtab_hdr;
1631 struct elf_link_hash_entry **sym_hashes;
aa137e4d
NC
1632 const Elf_Internal_Rela *rel;
1633 const Elf_Internal_Rela *rel_end;
1634 asection *sreloc;
1635 int num_relocs;
6f7be959 1636 bfd_boolean has_tls_gd_or_ie = FALSE, has_tls_add = FALSE;
aa137e4d 1637
0e1862bb 1638 if (bfd_link_relocatable (info))
aa137e4d
NC
1639 return TRUE;
1640
1641 htab = tilegx_elf_hash_table (info);
1642 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1643 sym_hashes = elf_sym_hashes (abfd);
aa137e4d
NC
1644
1645 sreloc = NULL;
1646
1647 num_relocs = sec->reloc_count;
1648
1649 BFD_ASSERT (is_tilegx_elf (abfd) || num_relocs == 0);
1650
1651 if (htab->elf.dynobj == NULL)
1652 htab->elf.dynobj = abfd;
1653
1654 rel_end = relocs + num_relocs;
6f7be959
WL
1655
1656 /* Check whether to do optimization to transform TLS GD/IE
1657 referehces to TLS LE. We disable it if we're linking with old
1658 TLS code sequences that do not support such optimization. Old
1659 TLS code sequences have tls_gd_call/tls_ie_load relocations but
1660 no tls_add relocations. */
1661 for (rel = relocs; rel < rel_end && !has_tls_add; rel++)
1662 {
1663 int r_type = TILEGX_ELF_R_TYPE (rel->r_info);
1664 switch (r_type)
1665 {
1666 case R_TILEGX_TLS_GD_CALL:
1667 case R_TILEGX_TLS_IE_LOAD:
1668 has_tls_gd_or_ie = TRUE;
1669 break;
1670 case R_TILEGX_IMM8_X0_TLS_ADD:
1671 case R_TILEGX_IMM8_Y0_TLS_ADD:
1672 case R_TILEGX_IMM8_X1_TLS_ADD:
1673 case R_TILEGX_IMM8_Y1_TLS_ADD:
1674 has_tls_add = TRUE;
1675 break;
1676 }
1677 }
1678
1679 sec->sec_flg0 = (has_tls_gd_or_ie && !has_tls_add);
1680 htab->disable_le_transition |= sec->sec_flg0;
1681
aa137e4d
NC
1682 for (rel = relocs; rel < rel_end; rel++)
1683 {
1684 unsigned int r_type;
d42c267e 1685 unsigned int r_symndx;
aa137e4d
NC
1686 struct elf_link_hash_entry *h;
1687 int tls_type;
1688
1689 r_symndx = TILEGX_ELF_R_SYMNDX (htab, rel->r_info);
1690 r_type = TILEGX_ELF_R_TYPE (rel->r_info);
1691
1692 if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
1693 {
695344c0 1694 /* xgettext:c-format */
871b3ab2 1695 _bfd_error_handler (_("%pB: bad symbol index: %d"),
4eca0228 1696 abfd, r_symndx);
aa137e4d
NC
1697 return FALSE;
1698 }
1699
1700 if (r_symndx < symtab_hdr->sh_info)
1701 h = NULL;
1702 else
1703 {
1704 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1705 while (h->root.type == bfd_link_hash_indirect
1706 || h->root.type == bfd_link_hash_warning)
1707 h = (struct elf_link_hash_entry *) h->root.u.i.link;
1708 }
1709
6f7be959
WL
1710 r_type = tilegx_elf_tls_transition (info, r_type, h == NULL,
1711 sec->sec_flg0);
aa137e4d
NC
1712 switch (r_type)
1713 {
6f7be959
WL
1714 case R_TILEGX_IMM16_X0_HW0_TLS_LE:
1715 case R_TILEGX_IMM16_X1_HW0_TLS_LE:
1716 case R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE:
1717 case R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE:
1718 case R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE:
1719 case R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE:
28095894 1720 if (!bfd_link_executable (info))
6f7be959
WL
1721 goto r_tilegx_plt32;
1722 break;
1723
aa137e4d
NC
1724 case R_TILEGX_IMM16_X0_HW0_TLS_GD:
1725 case R_TILEGX_IMM16_X1_HW0_TLS_GD:
aa137e4d
NC
1726 case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
1727 case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
1728 case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
1729 case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
0e1862bb 1730 BFD_ASSERT (bfd_link_pic (info));
6f7be959 1731 tls_type = GOT_TLS_GD;
07d6d2b8 1732 goto have_got_reference;
aa137e4d
NC
1733
1734 case R_TILEGX_IMM16_X0_HW0_TLS_IE:
1735 case R_TILEGX_IMM16_X1_HW0_TLS_IE:
aa137e4d
NC
1736 case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
1737 case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
1738 case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
1739 case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
07d6d2b8
AM
1740 tls_type = GOT_TLS_IE;
1741 if (!bfd_link_executable (info))
1742 info->flags |= DF_STATIC_TLS;
1743 goto have_got_reference;
aa137e4d
NC
1744
1745 case R_TILEGX_IMM16_X0_HW0_GOT:
1746 case R_TILEGX_IMM16_X1_HW0_GOT:
aa137e4d
NC
1747 case R_TILEGX_IMM16_X0_HW0_LAST_GOT:
1748 case R_TILEGX_IMM16_X1_HW0_LAST_GOT:
1749 case R_TILEGX_IMM16_X0_HW1_LAST_GOT:
1750 case R_TILEGX_IMM16_X1_HW1_LAST_GOT:
07d6d2b8
AM
1751 tls_type = GOT_NORMAL;
1752 /* Fall Through */
aa137e4d 1753
07d6d2b8 1754 have_got_reference:
aa137e4d
NC
1755 /* This symbol requires a global offset table entry. */
1756 {
07d6d2b8 1757 int old_tls_type;
aa137e4d
NC
1758
1759 if (h != NULL)
1760 {
1761 h->got.refcount += 1;
1762 old_tls_type = tilegx_elf_hash_entry(h)->tls_type;
1763 }
1764 else
1765 {
1766 bfd_signed_vma *local_got_refcounts;
1767
1768 /* This is a global offset table entry for a local symbol. */
1769 local_got_refcounts = elf_local_got_refcounts (abfd);
1770 if (local_got_refcounts == NULL)
1771 {
1772 bfd_size_type size;
1773
1774 size = symtab_hdr->sh_info;
1775 size *= (sizeof (bfd_signed_vma) + sizeof(char));
1776 local_got_refcounts = ((bfd_signed_vma *)
1777 bfd_zalloc (abfd, size));
1778 if (local_got_refcounts == NULL)
1779 return FALSE;
1780 elf_local_got_refcounts (abfd) = local_got_refcounts;
07d6d2b8
AM
1781 _bfd_tilegx_elf_local_got_tls_type (abfd)
1782 = (char *) (local_got_refcounts + symtab_hdr->sh_info);
aa137e4d
NC
1783 }
1784 local_got_refcounts[r_symndx] += 1;
07d6d2b8
AM
1785 old_tls_type = _bfd_tilegx_elf_local_got_tls_type (abfd) [r_symndx];
1786 }
1787
1788 /* If a TLS symbol is accessed using IE at least once,
1789 there is no point to use dynamic model for it. */
1790 if (old_tls_type != tls_type && old_tls_type != GOT_UNKNOWN
1791 && (old_tls_type != GOT_TLS_GD
1792 || tls_type != GOT_TLS_IE))
1793 {
1794 if (old_tls_type == GOT_TLS_IE && tls_type == GOT_TLS_GD)
1795 tls_type = old_tls_type;
1796 else
1797 {
4eca0228 1798 _bfd_error_handler
695344c0 1799 /* xgettext:c-format */
871b3ab2 1800 (_("%pB: `%s' accessed both as normal and thread local symbol"),
07d6d2b8
AM
1801 abfd, h ? h->root.root.string : "<local>");
1802 return FALSE;
1803 }
1804 }
1805
1806 if (old_tls_type != tls_type)
1807 {
1808 if (h != NULL)
1809 tilegx_elf_hash_entry (h)->tls_type = tls_type;
1810 else
1811 _bfd_tilegx_elf_local_got_tls_type (abfd) [r_symndx] = tls_type;
aa137e4d
NC
1812 }
1813 }
1814
1815 if (htab->elf.sgot == NULL)
1816 {
1817 if (!tilegx_elf_create_got_section (htab->elf.dynobj, info))
1818 return FALSE;
1819 }
1820 break;
1821
6f7be959 1822 case R_TILEGX_TLS_GD_CALL:
28095894 1823 if (!bfd_link_executable (info))
6f7be959
WL
1824 {
1825 /* These are basically R_TILEGX_JUMPOFF_X1_PLT relocs
1826 against __tls_get_addr. */
1827 struct bfd_link_hash_entry *bh = NULL;
1828 if (! _bfd_generic_link_add_one_symbol (info, abfd,
1829 "__tls_get_addr", 0,
1830 bfd_und_section_ptr, 0,
1831 NULL, FALSE, FALSE,
1832 &bh))
1833 return FALSE;
1834 h = (struct elf_link_hash_entry *) bh;
1835 }
1836 else
1837 break;
1838 /* Fall through */
1839
07d6d2b8 1840 case R_TILEGX_JUMPOFF_X1_PLT:
e5b95258
WL
1841 case R_TILEGX_IMM16_X0_HW0_PLT_PCREL:
1842 case R_TILEGX_IMM16_X1_HW0_PLT_PCREL:
1843 case R_TILEGX_IMM16_X0_HW1_PLT_PCREL:
1844 case R_TILEGX_IMM16_X1_HW1_PLT_PCREL:
1845 case R_TILEGX_IMM16_X0_HW2_PLT_PCREL:
1846 case R_TILEGX_IMM16_X1_HW2_PLT_PCREL:
1847 case R_TILEGX_IMM16_X0_HW3_PLT_PCREL:
1848 case R_TILEGX_IMM16_X1_HW3_PLT_PCREL:
1849 case R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL:
1850 case R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL:
1851 case R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL:
1852 case R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL:
1853 case R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL:
1854 case R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL:
aa137e4d
NC
1855 /* This symbol requires a procedure linkage table entry. We
1856 actually build the entry in adjust_dynamic_symbol,
1857 because this might be a case of linking PIC code without
1858 linking in any dynamic objects, in which case we don't
1859 need to generate a procedure linkage table after all. */
1860
1861 if (h != NULL)
07d6d2b8
AM
1862 {
1863 h->needs_plt = 1;
1864 h->plt.refcount += 1;
1865 }
aa137e4d
NC
1866 break;
1867
07d6d2b8
AM
1868 case R_TILEGX_64_PCREL:
1869 case R_TILEGX_32_PCREL:
1870 case R_TILEGX_16_PCREL:
1871 case R_TILEGX_8_PCREL:
aa137e4d
NC
1872 case R_TILEGX_IMM16_X0_HW0_PCREL:
1873 case R_TILEGX_IMM16_X1_HW0_PCREL:
1874 case R_TILEGX_IMM16_X0_HW1_PCREL:
1875 case R_TILEGX_IMM16_X1_HW1_PCREL:
1876 case R_TILEGX_IMM16_X0_HW2_PCREL:
1877 case R_TILEGX_IMM16_X1_HW2_PCREL:
1878 case R_TILEGX_IMM16_X0_HW3_PCREL:
1879 case R_TILEGX_IMM16_X1_HW3_PCREL:
1880 case R_TILEGX_IMM16_X0_HW0_LAST_PCREL:
1881 case R_TILEGX_IMM16_X1_HW0_LAST_PCREL:
1882 case R_TILEGX_IMM16_X0_HW1_LAST_PCREL:
1883 case R_TILEGX_IMM16_X1_HW1_LAST_PCREL:
1884 case R_TILEGX_IMM16_X0_HW2_LAST_PCREL:
1885 case R_TILEGX_IMM16_X1_HW2_LAST_PCREL:
1886 if (h != NULL)
1887 h->non_got_ref = 1;
1888
1889 if (h != NULL
1890 && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
1891 break;
1892 /* Fall through. */
1893
07d6d2b8
AM
1894 case R_TILEGX_64:
1895 case R_TILEGX_32:
1896 case R_TILEGX_16:
1897 case R_TILEGX_8:
aa137e4d
NC
1898 case R_TILEGX_HW0:
1899 case R_TILEGX_HW1:
1900 case R_TILEGX_HW2:
1901 case R_TILEGX_HW3:
1902 case R_TILEGX_HW0_LAST:
1903 case R_TILEGX_HW1_LAST:
1904 case R_TILEGX_HW2_LAST:
07d6d2b8
AM
1905 case R_TILEGX_COPY:
1906 case R_TILEGX_GLOB_DAT:
1907 case R_TILEGX_JMP_SLOT:
1908 case R_TILEGX_RELATIVE:
1909 case R_TILEGX_BROFF_X1:
1910 case R_TILEGX_JUMPOFF_X1:
1911 case R_TILEGX_IMM8_X0:
1912 case R_TILEGX_IMM8_Y0:
1913 case R_TILEGX_IMM8_X1:
1914 case R_TILEGX_IMM8_Y1:
1915 case R_TILEGX_DEST_IMM8_X1:
1916 case R_TILEGX_MT_IMM14_X1:
1917 case R_TILEGX_MF_IMM14_X1:
1918 case R_TILEGX_MMSTART_X0:
1919 case R_TILEGX_MMEND_X0:
1920 case R_TILEGX_SHAMT_X0:
1921 case R_TILEGX_SHAMT_X1:
1922 case R_TILEGX_SHAMT_Y0:
1923 case R_TILEGX_SHAMT_Y1:
aa137e4d
NC
1924 case R_TILEGX_IMM16_X0_HW0:
1925 case R_TILEGX_IMM16_X1_HW0:
1926 case R_TILEGX_IMM16_X0_HW1:
1927 case R_TILEGX_IMM16_X1_HW1:
1928 case R_TILEGX_IMM16_X0_HW2:
1929 case R_TILEGX_IMM16_X1_HW2:
1930 case R_TILEGX_IMM16_X0_HW3:
1931 case R_TILEGX_IMM16_X1_HW3:
1932 case R_TILEGX_IMM16_X0_HW0_LAST:
1933 case R_TILEGX_IMM16_X1_HW0_LAST:
1934 case R_TILEGX_IMM16_X0_HW1_LAST:
1935 case R_TILEGX_IMM16_X1_HW1_LAST:
1936 case R_TILEGX_IMM16_X0_HW2_LAST:
1937 case R_TILEGX_IMM16_X1_HW2_LAST:
1938 if (h != NULL)
6f7be959 1939 h->non_got_ref = 1;
aa137e4d 1940
6f7be959 1941 r_tilegx_plt32:
0e1862bb 1942 if (h != NULL && !bfd_link_pic (info))
6f7be959
WL
1943 {
1944 /* We may need a .plt entry if the function this reloc
1945 refers to is in a shared lib. */
1946 h->plt.refcount += 1;
1947 }
aa137e4d
NC
1948
1949 /* If we are creating a shared library, and this is a reloc
1950 against a global symbol, or a non PC relative reloc
1951 against a local symbol, then we need to copy the reloc
1952 into the shared library. However, if we are linking with
1953 -Bsymbolic, we do not need to copy a reloc against a
1954 global symbol which is defined in an object we are
1955 including in the link (i.e., DEF_REGULAR is set). At
1956 this point we have not seen all the input files, so it is
1957 possible that DEF_REGULAR is not set now but will be set
1958 later (it is never cleared). In case of a weak definition,
1959 DEF_REGULAR may be cleared later by a strong definition in
1960 a shared library. We account for that possibility below by
1961 storing information in the relocs_copied field of the hash
1962 table entry. A similar situation occurs when creating
1963 shared libraries and symbol visibility changes render the
1964 symbol local.
1965
1966 If on the other hand, we are creating an executable, we
1967 may need to keep relocations for symbols satisfied by a
1968 dynamic library if we manage to avoid copy relocs for the
1969 symbol. */
0e1862bb 1970 if ((bfd_link_pic (info)
aa137e4d
NC
1971 && (sec->flags & SEC_ALLOC) != 0
1972 && (! tilegx_elf_howto_table[r_type].pc_relative
1973 || (h != NULL
1974 && (! info->symbolic
1975 || h->root.type == bfd_link_hash_defweak
1976 || !h->def_regular))))
0e1862bb 1977 || (!bfd_link_pic (info)
aa137e4d
NC
1978 && (sec->flags & SEC_ALLOC) != 0
1979 && h != NULL
1980 && (h->root.type == bfd_link_hash_defweak
1981 || !h->def_regular)))
1982 {
3bf083ed
AM
1983 struct elf_dyn_relocs *p;
1984 struct elf_dyn_relocs **head;
aa137e4d
NC
1985
1986 /* When creating a shared object, we must copy these
1987 relocs into the output file. We create a reloc
1988 section in dynobj and make room for the reloc. */
1989 if (sreloc == NULL)
1990 {
1991 sreloc = _bfd_elf_make_dynamic_reloc_section
1992 (sec, htab->elf.dynobj, htab->word_align_power, abfd,
1993 /*rela?*/ TRUE);
1994
1995 if (sreloc == NULL)
1996 return FALSE;
1997 }
1998
1999 /* If this is a global symbol, we count the number of
2000 relocations we need for this symbol. */
2001 if (h != NULL)
190eb1dd 2002 head = &h->dyn_relocs;
aa137e4d
NC
2003 else
2004 {
2005 /* Track dynamic relocs needed for local syms too.
2006 We really need local syms available to do this
2007 easily. Oh well. */
2008
2009 asection *s;
2010 void *vpp;
2011 Elf_Internal_Sym *isym;
2012
2013 isym = bfd_sym_from_r_symndx (&htab->sym_cache,
2014 abfd, r_symndx);
2015 if (isym == NULL)
2016 return FALSE;
2017
2018 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2019 if (s == NULL)
2020 s = sec;
2021
2022 vpp = &elf_section_data (s)->local_dynrel;
3bf083ed 2023 head = (struct elf_dyn_relocs **) vpp;
aa137e4d
NC
2024 }
2025
2026 p = *head;
2027 if (p == NULL || p->sec != sec)
2028 {
986f0783 2029 size_t amt = sizeof *p;
3bf083ed 2030 p = ((struct elf_dyn_relocs *)
aa137e4d
NC
2031 bfd_alloc (htab->elf.dynobj, amt));
2032 if (p == NULL)
2033 return FALSE;
2034 p->next = *head;
2035 *head = p;
2036 p->sec = sec;
2037 p->count = 0;
2038 p->pc_count = 0;
2039 }
2040
2041 p->count += 1;
2042 if (tilegx_elf_howto_table[r_type].pc_relative)
2043 p->pc_count += 1;
2044 }
2045
2046 break;
2047
2048 case R_TILEGX_GNU_VTINHERIT:
2049 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2050 return FALSE;
2051 break;
2052
2053 case R_TILEGX_GNU_VTENTRY:
2054 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
2055 return FALSE;
2056 break;
2057
2058 default:
2059 break;
2060 }
2061 }
2062
2063 return TRUE;
2064}
2065
2066\f
2067asection *
2068tilegx_elf_gc_mark_hook (asection *sec,
2069 struct bfd_link_info *info,
2070 Elf_Internal_Rela *rel,
2071 struct elf_link_hash_entry *h,
2072 Elf_Internal_Sym *sym)
2073{
2074 if (h != NULL)
2075 {
2076 switch (TILEGX_ELF_R_TYPE (rel->r_info))
b45b6908
AM
2077 {
2078 case R_TILEGX_GNU_VTINHERIT:
2079 case R_TILEGX_GNU_VTENTRY:
2080 return NULL;
2081 }
2082 }
2083
2084 /* FIXME: The test here, in check_relocs and in relocate_section
0e1862bb
L
2085 dealing with TLS optimization, ought to be !bfd_link_executable (info). */
2086 if (bfd_link_pic (info))
b45b6908 2087 {
8e354058
L
2088 struct bfd_link_hash_entry *bh;
2089
b45b6908
AM
2090 switch (TILEGX_ELF_R_TYPE (rel->r_info))
2091 {
2092 case R_TILEGX_TLS_GD_CALL:
2093 /* This reloc implicitly references __tls_get_addr. We know
2094 another reloc will reference the same symbol as the one
2095 on this reloc, so the real symbol and section will be
2096 gc marked when processing the other reloc. That lets
2097 us handle __tls_get_addr here. */
8e354058
L
2098 bh = NULL;
2099 if (! _bfd_generic_link_add_one_symbol (info, sec->owner,
2100 "__tls_get_addr", 0,
2101 bfd_und_section_ptr,
2102 0, NULL, FALSE,
2103 FALSE, &bh))
2104 return NULL;
2105 h = (struct elf_link_hash_entry *) bh;
b45b6908
AM
2106 BFD_ASSERT (h != NULL);
2107 h->mark = 1;
60d67dc8
AM
2108 if (h->is_weakalias)
2109 weakdef (h)->mark = 1;
b45b6908
AM
2110 sym = NULL;
2111 }
aa137e4d
NC
2112 }
2113
2114 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
2115}
2116
63c1f59d
AM
2117/* Find dynamic relocs for H that apply to read-only sections. */
2118
2119static asection *
2120readonly_dynrelocs (struct elf_link_hash_entry *h)
2121{
3bf083ed 2122 struct elf_dyn_relocs *p;
63c1f59d 2123
190eb1dd 2124 for (p = h->dyn_relocs; p != NULL; p = p->next)
63c1f59d
AM
2125 {
2126 asection *s = p->sec->output_section;
2127
2128 if (s != NULL && (s->flags & SEC_READONLY) != 0)
2129 return p->sec;
2130 }
2131 return NULL;
2132}
2133
aa137e4d
NC
2134/* Adjust a symbol defined by a dynamic object and referenced by a
2135 regular object. The current definition is in some section of the
2136 dynamic object, but we're not including those sections. We have to
2137 change the definition to something the rest of the link can
2138 understand. */
2139
2140bfd_boolean
2141tilegx_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2142 struct elf_link_hash_entry *h)
2143{
2144 struct tilegx_elf_link_hash_table *htab;
aa137e4d 2145 bfd *dynobj;
5474d94f 2146 asection *s, *srel;
aa137e4d
NC
2147
2148 htab = tilegx_elf_hash_table (info);
2149 BFD_ASSERT (htab != NULL);
2150
2151 dynobj = htab->elf.dynobj;
2152
2153 /* Make sure we know what is going on here. */
2154 BFD_ASSERT (dynobj != NULL
2155 && (h->needs_plt
60d67dc8 2156 || h->is_weakalias
aa137e4d
NC
2157 || (h->def_dynamic
2158 && h->ref_regular
2159 && !h->def_regular)));
2160
2161 /* If this is a function, put it in the procedure linkage table. We
2162 will fill in the contents of the procedure linkage table later
2163 (although we could actually do it here). */
2164 if (h->type == STT_FUNC || h->needs_plt)
2165 {
2166 if (h->plt.refcount <= 0
2167 || SYMBOL_CALLS_LOCAL (info, h)
2168 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
2169 && h->root.type == bfd_link_hash_undefweak))
2170 {
2171 /* This case can occur if we saw a R_TILEGX_JUMPOFF_X1_PLT
07d6d2b8
AM
2172 reloc in an input file, but the symbol was never referred
2173 to by a dynamic object, or if all references were garbage
2174 collected. In such a case, we don't actually need to build
2175 a procedure linkage table, and we can just do a
2176 R_TILEGX_JUMPOFF_X1 relocation instead. */
aa137e4d
NC
2177 h->plt.offset = (bfd_vma) -1;
2178 h->needs_plt = 0;
2179 }
2180
2181 return TRUE;
2182 }
2183 else
2184 h->plt.offset = (bfd_vma) -1;
2185
2186 /* If this is a weak symbol, and there is a real definition, the
2187 processor independent code will have arranged for us to see the
2188 real definition first, and we can just use the same value. */
60d67dc8 2189 if (h->is_weakalias)
aa137e4d 2190 {
60d67dc8
AM
2191 struct elf_link_hash_entry *def = weakdef (h);
2192 BFD_ASSERT (def->root.type == bfd_link_hash_defined);
2193 h->root.u.def.section = def->root.u.def.section;
2194 h->root.u.def.value = def->root.u.def.value;
aa137e4d
NC
2195 return TRUE;
2196 }
2197
2198 /* This is a reference to a symbol defined by a dynamic object which
2199 is not a function. */
2200
2201 /* If we are creating a shared library, we must presume that the
2202 only references to the symbol are via the global offset table.
2203 For such cases we need not do anything here; the relocations will
2204 be handled correctly by relocate_section. */
0e1862bb 2205 if (bfd_link_pic (info))
aa137e4d
NC
2206 return TRUE;
2207
2208 /* If there are no references to this symbol that do not use the
2209 GOT, we don't need to generate a copy reloc. */
2210 if (!h->non_got_ref)
2211 return TRUE;
2212
2213 /* If -z nocopyreloc was given, we won't generate them either. */
2214 if (info->nocopyreloc)
2215 {
2216 h->non_got_ref = 0;
2217 return TRUE;
2218 }
2219
3bf083ed 2220 /* If we don't find any dynamic relocs in read-only sections, then
aa137e4d 2221 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
3bf083ed 2222 if (!readonly_dynrelocs (h))
aa137e4d
NC
2223 {
2224 h->non_got_ref = 0;
2225 return TRUE;
2226 }
2227
aa137e4d
NC
2228 /* We must allocate the symbol in our .dynbss section, which will
2229 become part of the .bss section of the executable. There will be
2230 an entry for this symbol in the .dynsym section. The dynamic
2231 object will contain position independent code, so all references
2232 from the dynamic object to this symbol will go through the global
2233 offset table. The dynamic linker will use the .dynsym entry to
2234 determine the address it must put in the global offset table, so
2235 both the dynamic object and the regular object will refer to the
2236 same memory location for the variable. */
2237
2238 /* We must generate a R_TILEGX_COPY reloc to tell the dynamic linker
2239 to copy the initial value out of the dynamic object and into the
2240 runtime process image. We need to remember the offset into the
2241 .rel.bss section we are going to use. */
5474d94f
AM
2242 if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
2243 {
2244 s = htab->elf.sdynrelro;
2245 srel = htab->elf.sreldynrelro;
2246 }
2247 else
2248 {
2249 s = htab->elf.sdynbss;
2250 srel = htab->elf.srelbss;
2251 }
1d7e9d18 2252 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
aa137e4d 2253 {
5474d94f 2254 srel->size += TILEGX_ELF_RELA_BYTES (htab);
aa137e4d
NC
2255 h->needs_copy = 1;
2256 }
2257
5474d94f 2258 return _bfd_elf_adjust_dynamic_copy (info, h, s);
aa137e4d
NC
2259}
2260
2261/* Allocate space in .plt, .got and associated reloc sections for
2262 dynamic relocs. */
2263
2264static bfd_boolean
e4d34ace 2265allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
aa137e4d
NC
2266{
2267 struct bfd_link_info *info;
2268 struct tilegx_elf_link_hash_table *htab;
3bf083ed 2269 struct elf_dyn_relocs *p;
aa137e4d
NC
2270
2271 if (h->root.type == bfd_link_hash_indirect)
2272 return TRUE;
2273
aa137e4d
NC
2274 info = (struct bfd_link_info *) inf;
2275 htab = tilegx_elf_hash_table (info);
2276 BFD_ASSERT (htab != NULL);
2277
2278 if (htab->elf.dynamic_sections_created
2279 && h->plt.refcount > 0)
2280 {
2281 /* Make sure this symbol is output as a dynamic symbol.
2282 Undefined weak syms won't yet be marked as dynamic. */
2283 if (h->dynindx == -1
2284 && !h->forced_local)
2285 {
2286 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2287 return FALSE;
2288 }
2289
0e1862bb 2290 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
aa137e4d
NC
2291 {
2292 asection *s = htab->elf.splt;
2293
2294 /* Allocate room for the header and tail. */
2295 if (s->size == 0)
2296 {
663b5850 2297 s->size = PLT_ENTRY_SIZE;
aa137e4d
NC
2298 }
2299
07d6d2b8 2300 h->plt.offset = s->size - PLT_ENTRY_SIZE + PLT_HEADER_SIZE;
aa137e4d
NC
2301
2302 /* If this symbol is not defined in a regular file, and we are
2303 not generating a shared library, then set the symbol to this
2304 location in the .plt. This is required to make function
2305 pointers compare as equal between the normal executable and
2306 the shared library. */
0e1862bb 2307 if (! bfd_link_pic (info)
aa137e4d
NC
2308 && !h->def_regular)
2309 {
2310 h->root.u.def.section = s;
2311 h->root.u.def.value = h->plt.offset;
2312 }
2313
2314 /* Make room for this entry. */
2315 s->size += PLT_ENTRY_SIZE;
2316
2317 /* We also need to make an entry in the .got.plt section. */
2318 htab->elf.sgotplt->size += GOT_ENTRY_SIZE (htab);
2319
2320 /* We also need to make an entry in the .rela.plt section. */
2321 htab->elf.srelplt->size += TILEGX_ELF_RELA_BYTES (htab);
2322 }
2323 else
2324 {
2325 h->plt.offset = (bfd_vma) -1;
2326 h->needs_plt = 0;
2327 }
2328 }
2329 else
2330 {
2331 h->plt.offset = (bfd_vma) -1;
2332 h->needs_plt = 0;
2333 }
2334
6f7be959
WL
2335 /* If a TLS_IE symbol is now local to the binary, make it a TLS_LE
2336 requiring no TLS entry. */
2337 if (h->got.refcount > 0
2338 && !htab->disable_le_transition
28095894 2339 && bfd_link_executable (info)
6f7be959
WL
2340 && h->dynindx == -1
2341 && tilegx_elf_hash_entry(h)->tls_type == GOT_TLS_IE)
2342 h->got.offset = (bfd_vma) -1;
2343 else if (h->got.refcount > 0)
aa137e4d
NC
2344 {
2345 asection *s;
2346 bfd_boolean dyn;
2347 int tls_type = tilegx_elf_hash_entry(h)->tls_type;
2348
2349 /* Make sure this symbol is output as a dynamic symbol.
2350 Undefined weak syms won't yet be marked as dynamic. */
2351 if (h->dynindx == -1
2352 && !h->forced_local)
2353 {
2354 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2355 return FALSE;
2356 }
2357
2358 s = htab->elf.sgot;
2359 h->got.offset = s->size;
2360 s->size += TILEGX_ELF_WORD_BYTES (htab);
2361 /* TLS_GD entries need 2 consecutive GOT slots. */
2362 if (tls_type == GOT_TLS_GD)
07d6d2b8 2363 s->size += TILEGX_ELF_WORD_BYTES (htab);
aa137e4d
NC
2364 dyn = htab->elf.dynamic_sections_created;
2365 /* TLS_IE needs one dynamic relocation,
07d6d2b8 2366 TLS_GD needs two if local symbol and two if global. */
aa137e4d
NC
2367 if (tls_type == GOT_TLS_GD || tls_type == GOT_TLS_IE)
2368 htab->elf.srelgot->size += 2 * TILEGX_ELF_RELA_BYTES (htab);
0e1862bb
L
2369 else if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
2370 bfd_link_pic (info),
2371 h))
aa137e4d
NC
2372 htab->elf.srelgot->size += TILEGX_ELF_RELA_BYTES (htab);
2373 }
2374 else
2375 h->got.offset = (bfd_vma) -1;
2376
190eb1dd 2377 if (h->dyn_relocs == NULL)
aa137e4d
NC
2378 return TRUE;
2379
2380 /* In the shared -Bsymbolic case, discard space allocated for
2381 dynamic pc-relative relocs against symbols which turn out to be
2382 defined in regular objects. For the normal shared case, discard
2383 space for pc-relative relocs that have become local due to symbol
2384 visibility changes. */
2385
0e1862bb 2386 if (bfd_link_pic (info))
aa137e4d
NC
2387 {
2388 if (SYMBOL_CALLS_LOCAL (info, h))
2389 {
3bf083ed 2390 struct elf_dyn_relocs **pp;
aa137e4d 2391
190eb1dd 2392 for (pp = &h->dyn_relocs; (p = *pp) != NULL; )
aa137e4d
NC
2393 {
2394 p->count -= p->pc_count;
2395 p->pc_count = 0;
2396 if (p->count == 0)
2397 *pp = p->next;
2398 else
2399 pp = &p->next;
2400 }
2401 }
2402
2403 /* Also discard relocs on undefined weak syms with non-default
2404 visibility. */
190eb1dd 2405 if (h->dyn_relocs != NULL
aa137e4d
NC
2406 && h->root.type == bfd_link_hash_undefweak)
2407 {
a3cd202a
L
2408 if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
2409 || UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
190eb1dd 2410 h->dyn_relocs = NULL;
aa137e4d
NC
2411
2412 /* Make sure undefined weak symbols are output as a dynamic
2413 symbol in PIEs. */
2414 else if (h->dynindx == -1
2415 && !h->forced_local)
2416 {
2417 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2418 return FALSE;
2419 }
2420 }
2421 }
2422 else
2423 {
2424 /* For the non-shared case, discard space for relocs against
2425 symbols which turn out to need copy relocs or are not
2426 dynamic. */
2427
2428 if (!h->non_got_ref
2429 && ((h->def_dynamic
2430 && !h->def_regular)
2431 || (htab->elf.dynamic_sections_created
2432 && (h->root.type == bfd_link_hash_undefweak
2433 || h->root.type == bfd_link_hash_undefined))))
2434 {
2435 /* Make sure this symbol is output as a dynamic symbol.
2436 Undefined weak syms won't yet be marked as dynamic. */
2437 if (h->dynindx == -1
2438 && !h->forced_local)
2439 {
2440 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2441 return FALSE;
2442 }
2443
2444 /* If that succeeded, we know we'll be keeping all the
2445 relocs. */
2446 if (h->dynindx != -1)
2447 goto keep;
2448 }
2449
190eb1dd 2450 h->dyn_relocs = NULL;
aa137e4d
NC
2451
2452 keep: ;
2453 }
2454
2455 /* Finally, allocate space. */
190eb1dd 2456 for (p = h->dyn_relocs; p != NULL; p = p->next)
aa137e4d
NC
2457 {
2458 asection *sreloc = elf_section_data (p->sec)->sreloc;
2459 sreloc->size += p->count * TILEGX_ELF_RELA_BYTES (htab);
2460 }
2461
2462 return TRUE;
2463}
2464
63c1f59d
AM
2465/* Set DF_TEXTREL if we find any dynamic relocs that apply to
2466 read-only sections. */
aa137e4d
NC
2467
2468static bfd_boolean
63c1f59d 2469maybe_set_textrel (struct elf_link_hash_entry *h, void *info_p)
aa137e4d 2470{
63c1f59d 2471 asection *sec;
aa137e4d 2472
63c1f59d
AM
2473 if (h->root.type == bfd_link_hash_indirect)
2474 return TRUE;
aa137e4d 2475
63c1f59d
AM
2476 sec = readonly_dynrelocs (h);
2477 if (sec != NULL)
2478 {
2479 struct bfd_link_info *info = (struct bfd_link_info *) info_p;
aa137e4d 2480
63c1f59d
AM
2481 info->flags |= DF_TEXTREL;
2482 info->callbacks->minfo
c1c8c1ef 2483 (_("%pB: dynamic relocation against `%pT' in read-only section `%pA'\n"),
63c1f59d 2484 sec->owner, h->root.root.string, sec);
007873f5 2485
63c1f59d
AM
2486 /* Not an error, just cut short the traversal. */
2487 return FALSE;
aa137e4d
NC
2488 }
2489 return TRUE;
2490}
2491
2492/* Return true if the dynamic symbol for a given section should be
2493 omitted when creating a shared library. */
2494
2495bfd_boolean
2496tilegx_elf_omit_section_dynsym (bfd *output_bfd,
2497 struct bfd_link_info *info,
2498 asection *p)
2499{
2500 /* We keep the .got section symbol so that explicit relocations
2501 against the _GLOBAL_OFFSET_TABLE_ symbol emitted in PIC mode
2502 can be turned into relocations against the .got symbol. */
2503 if (strcmp (p->name, ".got") == 0)
2504 return FALSE;
2505
d00dd7dc 2506 return _bfd_elf_omit_section_dynsym_default (output_bfd, info, p);
aa137e4d
NC
2507}
2508
2509bfd_boolean
2510tilegx_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2511 struct bfd_link_info *info)
2512{
2513 struct tilegx_elf_link_hash_table *htab;
2514 bfd *dynobj;
2515 asection *s;
2516 bfd *ibfd;
2517
2518 htab = tilegx_elf_hash_table (info);
2519 BFD_ASSERT (htab != NULL);
2520 dynobj = htab->elf.dynobj;
2521 BFD_ASSERT (dynobj != NULL);
2522
2523 if (elf_hash_table (info)->dynamic_sections_created)
2524 {
2525 /* Set the contents of the .interp section to the interpreter. */
9b8b325a 2526 if (bfd_link_executable (info) && !info->nointerp)
aa137e4d 2527 {
3d4d4302 2528 s = bfd_get_linker_section (dynobj, ".interp");
aa137e4d
NC
2529 BFD_ASSERT (s != NULL);
2530 s->size = strlen (htab->dynamic_interpreter) + 1;
2531 s->contents = (unsigned char *) htab->dynamic_interpreter;
2532 }
2533 }
2534
2535 /* Set up .got offsets for local syms, and space for local dynamic
2536 relocs. */
c72f2fb2 2537 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
aa137e4d
NC
2538 {
2539 bfd_signed_vma *local_got;
2540 bfd_signed_vma *end_local_got;
2541 char *local_tls_type;
2542 bfd_size_type locsymcount;
2543 Elf_Internal_Shdr *symtab_hdr;
2544 asection *srel;
2545
2546 if (! is_tilegx_elf (ibfd))
2547 continue;
2548
2549 for (s = ibfd->sections; s != NULL; s = s->next)
2550 {
3bf083ed 2551 struct elf_dyn_relocs *p;
aa137e4d
NC
2552
2553 for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
2554 {
2555 if (!bfd_is_abs_section (p->sec)
2556 && bfd_is_abs_section (p->sec->output_section))
2557 {
2558 /* Input section has been discarded, either because
2559 it is a copy of a linkonce section or due to
2560 linker script /DISCARD/, so we'll be discarding
2561 the relocs too. */
2562 }
2563 else if (p->count != 0)
2564 {
2565 srel = elf_section_data (p->sec)->sreloc;
2566 srel->size += p->count * TILEGX_ELF_RELA_BYTES (htab);
2567 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
007873f5
L
2568 {
2569 info->flags |= DF_TEXTREL;
2570
871b3ab2 2571 info->callbacks->minfo (_("%pB: dynamic relocation in read-only section `%pA'\n"),
007873f5
L
2572 p->sec->owner, p->sec);
2573 }
aa137e4d
NC
2574 }
2575 }
2576 }
2577
2578 local_got = elf_local_got_refcounts (ibfd);
2579 if (!local_got)
2580 continue;
2581
2582 symtab_hdr = &elf_symtab_hdr (ibfd);
2583 locsymcount = symtab_hdr->sh_info;
2584 end_local_got = local_got + locsymcount;
2585 local_tls_type = _bfd_tilegx_elf_local_got_tls_type (ibfd);
2586 s = htab->elf.sgot;
2587 srel = htab->elf.srelgot;
2588 for (; local_got < end_local_got; ++local_got, ++local_tls_type)
2589 {
2590 if (*local_got > 0)
2591 {
2592 *local_got = s->size;
2593 s->size += TILEGX_ELF_WORD_BYTES (htab);
07d6d2b8
AM
2594 if (*local_tls_type == GOT_TLS_GD)
2595 s->size += TILEGX_ELF_WORD_BYTES (htab);
2596 if (bfd_link_pic (info)
2597 || *local_tls_type == GOT_TLS_GD
2598 || *local_tls_type == GOT_TLS_IE)
aa137e4d
NC
2599 srel->size += TILEGX_ELF_RELA_BYTES (htab);
2600 }
2601 else
2602 *local_got = (bfd_vma) -1;
2603 }
2604 }
2605
2606 /* Allocate global sym .plt and .got entries, and space for global
2607 sym dynamic relocs. */
e4d34ace 2608 elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
aa137e4d
NC
2609
2610 if (elf_hash_table (info)->dynamic_sections_created)
2611 {
2612 /* If the .got section is more than 0x8000 bytes, we add
2613 0x8000 to the value of _GLOBAL_OFFSET_TABLE_, so that 16
2614 bit relocations have a greater chance of working. */
2615 if (htab->elf.sgot->size >= 0x8000
2616 && elf_hash_table (info)->hgot->root.u.def.value == 0)
2617 elf_hash_table (info)->hgot->root.u.def.value = 0x8000;
2618 }
2619
2620 if (htab->elf.sgotplt)
2621 {
2622 struct elf_link_hash_entry *got;
2623 got = elf_link_hash_lookup (elf_hash_table (info),
2624 "_GLOBAL_OFFSET_TABLE_",
2625 FALSE, FALSE, FALSE);
2626
2627 /* Don't allocate .got.plt section if there are no GOT nor PLT
07d6d2b8 2628 entries and there is no refeence to _GLOBAL_OFFSET_TABLE_. */
aa137e4d
NC
2629 if ((got == NULL
2630 || !got->ref_regular_nonweak)
2631 && (htab->elf.sgotplt->size
2632 == (unsigned)GOTPLT_HEADER_SIZE (htab))
2633 && (htab->elf.splt == NULL
2634 || htab->elf.splt->size == 0)
2635 && (htab->elf.sgot == NULL
2636 || (htab->elf.sgot->size
2637 == get_elf_backend_data (output_bfd)->got_header_size)))
2638 htab->elf.sgotplt->size = 0;
2639 }
2640
2641 /* The check_relocs and adjust_dynamic_symbol entry points have
2642 determined the sizes of the various dynamic sections. Allocate
2643 memory for them. */
2644 for (s = dynobj->sections; s != NULL; s = s->next)
2645 {
2646 if ((s->flags & SEC_LINKER_CREATED) == 0)
2647 continue;
2648
2649 if (s == htab->elf.splt
2650 || s == htab->elf.sgot
2651 || s == htab->elf.sgotplt
5474d94f
AM
2652 || s == htab->elf.sdynbss
2653 || s == htab->elf.sdynrelro)
aa137e4d
NC
2654 {
2655 /* Strip this section if we don't need it; see the
2656 comment below. */
2657 }
2658 else if (strncmp (s->name, ".rela", 5) == 0)
2659 {
2660 if (s->size != 0)
2661 {
2662 /* We use the reloc_count field as a counter if we need
2663 to copy relocs into the output file. */
2664 s->reloc_count = 0;
2665 }
2666 }
2667 else
2668 {
2669 /* It's not one of our sections. */
2670 continue;
2671 }
2672
2673 if (s->size == 0)
2674 {
2675 /* If we don't need this section, strip it from the
2676 output file. This is mostly to handle .rela.bss and
2677 .rela.plt. We must create both sections in
2678 create_dynamic_sections, because they must be created
2679 before the linker maps input sections to output
2680 sections. The linker does that before
2681 adjust_dynamic_symbol is called, and it is that
2682 function which decides whether anything needs to go
2683 into these sections. */
2684 s->flags |= SEC_EXCLUDE;
2685 continue;
2686 }
2687
2688 if ((s->flags & SEC_HAS_CONTENTS) == 0)
2689 continue;
2690
2691 /* Allocate memory for the section contents. Zero the memory
2692 for the benefit of .rela.plt, which has 4 unused entries
2693 at the beginning, and we don't want garbage. */
2694 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2695 if (s->contents == NULL)
2696 return FALSE;
2697 }
2698
2699 if (elf_hash_table (info)->dynamic_sections_created)
2700 {
2701 /* Add some entries to the .dynamic section. We fill in the
2702 values later, in tilegx_elf_finish_dynamic_sections, but we
2703 must add the entries now so that we get the correct size for
2704 the .dynamic section. The DT_DEBUG entry is filled in by the
2705 dynamic linker and used by the debugger. */
2706#define add_dynamic_entry(TAG, VAL) \
2707 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
2708
0e1862bb 2709 if (bfd_link_executable (info))
aa137e4d
NC
2710 {
2711 if (!add_dynamic_entry (DT_DEBUG, 0))
2712 return FALSE;
2713 }
2714
2715 if (htab->elf.srelplt->size != 0)
2716 {
2717 if (!add_dynamic_entry (DT_PLTGOT, 0)
2718 || !add_dynamic_entry (DT_PLTRELSZ, 0)
2719 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
2720 || !add_dynamic_entry (DT_JMPREL, 0))
2721 return FALSE;
2722 }
2723
2724 if (!add_dynamic_entry (DT_RELA, 0)
2725 || !add_dynamic_entry (DT_RELASZ, 0)
2726 || !add_dynamic_entry (DT_RELAENT, TILEGX_ELF_RELA_BYTES (htab)))
2727 return FALSE;
2728
2729 /* If any dynamic relocs apply to a read-only section,
2730 then we need a DT_TEXTREL entry. */
2731 if ((info->flags & DF_TEXTREL) == 0)
63c1f59d 2732 elf_link_hash_traverse (&htab->elf, maybe_set_textrel, info);
aa137e4d
NC
2733
2734 if (info->flags & DF_TEXTREL)
2735 {
2736 if (!add_dynamic_entry (DT_TEXTREL, 0))
2737 return FALSE;
2738 }
2739 }
2740#undef add_dynamic_entry
2741
2742 return TRUE;
2743}
2744\f
2745/* Return the base VMA address which should be subtracted from real addresses
2746 when resolving @dtpoff relocation.
2747 This is PT_TLS segment p_vaddr. */
2748
2749static bfd_vma
2750dtpoff_base (struct bfd_link_info *info)
2751{
2752 /* If tls_sec is NULL, we should have signalled an error already. */
2753 if (elf_hash_table (info)->tls_sec == NULL)
2754 return 0;
2755 return elf_hash_table (info)->tls_sec->vma;
2756}
2757
2758/* Return the relocation value for @tpoff relocation. */
2759
2760static bfd_vma
2761tpoff (struct bfd_link_info *info, bfd_vma address)
2762{
2763 struct elf_link_hash_table *htab = elf_hash_table (info);
2764
2765 /* If tls_sec is NULL, we should have signalled an error already. */
2766 if (htab->tls_sec == NULL)
2767 return 0;
2768
2769 return (address - htab->tls_sec->vma);
2770}
2771
6f7be959
WL
2772/* Copy SIZE bits from FROM to TO at address ADDR. */
2773
2774static void
2775tilegx_copy_bits (bfd_byte *addr, int from, int to, int size)
2776{
2777 int i;
2778 for (i = 0; i < size; i++)
2779 {
2780 int from_byte = (from + i) / 8;
2781 int from_bit = (from + i) % 8;
2782 int to_byte = (to + i) / 8;
2783 int to_bit = (to + i) % 8;
2784 bfd_byte to_mask = 1 << to_bit;
2785 addr[to_byte] = (addr[to_byte] & ~to_mask)
2786 | ((addr[from_byte] >> from_bit << to_bit) & to_mask);
2787 }
2788}
2789
2790/* Replace the MASK bits in ADDR with those in INSN, for the next
2791 TILEGX_BUNDLE_SIZE_IN_BYTES bytes. */
2792
2793static void
2794tilegx_replace_insn (bfd_byte *addr, const bfd_byte *mask,
2795 const bfd_byte *insn)
2796{
2797 int i;
2798 for (i = 0; i < TILEGX_BUNDLE_SIZE_IN_BYTES; i++)
2799 {
2800 addr[i] = (addr[i] & ~mask[i]) | (insn[i] & mask[i]);
2801 }
2802}
2803
2804/* Mask to extract the bits corresponding to an instruction in a
2805 specific pipe of a bundle. */
2806static const bfd_byte insn_mask_X1[] = {
2807 0x00, 0x00, 0x00, 0x80, 0xff, 0xff, 0xff, 0x3f
2808};
2809
2810/* Mask to extract the bits corresponding to an instruction in a
2811 specific pipe of a bundle, minus the destination operand and the
2812 first source operand. */
68ffbac6 2813static const bfd_byte insn_mask_X0_no_dest_no_srca[] = {
6f7be959
WL
2814 0x00, 0xf0, 0xff, 0x7f, 0x00, 0x00, 0x00, 0x00
2815};
2816
2817static const bfd_byte insn_mask_X1_no_dest_no_srca[] = {
2818 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0xff, 0x3f
2819};
2820
2821static const bfd_byte insn_mask_Y0_no_dest_no_srca[] = {
2822 0x00, 0xf0, 0x0f, 0x78, 0x00, 0x00, 0x00, 0x00
2823};
2824static const bfd_byte insn_mask_Y1_no_dest_no_srca[] = {
2825 0x00, 0x00, 0x00, 0x00, 0x00, 0xf8, 0x07, 0x3c
2826};
2827
2828/* Mask to extract the bits corresponding to an instruction in a
2829 specific pipe of a bundle, minus the register operands. */
2830static const bfd_byte insn_mask_X0_no_operand[] = {
2831 0x00, 0x00, 0xfc, 0x7f, 0x00, 0x00, 0x00, 0x00
2832};
2833
2834static const bfd_byte insn_mask_X1_no_operand[] = {
2835 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xfe, 0x3f
2836};
2837
2838static const bfd_byte insn_mask_Y0_no_operand[] = {
2839 0x00, 0x00, 0x0c, 0x78, 0x00, 0x00, 0x00, 0x00
2840};
2841
2842static const bfd_byte insn_mask_Y1_no_operand[] = {
2843 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x3c
2844};
2845
2846/* Various instructions synthesized to support tls references. */
2847
2848/* ld r0, r0 in the X1 pipe, used for tls ie. */
2849static const bfd_byte insn_tls_ie_ld_X1[] = {
2850 0x00, 0x00, 0x00, 0x00, 0x00, 0xe8, 0x6a, 0x28
2851};
2852
2853/* ld4s r0, r0 in the X1 pipe, used for tls ie. */
2854static const bfd_byte insn_tls_ie_ld4s_X1[] = {
2855 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x6a, 0x28
2856};
2857
2858/* add r0, r0, tp in various pipes, used for tls ie. */
2859static const bfd_byte insn_tls_ie_add_X0X1[] = {
2860 0x00, 0x50, 0x0f, 0x50, 0x00, 0xa8, 0x07, 0x28
2861};
2862static const bfd_byte insn_tls_ie_add_Y0Y1[] = {
2863 0x00, 0x50, 0x27, 0x2c, 0x00, 0xa8, 0x13, 0x9a
2864};
2865
2866/* addx r0, r0, tp in various pipes, used for tls ie. */
2867static const bfd_byte insn_tls_ie_addx_X0X1[] = {
2868 0x00, 0x50, 0x0b, 0x50, 0x00, 0xa8, 0x05, 0x28
2869};
2870static const bfd_byte insn_tls_ie_addx_Y0Y1[] = {
2871 0x00, 0x50, 0x03, 0x2c, 0x00, 0xa8, 0x01, 0x9a
2872};
2873
2874/* move r0, r0 in various pipes, used for tls gd. */
2875static const bfd_byte insn_tls_gd_add_X0X1[] = {
2876 0x00, 0xf0, 0x07, 0x51, 0x00, 0xf8, 0x3b, 0x28
2877};
2878static const bfd_byte insn_tls_gd_add_Y0Y1[] = {
2879 0x00, 0xf0, 0x0b, 0x54, 0x00, 0xf8, 0x05, 0xae
2880};
2881
2882static const bfd_byte *insn_move_X0X1 = insn_tls_gd_add_X0X1;
2883static const bfd_byte *insn_move_Y0Y1 = insn_tls_gd_add_Y0Y1;
2884
2885static const bfd_byte *insn_add_X0X1 = insn_tls_ie_add_X0X1;
2886static const bfd_byte *insn_add_Y0Y1 = insn_tls_ie_add_Y0Y1;
2887
2888static const bfd_byte *insn_addx_X0X1 = insn_tls_ie_addx_X0X1;
2889static const bfd_byte *insn_addx_Y0Y1 = insn_tls_ie_addx_Y0Y1;
2890
aa137e4d
NC
2891/* Relocate an TILEGX ELF section.
2892
2893 The RELOCATE_SECTION function is called by the new ELF backend linker
2894 to handle the relocations for a section.
2895
2896 The relocs are always passed as Rela structures.
2897
2898 This function is responsible for adjusting the section contents as
2899 necessary, and (if generating a relocatable output file) adjusting
2900 the reloc addend as necessary.
2901
2902 This function does not have to worry about setting the reloc
2903 address or the reloc symbol index.
2904
2905 LOCAL_SYMS is a pointer to the swapped in local symbols.
2906
2907 LOCAL_SECTIONS is an array giving the section in the input file
2908 corresponding to the st_shndx field of each local symbol.
2909
2910 The global hash table entry for the global symbols can be found
2911 via elf_sym_hashes (input_bfd).
2912
2913 When generating relocatable output, this function must handle
2914 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
2915 going to be the section symbol corresponding to the output
2916 section, which means that the addend must be adjusted
2917 accordingly. */
2918
2919bfd_boolean
2920tilegx_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
2921 bfd *input_bfd, asection *input_section,
2922 bfd_byte *contents, Elf_Internal_Rela *relocs,
2923 Elf_Internal_Sym *local_syms,
2924 asection **local_sections)
2925{
2926 struct tilegx_elf_link_hash_table *htab;
2927 Elf_Internal_Shdr *symtab_hdr;
2928 struct elf_link_hash_entry **sym_hashes;
2929 bfd_vma *local_got_offsets;
535127d2 2930 bfd_vma got_base;
aa137e4d
NC
2931 asection *sreloc;
2932 Elf_Internal_Rela *rel;
2933 Elf_Internal_Rela *relend;
2934 int num_relocs;
2935
2936 htab = tilegx_elf_hash_table (info);
2937 BFD_ASSERT (htab != NULL);
2938 symtab_hdr = &elf_symtab_hdr (input_bfd);
2939 sym_hashes = elf_sym_hashes (input_bfd);
2940 local_got_offsets = elf_local_got_offsets (input_bfd);
2941
535127d2
WL
2942 if (elf_hash_table (info)->hgot == NULL)
2943 got_base = 0;
2944 else
2945 got_base = elf_hash_table (info)->hgot->root.u.def.value;
2946
aa137e4d
NC
2947 sreloc = elf_section_data (input_section)->sreloc;
2948
2949 rel = relocs;
2950 num_relocs = input_section->reloc_count;
2951 relend = relocs + num_relocs;
2952 for (; rel < relend; rel++)
2953 {
2954 int r_type, tls_type;
6f7be959 2955 bfd_boolean is_tls_iele, is_tls_le;
aa137e4d
NC
2956 reloc_howto_type *howto;
2957 unsigned long r_symndx;
2958 struct elf_link_hash_entry *h;
2959 Elf_Internal_Sym *sym;
2960 tilegx_create_func create_func;
2961 asection *sec;
2962 bfd_vma relocation;
2963 bfd_reloc_status_type r;
2964 const char *name;
2965 bfd_vma off;
2966 bfd_boolean is_plt = FALSE;
a3cd202a 2967 bfd_boolean resolved_to_zero;
aa137e4d
NC
2968 bfd_boolean unresolved_reloc;
2969
2970 r_type = TILEGX_ELF_R_TYPE (rel->r_info);
2971 if (r_type == R_TILEGX_GNU_VTINHERIT
2972 || r_type == R_TILEGX_GNU_VTENTRY)
2973 continue;
2974
2975 if ((unsigned int)r_type >= ARRAY_SIZE (tilegx_elf_howto_table))
47aeb64c 2976 return _bfd_unrecognized_reloc (input_bfd, input_section, r_type);
aa137e4d
NC
2977
2978 howto = tilegx_elf_howto_table + r_type;
2979
2980 /* This is a final link. */
2981 r_symndx = TILEGX_ELF_R_SYMNDX (htab, rel->r_info);
2982 h = NULL;
2983 sym = NULL;
2984 sec = NULL;
2985 unresolved_reloc = FALSE;
2986 if (r_symndx < symtab_hdr->sh_info)
2987 {
2988 sym = local_syms + r_symndx;
2989 sec = local_sections[r_symndx];
2990 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
2991 }
2992 else
2993 {
62d887d4
L
2994 bfd_boolean warned ATTRIBUTE_UNUSED;
2995 bfd_boolean ignored ATTRIBUTE_UNUSED;
aa137e4d
NC
2996
2997 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
2998 r_symndx, symtab_hdr, sym_hashes,
2999 h, sec, relocation,
62d887d4 3000 unresolved_reloc, warned, ignored);
aa137e4d
NC
3001 if (warned)
3002 {
3003 /* To avoid generating warning messages about truncated
3004 relocations, set the relocation's address to be the same as
3005 the start of this section. */
3006 if (input_section->output_section != NULL)
3007 relocation = input_section->output_section->vma;
3008 else
3009 relocation = 0;
3010 }
3011 }
3012
dbaa2011 3013 if (sec != NULL && discarded_section (sec))
aa137e4d 3014 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
545fd46b 3015 rel, 1, relend, howto, 0, contents);
aa137e4d 3016
0e1862bb 3017 if (bfd_link_relocatable (info))
aa137e4d
NC
3018 continue;
3019
3020 if (h != NULL)
3021 name = h->root.root.string;
3022 else
3023 {
3024 name = (bfd_elf_string_from_elf_section
3025 (input_bfd, symtab_hdr->sh_link, sym->st_name));
3026 if (name == NULL || *name == '\0')
fd361982 3027 name = bfd_section_name (sec);
aa137e4d
NC
3028 }
3029
6f7be959
WL
3030 switch (r_type)
3031 {
3032 case R_TILEGX_TLS_GD_CALL:
3033 case R_TILEGX_IMM8_X0_TLS_GD_ADD:
3034 case R_TILEGX_IMM8_Y0_TLS_GD_ADD:
3035 case R_TILEGX_IMM8_X1_TLS_GD_ADD:
3036 case R_TILEGX_IMM8_Y1_TLS_GD_ADD:
3037 case R_TILEGX_IMM8_X0_TLS_ADD:
3038 case R_TILEGX_IMM8_Y0_TLS_ADD:
3039 case R_TILEGX_IMM8_X1_TLS_ADD:
3040 case R_TILEGX_IMM8_Y1_TLS_ADD:
3041 tls_type = GOT_UNKNOWN;
3042 if (h == NULL && local_got_offsets)
3043 tls_type =
3044 _bfd_tilegx_elf_local_got_tls_type (input_bfd) [r_symndx];
3045 else if (h != NULL)
3046 tls_type = tilegx_elf_hash_entry(h)->tls_type;
3047
28095894 3048 is_tls_iele = (bfd_link_executable (info) || tls_type == GOT_TLS_IE);
6f7be959 3049 is_tls_le = is_tls_iele && (!input_section->sec_flg0
28095894 3050 && bfd_link_executable (info)
6f7be959
WL
3051 && (h == NULL || h->dynindx == -1));
3052
3053 if (r_type == R_TILEGX_TLS_GD_CALL)
3054 {
3055 if (is_tls_le)
3056 {
3057 /* GD -> LE */
3058 tilegx_replace_insn (contents + rel->r_offset,
3059 insn_mask_X1, insn_move_X0X1);
3060 continue;
3061 }
3062 else if (is_tls_iele)
3063 {
3064 /* GD -> IE */
3065 if (ABI_64_P (output_bfd))
3066 tilegx_replace_insn (contents + rel->r_offset,
3067 insn_mask_X1, insn_tls_ie_ld_X1);
3068 else
3069 tilegx_replace_insn (contents + rel->r_offset,
3070 insn_mask_X1, insn_tls_ie_ld4s_X1);
3071 continue;
3072 }
3073
3074 /* GD -> GD */
3075 h = (struct elf_link_hash_entry *)
3076 bfd_link_hash_lookup (info->hash, "__tls_get_addr", FALSE,
3077 FALSE, TRUE);
3078 BFD_ASSERT (h != NULL);
3079 r_type = R_TILEGX_JUMPOFF_X1_PLT;
3080 howto = tilegx_elf_howto_table + r_type;
3081 }
3082 else if (r_type == R_TILEGX_IMM8_X0_TLS_ADD
3083 || r_type == R_TILEGX_IMM8_X1_TLS_ADD
3084 || r_type == R_TILEGX_IMM8_Y0_TLS_ADD
3085 || r_type == R_TILEGX_IMM8_Y1_TLS_ADD)
3086 {
3087 bfd_boolean is_pipe0 =
3088 (r_type == R_TILEGX_IMM8_X0_TLS_ADD
3089 || r_type == R_TILEGX_IMM8_Y0_TLS_ADD);
3090 bfd_boolean is_X0X1 =
3091 (r_type == R_TILEGX_IMM8_X0_TLS_ADD
3092 || r_type == R_TILEGX_IMM8_X1_TLS_ADD);
3093 int dest_begin = is_pipe0 ? 0 : 31;
3094 int src_begin;
3095 const bfd_byte *insn;
84abc003 3096 const bfd_byte *mask = NULL;
6f7be959
WL
3097
3098 if (is_tls_le)
3099 {
3100 /* 1. copy dest operand into the first source operand.
3101 2. change the opcode to "move". */
3102 src_begin = is_pipe0 ? 6 : 37;
3103 insn = is_X0X1 ? insn_move_X0X1 : insn_move_Y0Y1;
3104
3105 switch (r_type)
3106 {
3107 case R_TILEGX_IMM8_X0_TLS_ADD:
3108 mask = insn_mask_X0_no_dest_no_srca;
3109 break;
3110 case R_TILEGX_IMM8_X1_TLS_ADD:
3111 mask = insn_mask_X1_no_dest_no_srca;
3112 break;
3113 case R_TILEGX_IMM8_Y0_TLS_ADD:
3114 mask = insn_mask_Y0_no_dest_no_srca;
3115 break;
3116 case R_TILEGX_IMM8_Y1_TLS_ADD:
3117 mask = insn_mask_Y1_no_dest_no_srca;
3118 break;
3119 }
3120 }
3121 else
3122 {
3123 /* 1. copy dest operand into the second source operand.
3124 2. change the opcode to "add". */
3125 src_begin = is_pipe0 ? 12 : 43;
3126 if (ABI_64_P (output_bfd))
3127 insn = is_X0X1 ? insn_add_X0X1 : insn_add_Y0Y1;
3128 else
3129 insn = is_X0X1 ? insn_addx_X0X1 : insn_addx_Y0Y1;
3130
3131 switch (r_type)
3132 {
3133 case R_TILEGX_IMM8_X0_TLS_ADD:
3134 mask = insn_mask_X0_no_operand;
3135 break;
3136 case R_TILEGX_IMM8_X1_TLS_ADD:
3137 mask = insn_mask_X1_no_operand;
3138 break;
3139 case R_TILEGX_IMM8_Y0_TLS_ADD:
3140 mask = insn_mask_Y0_no_operand;
3141 break;
3142 case R_TILEGX_IMM8_Y1_TLS_ADD:
3143 mask = insn_mask_Y1_no_operand;
3144 break;
3145 }
3146 }
3147
3148 tilegx_copy_bits (contents + rel->r_offset, dest_begin,
3149 src_begin, 6);
3150 tilegx_replace_insn (contents + rel->r_offset, mask, insn);
3151
3152 continue;
3153 }
3154 else
3155 {
3156 const bfd_byte *mask = NULL;
3157 const bfd_byte *add_insn = NULL;
3158 bfd_boolean is_64bit = ABI_64_P (output_bfd);
3159
3160 switch (r_type)
3161 {
3162 case R_TILEGX_IMM8_X0_TLS_GD_ADD:
3163 add_insn = is_tls_iele
3164 ? (is_64bit ? insn_tls_ie_add_X0X1 : insn_tls_ie_addx_X0X1)
3165 : insn_tls_gd_add_X0X1;
3166 mask = insn_mask_X0_no_dest_no_srca;
3167 break;
3168 case R_TILEGX_IMM8_X1_TLS_GD_ADD:
3169 add_insn = is_tls_iele
3170 ? (is_64bit ? insn_tls_ie_add_X0X1 : insn_tls_ie_addx_X0X1)
3171 : insn_tls_gd_add_X0X1;
3172 mask = insn_mask_X1_no_dest_no_srca;
3173 break;
3174 case R_TILEGX_IMM8_Y0_TLS_GD_ADD:
3175 add_insn = is_tls_iele
3176 ? (is_64bit ? insn_tls_ie_add_Y0Y1 : insn_tls_ie_addx_Y0Y1)
3177 : insn_tls_gd_add_Y0Y1;
3178 mask = insn_mask_Y0_no_dest_no_srca;
3179 break;
3180 case R_TILEGX_IMM8_Y1_TLS_GD_ADD:
3181 add_insn = is_tls_iele
3182 ? (is_64bit ? insn_tls_ie_add_Y0Y1 : insn_tls_ie_addx_Y0Y1)
3183 : insn_tls_gd_add_Y0Y1;
3184 mask = insn_mask_Y1_no_dest_no_srca;
3185 break;
3186 }
3187
3188 tilegx_replace_insn (contents + rel->r_offset, mask, add_insn);
3189
3190 continue;
3191 }
3192 break;
3193 case R_TILEGX_TLS_IE_LOAD:
3194 if (!input_section->sec_flg0
28095894 3195 && bfd_link_executable (info)
6f7be959
WL
3196 && (h == NULL || h->dynindx == -1))
3197 {
3198 /* IE -> LE */
3199 tilegx_replace_insn (contents + rel->r_offset,
3200 insn_mask_X1_no_dest_no_srca,
3201 insn_move_X0X1);
3202 }
3203 else
3204 {
3205 /* IE -> IE */
3206 if (ABI_64_P (output_bfd))
3207 tilegx_replace_insn (contents + rel->r_offset,
3208 insn_mask_X1_no_dest_no_srca,
3209 insn_tls_ie_ld_X1);
3210 else
3211 tilegx_replace_insn (contents + rel->r_offset,
3212 insn_mask_X1_no_dest_no_srca,
3213 insn_tls_ie_ld4s_X1);
3214 }
3215 continue;
3216 break;
3217 default:
3218 break;
3219 }
3220
a3cd202a
L
3221 resolved_to_zero = (h != NULL
3222 && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
3223
aa137e4d
NC
3224 switch (r_type)
3225 {
3226 case R_TILEGX_IMM16_X0_HW0_GOT:
3227 case R_TILEGX_IMM16_X1_HW0_GOT:
aa137e4d
NC
3228 case R_TILEGX_IMM16_X0_HW0_LAST_GOT:
3229 case R_TILEGX_IMM16_X1_HW0_LAST_GOT:
3230 case R_TILEGX_IMM16_X0_HW1_LAST_GOT:
3231 case R_TILEGX_IMM16_X1_HW1_LAST_GOT:
aa137e4d
NC
3232 /* Relocation is to the entry for this symbol in the global
3233 offset table. */
3234 if (htab->elf.sgot == NULL)
3235 abort ();
3236
3237 if (h != NULL)
3238 {
3239 bfd_boolean dyn;
3240
3241 off = h->got.offset;
3242 BFD_ASSERT (off != (bfd_vma) -1);
3243 dyn = elf_hash_table (info)->dynamic_sections_created;
3244
0e1862bb
L
3245 if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
3246 bfd_link_pic (info),
3247 h)
3248 || (bfd_link_pic (info)
aa137e4d
NC
3249 && SYMBOL_REFERENCES_LOCAL (info, h)))
3250 {
3251 /* This is actually a static link, or it is a
3252 -Bsymbolic link and the symbol is defined
3253 locally, or the symbol was forced to be local
3254 because of a version file. We must initialize
3255 this entry in the global offset table. Since the
3256 offset must always be a multiple
3257 of 8 for 64-bit, we use the least significant bit
3258 to record whether we have initialized it already.
3259
3260 When doing a dynamic link, we create a .rela.got
3261 relocation entry to initialize the value. This
3262 is done in the finish_dynamic_symbol routine. */
3263 if ((off & 1) != 0)
3264 off &= ~1;
3265 else
3266 {
3267 TILEGX_ELF_PUT_WORD (htab, output_bfd, relocation,
3268 htab->elf.sgot->contents + off);
3269 h->got.offset |= 1;
3270 }
3271 }
3272 else
3273 unresolved_reloc = FALSE;
3274 }
3275 else
3276 {
3277 BFD_ASSERT (local_got_offsets != NULL
3278 && local_got_offsets[r_symndx] != (bfd_vma) -1);
3279
3280 off = local_got_offsets[r_symndx];
3281
3282 /* The offset must always be a multiple of 8 on 64-bit.
07d6d2b8 3283 We use the least significant bit to record
aa137e4d
NC
3284 whether we have already processed this entry. */
3285 if ((off & 1) != 0)
3286 off &= ~1;
3287 else
3288 {
0e1862bb 3289 if (bfd_link_pic (info))
aa137e4d
NC
3290 {
3291 asection *s;
3292 Elf_Internal_Rela outrel;
3293
3294 /* We need to generate a R_TILEGX_RELATIVE reloc
3295 for the dynamic linker. */
3296 s = htab->elf.srelgot;
3297 BFD_ASSERT (s != NULL);
3298
3299 outrel.r_offset = (htab->elf.sgot->output_section->vma
3300 + htab->elf.sgot->output_offset
3301 + off);
3302 outrel.r_info =
3303 TILEGX_ELF_R_INFO (htab, NULL, 0, R_TILEGX_RELATIVE);
3304 outrel.r_addend = relocation;
3305 relocation = 0;
3306 tilegx_elf_append_rela (output_bfd, s, &outrel);
3307 }
3308
3309 TILEGX_ELF_PUT_WORD (htab, output_bfd, relocation,
3310 htab->elf.sgot->contents + off);
3311 local_got_offsets[r_symndx] |= 1;
3312 }
3313 }
535127d2 3314 relocation = off - got_base;
aa137e4d
NC
3315 break;
3316
07d6d2b8 3317 case R_TILEGX_JUMPOFF_X1_PLT:
e5b95258
WL
3318 case R_TILEGX_IMM16_X0_HW0_PLT_PCREL:
3319 case R_TILEGX_IMM16_X1_HW0_PLT_PCREL:
3320 case R_TILEGX_IMM16_X0_HW1_PLT_PCREL:
3321 case R_TILEGX_IMM16_X1_HW1_PLT_PCREL:
3322 case R_TILEGX_IMM16_X0_HW2_PLT_PCREL:
3323 case R_TILEGX_IMM16_X1_HW2_PLT_PCREL:
3324 case R_TILEGX_IMM16_X0_HW3_PLT_PCREL:
3325 case R_TILEGX_IMM16_X1_HW3_PLT_PCREL:
3326 case R_TILEGX_IMM16_X0_HW0_LAST_PLT_PCREL:
3327 case R_TILEGX_IMM16_X1_HW0_LAST_PLT_PCREL:
3328 case R_TILEGX_IMM16_X0_HW1_LAST_PLT_PCREL:
3329 case R_TILEGX_IMM16_X1_HW1_LAST_PLT_PCREL:
3330 case R_TILEGX_IMM16_X0_HW2_LAST_PLT_PCREL:
3331 case R_TILEGX_IMM16_X1_HW2_LAST_PLT_PCREL:
aa137e4d
NC
3332 /* Relocation is to the entry for this symbol in the
3333 procedure linkage table. */
07d6d2b8 3334 BFD_ASSERT (h != NULL);
aa137e4d
NC
3335
3336 if (h->plt.offset == (bfd_vma) -1 || htab->elf.splt == NULL)
3337 {
3338 /* We didn't make a PLT entry for this symbol. This
3339 happens when statically linking PIC code, or when
3340 using -Bsymbolic. */
3341 break;
3342 }
3343
3344 relocation = (htab->elf.splt->output_section->vma
3345 + htab->elf.splt->output_offset
3346 + h->plt.offset);
3347 unresolved_reloc = FALSE;
3348 break;
3349
07d6d2b8
AM
3350 case R_TILEGX_64_PCREL:
3351 case R_TILEGX_32_PCREL:
3352 case R_TILEGX_16_PCREL:
3353 case R_TILEGX_8_PCREL:
aa137e4d
NC
3354 case R_TILEGX_IMM16_X0_HW0_PCREL:
3355 case R_TILEGX_IMM16_X1_HW0_PCREL:
3356 case R_TILEGX_IMM16_X0_HW1_PCREL:
3357 case R_TILEGX_IMM16_X1_HW1_PCREL:
3358 case R_TILEGX_IMM16_X0_HW2_PCREL:
3359 case R_TILEGX_IMM16_X1_HW2_PCREL:
3360 case R_TILEGX_IMM16_X0_HW3_PCREL:
3361 case R_TILEGX_IMM16_X1_HW3_PCREL:
3362 case R_TILEGX_IMM16_X0_HW0_LAST_PCREL:
3363 case R_TILEGX_IMM16_X1_HW0_LAST_PCREL:
3364 case R_TILEGX_IMM16_X0_HW1_LAST_PCREL:
3365 case R_TILEGX_IMM16_X1_HW1_LAST_PCREL:
3366 case R_TILEGX_IMM16_X0_HW2_LAST_PCREL:
3367 case R_TILEGX_IMM16_X1_HW2_LAST_PCREL:
3368 if (h != NULL
3369 && strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0)
3370 break;
3371 /* Fall through. */
07d6d2b8
AM
3372 case R_TILEGX_64:
3373 case R_TILEGX_32:
3374 case R_TILEGX_16:
3375 case R_TILEGX_8:
aa137e4d
NC
3376 case R_TILEGX_HW0:
3377 case R_TILEGX_HW1:
3378 case R_TILEGX_HW2:
3379 case R_TILEGX_HW3:
3380 case R_TILEGX_HW0_LAST:
3381 case R_TILEGX_HW1_LAST:
3382 case R_TILEGX_HW2_LAST:
07d6d2b8
AM
3383 case R_TILEGX_COPY:
3384 case R_TILEGX_GLOB_DAT:
3385 case R_TILEGX_JMP_SLOT:
3386 case R_TILEGX_RELATIVE:
3387 case R_TILEGX_BROFF_X1:
3388 case R_TILEGX_JUMPOFF_X1:
3389 case R_TILEGX_IMM8_X0:
3390 case R_TILEGX_IMM8_Y0:
3391 case R_TILEGX_IMM8_X1:
3392 case R_TILEGX_IMM8_Y1:
3393 case R_TILEGX_DEST_IMM8_X1:
3394 case R_TILEGX_MT_IMM14_X1:
3395 case R_TILEGX_MF_IMM14_X1:
3396 case R_TILEGX_MMSTART_X0:
3397 case R_TILEGX_MMEND_X0:
3398 case R_TILEGX_SHAMT_X0:
3399 case R_TILEGX_SHAMT_X1:
3400 case R_TILEGX_SHAMT_Y0:
3401 case R_TILEGX_SHAMT_Y1:
aa137e4d
NC
3402 case R_TILEGX_IMM16_X0_HW0:
3403 case R_TILEGX_IMM16_X1_HW0:
3404 case R_TILEGX_IMM16_X0_HW1:
3405 case R_TILEGX_IMM16_X1_HW1:
3406 case R_TILEGX_IMM16_X0_HW2:
3407 case R_TILEGX_IMM16_X1_HW2:
3408 case R_TILEGX_IMM16_X0_HW3:
3409 case R_TILEGX_IMM16_X1_HW3:
3410 case R_TILEGX_IMM16_X0_HW0_LAST:
3411 case R_TILEGX_IMM16_X1_HW0_LAST:
3412 case R_TILEGX_IMM16_X0_HW1_LAST:
3413 case R_TILEGX_IMM16_X1_HW1_LAST:
3414 case R_TILEGX_IMM16_X0_HW2_LAST:
3415 case R_TILEGX_IMM16_X1_HW2_LAST:
3416 if ((input_section->flags & SEC_ALLOC) == 0)
3417 break;
3418
0e1862bb 3419 if ((bfd_link_pic (info)
aa137e4d 3420 && (h == NULL
a3cd202a
L
3421 || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3422 && !resolved_to_zero)
aa137e4d
NC
3423 || h->root.type != bfd_link_hash_undefweak)
3424 && (! howto->pc_relative
3425 || !SYMBOL_CALLS_LOCAL (info, h)))
0e1862bb 3426 || (!bfd_link_pic (info)
aa137e4d
NC
3427 && h != NULL
3428 && h->dynindx != -1
3429 && !h->non_got_ref
3430 && ((h->def_dynamic
3431 && !h->def_regular)
3432 || h->root.type == bfd_link_hash_undefweak
3433 || h->root.type == bfd_link_hash_undefined)))
3434 {
3435 Elf_Internal_Rela outrel;
3436 bfd_boolean skip, relocate = FALSE;
3437
3438 /* When generating a shared object, these relocations
3439 are copied into the output file to be resolved at run
3440 time. */
3441
3442 BFD_ASSERT (sreloc != NULL);
3443
3444 skip = FALSE;
3445
3446 outrel.r_offset =
3447 _bfd_elf_section_offset (output_bfd, info, input_section,
3448 rel->r_offset);
3449 if (outrel.r_offset == (bfd_vma) -1)
3450 skip = TRUE;
3451 else if (outrel.r_offset == (bfd_vma) -2)
3452 skip = TRUE, relocate = TRUE;
3453 outrel.r_offset += (input_section->output_section->vma
3454 + input_section->output_offset);
3455
3456 switch (r_type)
3457 {
07d6d2b8
AM
3458 case R_TILEGX_64_PCREL:
3459 case R_TILEGX_32_PCREL:
3460 case R_TILEGX_16_PCREL:
3461 case R_TILEGX_8_PCREL:
aa137e4d
NC
3462 /* If the symbol is not dynamic, we should not keep
3463 a dynamic relocation. But an .rela.* slot has been
3464 allocated for it, output R_TILEGX_NONE.
3465 FIXME: Add code tracking needed dynamic relocs as
3466 e.g. i386 has. */
3467 if (h->dynindx == -1)
3468 skip = TRUE, relocate = TRUE;
3469 break;
3470 }
3471
3472 if (skip)
3473 memset (&outrel, 0, sizeof outrel);
3474 /* h->dynindx may be -1 if the symbol was marked to
3475 become local. */
3476 else if (h != NULL &&
3477 h->dynindx != -1
3478 && (! is_plt
0e1862bb 3479 || !bfd_link_pic (info)
aa137e4d
NC
3480 || !SYMBOLIC_BIND (info, h)
3481 || !h->def_regular))
3482 {
3483 BFD_ASSERT (h->dynindx != -1);
3484 outrel.r_info = TILEGX_ELF_R_INFO (htab, rel, h->dynindx, r_type);
3485 outrel.r_addend = rel->r_addend;
3486 }
3487 else
3488 {
3489 if (r_type == R_TILEGX_32 || r_type == R_TILEGX_64)
3490 {
3491 outrel.r_info = TILEGX_ELF_R_INFO (htab, NULL, 0,
3492 R_TILEGX_RELATIVE);
3493 outrel.r_addend = relocation + rel->r_addend;
3494 }
3495 else
3496 {
3497 long indx;
3498
3499 outrel.r_addend = relocation + rel->r_addend;
3500
3501 if (is_plt)
3502 sec = htab->elf.splt;
3503
3504 if (bfd_is_abs_section (sec))
3505 indx = 0;
3506 else if (sec == NULL || sec->owner == NULL)
3507 {
3508 bfd_set_error (bfd_error_bad_value);
3509 return FALSE;
3510 }
3511 else
3512 {
3513 asection *osec;
3514
3515 /* We are turning this relocation into one
3516 against a section symbol. It would be
3517 proper to subtract the symbol's value,
3518 osec->vma, from the emitted reloc addend,
3519 but ld.so expects buggy relocs. */
3520 osec = sec->output_section;
3521 indx = elf_section_data (osec)->dynindx;
3522
3523 if (indx == 0)
3524 {
3525 osec = htab->elf.text_index_section;
3526 indx = elf_section_data (osec)->dynindx;
3527 }
3528
3529 /* FIXME: we really should be able to link non-pic
3530 shared libraries. */
3531 if (indx == 0)
3532 {
3533 BFD_FAIL ();
4eca0228 3534 _bfd_error_handler
871b3ab2 3535 (_("%pB: probably compiled without -fPIC?"),
aa137e4d
NC
3536 input_bfd);
3537 bfd_set_error (bfd_error_bad_value);
3538 return FALSE;
3539 }
3540 }
3541
3542 outrel.r_info = TILEGX_ELF_R_INFO (htab, rel, indx,
3543 r_type);
3544 }
3545 }
3546
3547 tilegx_elf_append_rela (output_bfd, sreloc, &outrel);
3548
3549 /* This reloc will be computed at runtime, so there's no
3550 need to do anything now. */
3551 if (! relocate)
3552 continue;
3553 }
3554 break;
3555
07d6d2b8
AM
3556 case R_TILEGX_IMM16_X0_HW0_TLS_LE:
3557 case R_TILEGX_IMM16_X1_HW0_TLS_LE:
3558 case R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE:
3559 case R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE:
3560 case R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE:
3561 case R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE:
28095894 3562 if (!bfd_link_executable (info))
6f7be959
WL
3563 {
3564 Elf_Internal_Rela outrel;
3565 bfd_boolean skip;
3566
3567 BFD_ASSERT (sreloc != NULL);
3568 skip = FALSE;
3569 outrel.r_offset =
3570 _bfd_elf_section_offset (output_bfd, info, input_section,
3571 rel->r_offset);
3572 if (outrel.r_offset == (bfd_vma) -1)
3573 skip = TRUE;
3574 else if (outrel.r_offset == (bfd_vma) -2)
3575 skip = TRUE;
3576 outrel.r_offset += (input_section->output_section->vma
3577 + input_section->output_offset);
3578 if (skip)
3579 memset (&outrel, 0, sizeof outrel);
3580 else
3581 {
3582 outrel.r_info = TILEGX_ELF_R_INFO (htab, NULL, 0, r_type);
3583 outrel.r_addend = relocation - dtpoff_base (info)
3584 + rel->r_addend;
3585 }
3586
3587 tilegx_elf_append_rela (output_bfd, sreloc, &outrel);
3588 continue;
3589 }
3590 relocation = tpoff (info, relocation);
3591 break;
3592
07d6d2b8
AM
3593 case R_TILEGX_IMM16_X0_HW0_TLS_GD:
3594 case R_TILEGX_IMM16_X1_HW0_TLS_GD:
3595 case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
3596 case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
3597 case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
3598 case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
3599 case R_TILEGX_IMM16_X0_HW0_TLS_IE:
3600 case R_TILEGX_IMM16_X1_HW0_TLS_IE:
3601 case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
3602 case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
3603 case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
3604 case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
6f7be959
WL
3605 r_type = tilegx_elf_tls_transition (info, r_type, h == NULL,
3606 input_section->sec_flg0);
07d6d2b8 3607 tls_type = GOT_UNKNOWN;
aa137e4d 3608 if (h == NULL && local_got_offsets)
6f7be959
WL
3609 tls_type =
3610 _bfd_tilegx_elf_local_got_tls_type (input_bfd) [r_symndx];
aa137e4d 3611 else if (h != NULL)
6f7be959
WL
3612 {
3613 tls_type = tilegx_elf_hash_entry(h)->tls_type;
28095894 3614 if (bfd_link_executable (info)
0e1862bb
L
3615 && h->dynindx == -1
3616 && tls_type == GOT_TLS_IE)
6f7be959
WL
3617 r_type = (!input_section->sec_flg0
3618 ? tilegx_tls_translate_to_le (r_type)
3619 : tilegx_tls_translate_to_ie (r_type));
3620 }
aa137e4d
NC
3621
3622 if (tls_type == GOT_TLS_IE)
6f7be959
WL
3623 r_type = tilegx_tls_translate_to_ie (r_type);
3624
3625 if (r_type == R_TILEGX_IMM16_X0_HW0_TLS_LE
3626 || r_type == R_TILEGX_IMM16_X1_HW0_TLS_LE
3627 || r_type == R_TILEGX_IMM16_X0_HW0_LAST_TLS_LE
3628 || r_type == R_TILEGX_IMM16_X1_HW0_LAST_TLS_LE
3629 || r_type == R_TILEGX_IMM16_X0_HW1_LAST_TLS_LE
3630 || r_type == R_TILEGX_IMM16_X1_HW1_LAST_TLS_LE)
3631 {
3632 relocation = tpoff (info, relocation);
3633 break;
3634 }
aa137e4d
NC
3635
3636 if (h != NULL)
3637 {
3638 off = h->got.offset;
3639 h->got.offset |= 1;
3640 }
3641 else
3642 {
3643 BFD_ASSERT (local_got_offsets != NULL);
3644 off = local_got_offsets[r_symndx];
3645 local_got_offsets[r_symndx] |= 1;
3646 }
3647
3648 if (htab->elf.sgot == NULL)
3649 abort ();
3650
3651 if ((off & 1) != 0)
3652 off &= ~1;
3653 else
3654 {
3655 Elf_Internal_Rela outrel;
3656 int indx = 0;
3657 bfd_boolean need_relocs = FALSE;
3658
3659 if (htab->elf.srelgot == NULL)
3660 abort ();
3661
3662 if (h != NULL)
3663 {
07d6d2b8
AM
3664 bfd_boolean dyn;
3665 dyn = htab->elf.dynamic_sections_created;
aa137e4d 3666
0e1862bb
L
3667 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
3668 bfd_link_pic (info),
3669 h)
3670 && (!bfd_link_pic (info)
aa137e4d
NC
3671 || !SYMBOL_REFERENCES_LOCAL (info, h)))
3672 {
3673 indx = h->dynindx;
3674 }
3675 }
3676
3677 /* The GOT entries have not been initialized yet. Do it
07d6d2b8 3678 now, and emit any relocations. */
0e1862bb 3679 if ((bfd_link_pic (info) || indx != 0)
aa137e4d
NC
3680 && (h == NULL
3681 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
3682 || h->root.type != bfd_link_hash_undefweak))
3683 need_relocs = TRUE;
3684
07d6d2b8
AM
3685 switch (r_type)
3686 {
aa137e4d
NC
3687 case R_TILEGX_IMM16_X0_HW0_TLS_IE:
3688 case R_TILEGX_IMM16_X1_HW0_TLS_IE:
aa137e4d
NC
3689 case R_TILEGX_IMM16_X0_HW0_LAST_TLS_IE:
3690 case R_TILEGX_IMM16_X1_HW0_LAST_TLS_IE:
3691 case R_TILEGX_IMM16_X0_HW1_LAST_TLS_IE:
3692 case R_TILEGX_IMM16_X1_HW1_LAST_TLS_IE:
aa137e4d
NC
3693 if (need_relocs) {
3694 TILEGX_ELF_PUT_WORD (htab, output_bfd, 0,
3695 htab->elf.sgot->contents + off);
07d6d2b8 3696 outrel.r_offset = (htab->elf.sgot->output_section->vma
aa137e4d 3697 + htab->elf.sgot->output_offset + off);
07d6d2b8 3698 outrel.r_addend = 0;
aa137e4d 3699 if (indx == 0)
07d6d2b8 3700 outrel.r_addend = relocation - dtpoff_base (info);
aa137e4d
NC
3701 outrel.r_info = TILEGX_ELF_R_INFO (htab, NULL, indx,
3702 TILEGX_ELF_TPOFF_RELOC (htab));
3703 tilegx_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
07d6d2b8 3704 } else {
aa137e4d
NC
3705 TILEGX_ELF_PUT_WORD (htab, output_bfd,
3706 tpoff (info, relocation),
3707 htab->elf.sgot->contents + off);
07d6d2b8
AM
3708 }
3709 break;
aa137e4d
NC
3710
3711 case R_TILEGX_IMM16_X0_HW0_TLS_GD:
3712 case R_TILEGX_IMM16_X1_HW0_TLS_GD:
aa137e4d
NC
3713 case R_TILEGX_IMM16_X0_HW0_LAST_TLS_GD:
3714 case R_TILEGX_IMM16_X1_HW0_LAST_TLS_GD:
3715 case R_TILEGX_IMM16_X0_HW1_LAST_TLS_GD:
3716 case R_TILEGX_IMM16_X1_HW1_LAST_TLS_GD:
aa137e4d 3717 if (need_relocs) {
07d6d2b8 3718 outrel.r_offset = (htab->elf.sgot->output_section->vma
aa137e4d 3719 + htab->elf.sgot->output_offset + off);
07d6d2b8
AM
3720 outrel.r_addend = 0;
3721 outrel.r_info = TILEGX_ELF_R_INFO (htab, NULL, indx,
aa137e4d
NC
3722 TILEGX_ELF_DTPMOD_RELOC (htab));
3723 TILEGX_ELF_PUT_WORD (htab, output_bfd, 0,
3724 htab->elf.sgot->contents + off);
07d6d2b8 3725 tilegx_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
aa137e4d 3726 if (indx == 0)
07d6d2b8
AM
3727 {
3728 BFD_ASSERT (! unresolved_reloc);
aa137e4d
NC
3729 TILEGX_ELF_PUT_WORD (htab, output_bfd,
3730 relocation - dtpoff_base (info),
3731 (htab->elf.sgot->contents + off +
3732 TILEGX_ELF_WORD_BYTES (htab)));
07d6d2b8 3733 }
aa137e4d 3734 else
07d6d2b8 3735 {
aa137e4d
NC
3736 TILEGX_ELF_PUT_WORD (htab, output_bfd, 0,
3737 (htab->elf.sgot->contents + off +
3738 TILEGX_ELF_WORD_BYTES (htab)));
07d6d2b8 3739 outrel.r_info = TILEGX_ELF_R_INFO (htab, NULL, indx,
aa137e4d 3740 TILEGX_ELF_DTPOFF_RELOC (htab));
07d6d2b8
AM
3741 outrel.r_offset += TILEGX_ELF_WORD_BYTES (htab);
3742 tilegx_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
3743 }
3744 }
aa137e4d
NC
3745
3746 else {
3747 /* If we are not emitting relocations for a
07d6d2b8
AM
3748 general dynamic reference, then we must be in a
3749 static link or an executable link with the
3750 symbol binding locally. Mark it as belonging
3751 to module 1, the executable. */
aa137e4d
NC
3752 TILEGX_ELF_PUT_WORD (htab, output_bfd, 1,
3753 htab->elf.sgot->contents + off );
3754 TILEGX_ELF_PUT_WORD (htab, output_bfd,
3755 relocation - dtpoff_base (info),
3756 htab->elf.sgot->contents + off +
3757 TILEGX_ELF_WORD_BYTES (htab));
3758 }
07d6d2b8
AM
3759 break;
3760 }
aa137e4d
NC
3761 }
3762
3763 if (off >= (bfd_vma) -2)
3764 abort ();
3765
535127d2 3766 relocation = off - got_base;
aa137e4d
NC
3767 unresolved_reloc = FALSE;
3768 howto = tilegx_elf_howto_table + r_type;
3769 break;
3770
3771 default:
3772 break;
3773 }
3774
3775 /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
3776 because such sections are not SEC_ALLOC and thus ld.so will
3777 not process them. */
3778 if (unresolved_reloc
3779 && !((input_section->flags & SEC_DEBUGGING) != 0
1d5316ab
AM
3780 && h->def_dynamic)
3781 && _bfd_elf_section_offset (output_bfd, info, input_section,
3782 rel->r_offset) != (bfd_vma) -1)
4eca0228 3783 _bfd_error_handler
695344c0 3784 /* xgettext:c-format */
2dcf00ce
AM
3785 (_("%pB(%pA+%#" PRIx64 "): "
3786 "unresolvable %s relocation against symbol `%s'"),
aa137e4d
NC
3787 input_bfd,
3788 input_section,
2dcf00ce 3789 (uint64_t) rel->r_offset,
aa137e4d
NC
3790 howto->name,
3791 h->root.root.string);
3792
3793 r = bfd_reloc_continue;
3794
3795 /* Get the operand creation function, if any. */
3796 create_func = reloc_to_create_func[r_type];
3797 if (create_func == NULL)
3798 {
07d6d2b8
AM
3799 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
3800 contents, rel->r_offset,
3801 relocation, rel->r_addend);
aa137e4d
NC
3802 }
3803 else
3804 {
07d6d2b8
AM
3805 if (howto->pc_relative)
3806 {
3807 relocation -=
3808 input_section->output_section->vma + input_section->output_offset;
3809 if (howto->pcrel_offset)
3810 relocation -= rel->r_offset;
3811 }
3812
3813 bfd_byte *data;
3814
3815 /* Add the relocation addend if any to the final target value */
3816 relocation += rel->r_addend;
3817
3818 /* Do basic range checking */
3819 r = bfd_check_overflow (howto->complain_on_overflow,
3820 howto->bitsize,
3821 howto->rightshift,
3822 TILEGX_ELF_WORD_BYTES (htab) * 8,
3823 relocation);
3824
3825 /*
3826 * Write the relocated value out into the raw section data.
3827 * Don't put a relocation out in the .rela section.
3828 */
3829 tilegx_bundle_bits mask = create_func(-1);
3830 tilegx_bundle_bits value = create_func(relocation >> howto->rightshift);
3831
3832 /* Only touch bytes while the mask is not 0, so we
3833 don't write to out of bounds memory if this is actually
3834 a 16-bit switch instruction. */
3835 for (data = contents + rel->r_offset; mask != 0; data++)
3836 {
3837 bfd_byte byte_mask = (bfd_byte)mask;
3838 *data = (*data & ~byte_mask) | ((bfd_byte)value & byte_mask);
3839 mask >>= 8;
3840 value >>= 8;
3841 }
aa137e4d
NC
3842 }
3843
3844 if (r != bfd_reloc_ok)
3845 {
3846 const char *msg = NULL;
3847
3848 switch (r)
3849 {
3850 case bfd_reloc_overflow:
1a72702b 3851 (*info->callbacks->reloc_overflow)
aa137e4d
NC
3852 (info, (h ? &h->root : NULL), name, howto->name,
3853 (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
3854 break;
3855
3856 case bfd_reloc_undefined:
1a72702b
AM
3857 (*info->callbacks->undefined_symbol)
3858 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
aa137e4d
NC
3859 break;
3860
3861 case bfd_reloc_outofrange:
3862 msg = _("internal error: out of range error");
3863 break;
3864
3865 case bfd_reloc_notsupported:
3866 msg = _("internal error: unsupported relocation error");
3867 break;
3868
3869 case bfd_reloc_dangerous:
3870 msg = _("internal error: dangerous relocation");
3871 break;
3872
3873 default:
3874 msg = _("internal error: unknown error");
3875 break;
3876 }
3877
3878 if (msg)
1a72702b
AM
3879 (*info->callbacks->warning) (info, msg, name, input_bfd,
3880 input_section, rel->r_offset);
aa137e4d
NC
3881 }
3882 }
3883
3884 return TRUE;
3885}
3886
3887/* Finish up dynamic symbol handling. We set the contents of various
3888 dynamic sections here. */
3889
3890bfd_boolean
3891tilegx_elf_finish_dynamic_symbol (bfd *output_bfd,
3892 struct bfd_link_info *info,
3893 struct elf_link_hash_entry *h,
3894 Elf_Internal_Sym *sym)
3895{
3896 struct tilegx_elf_link_hash_table *htab;
3897
3898 htab = tilegx_elf_hash_table (info);
3899 BFD_ASSERT (htab != NULL);
3900
3901 if (h->plt.offset != (bfd_vma) -1)
3902 {
3903 asection *splt;
3904 asection *srela;
3905 asection *sgotplt;
3906 Elf_Internal_Rela rela;
3907 bfd_byte *loc;
3908 bfd_vma r_offset;
3909 const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
3910
3911
3912 int rela_index;
3913
3914 /* This symbol has an entry in the PLT. Set it up. */
3915
3916 BFD_ASSERT (h->dynindx != -1);
3917
3918 splt = htab->elf.splt;
3919 srela = htab->elf.srelplt;
3920 sgotplt = htab->elf.sgotplt;
3921
3922 if (splt == NULL || srela == NULL)
3923 abort ();
3924
3925 /* Fill in the entry in the procedure linkage table. */
3926 rela_index = tilegx_plt_entry_build (output_bfd, htab, splt, sgotplt,
3927 h->plt.offset, &r_offset);
3928
3929 /* Fill in the entry in the global offset table, which initially points
3930 to the beginning of the plt. */
3931 TILEGX_ELF_PUT_WORD (htab, output_bfd,
3932 splt->output_section->vma + splt->output_offset,
3933 sgotplt->contents + r_offset);
3934
3935 /* Fill in the entry in the .rela.plt section. */
3936 rela.r_offset = (sgotplt->output_section->vma
3937 + sgotplt->output_offset
3938 + r_offset);
3939 rela.r_addend = 0;
3940 rela.r_info = TILEGX_ELF_R_INFO (htab, NULL, h->dynindx, R_TILEGX_JMP_SLOT);
3941
3942 loc = srela->contents + rela_index * TILEGX_ELF_RELA_BYTES (htab);
3943 bed->s->swap_reloca_out (output_bfd, &rela, loc);
3944
3945 if (!h->def_regular)
3946 {
3947 /* Mark the symbol as undefined, rather than as defined in
3948 the .plt section. Leave the value alone. */
3949 sym->st_shndx = SHN_UNDEF;
3950 /* If the symbol is weak, we do need to clear the value.
3951 Otherwise, the PLT entry would provide a definition for
3952 the symbol even if the symbol wasn't defined anywhere,
3953 and so the symbol would never be NULL. */
3954 if (!h->ref_regular_nonweak)
3955 sym->st_value = 0;
3956 }
3957 }
3958
3959 if (h->got.offset != (bfd_vma) -1
3960 && tilegx_elf_hash_entry(h)->tls_type != GOT_TLS_GD
3961 && tilegx_elf_hash_entry(h)->tls_type != GOT_TLS_IE)
3962 {
3963 asection *sgot;
3964 asection *srela;
3965 Elf_Internal_Rela rela;
3966
3967 /* This symbol has an entry in the GOT. Set it up. */
3968
3969 sgot = htab->elf.sgot;
3970 srela = htab->elf.srelgot;
3971 BFD_ASSERT (sgot != NULL && srela != NULL);
3972
3973 rela.r_offset = (sgot->output_section->vma
3974 + sgot->output_offset
3975 + (h->got.offset &~ (bfd_vma) 1));
3976
3977 /* If this is a -Bsymbolic link, and the symbol is defined
3978 locally, we just want to emit a RELATIVE reloc. Likewise if
3979 the symbol was forced to be local because of a version file.
3980 The entry in the global offset table will already have been
3981 initialized in the relocate_section function. */
0e1862bb 3982 if (bfd_link_pic (info)
aa137e4d
NC
3983 && (info->symbolic || h->dynindx == -1)
3984 && h->def_regular)
3985 {
3986 asection *sec = h->root.u.def.section;
3987 rela.r_info = TILEGX_ELF_R_INFO (htab, NULL, 0, R_TILEGX_RELATIVE);
3988 rela.r_addend = (h->root.u.def.value
3989 + sec->output_section->vma
3990 + sec->output_offset);
3991 }
3992 else
3993 {
3994 rela.r_info = TILEGX_ELF_R_INFO (htab, NULL, h->dynindx, R_TILEGX_GLOB_DAT);
3995 rela.r_addend = 0;
3996 }
3997
3998 TILEGX_ELF_PUT_WORD (htab, output_bfd, 0,
3999 sgot->contents + (h->got.offset & ~(bfd_vma) 1));
4000 tilegx_elf_append_rela (output_bfd, srela, &rela);
4001 }
4002
4003 if (h->needs_copy)
4004 {
4005 asection *s;
4006 Elf_Internal_Rela rela;
4007
4008 /* This symbols needs a copy reloc. Set it up. */
4009 BFD_ASSERT (h->dynindx != -1);
4010
afbf7e8e 4011 if (h->root.u.def.section == htab->elf.sdynrelro)
5474d94f
AM
4012 s = htab->elf.sreldynrelro;
4013 else
4014 s = htab->elf.srelbss;
aa137e4d
NC
4015 BFD_ASSERT (s != NULL);
4016
4017 rela.r_offset = (h->root.u.def.value
4018 + h->root.u.def.section->output_section->vma
4019 + h->root.u.def.section->output_offset);
4020 rela.r_info = TILEGX_ELF_R_INFO (htab, NULL, h->dynindx, R_TILEGX_COPY);
4021 rela.r_addend = 0;
4022 tilegx_elf_append_rela (output_bfd, s, &rela);
4023 }
4024
4025 /* Mark some specially defined symbols as absolute. */
9637f6ef 4026 if (h == htab->elf.hdynamic
aa137e4d
NC
4027 || (h == htab->elf.hgot || h == htab->elf.hplt))
4028 sym->st_shndx = SHN_ABS;
4029
4030 return TRUE;
4031}
4032
4033/* Finish up the dynamic sections. */
4034
4035static bfd_boolean
4036tilegx_finish_dyn (bfd *output_bfd, struct bfd_link_info *info,
4037 bfd *dynobj, asection *sdyn,
4038 asection *splt ATTRIBUTE_UNUSED)
4039{
4040 struct tilegx_elf_link_hash_table *htab;
4041 const struct elf_backend_data *bed;
4042 bfd_byte *dyncon, *dynconend;
4043 size_t dynsize;
aa137e4d
NC
4044
4045 htab = tilegx_elf_hash_table (info);
4046 BFD_ASSERT (htab != NULL);
4047 bed = get_elf_backend_data (output_bfd);
4048 dynsize = bed->s->sizeof_dyn;
4049 dynconend = sdyn->contents + sdyn->size;
aa137e4d
NC
4050
4051 for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize)
4052 {
4053 Elf_Internal_Dyn dyn;
4054 asection *s;
4055
4056 bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
4057
4058 switch (dyn.d_tag)
4059 {
4060 case DT_PLTGOT:
4061 s = htab->elf.sgotplt;
4062 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4063 break;
4064 case DT_JMPREL:
4065 s = htab->elf.srelplt;
4066 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
4067 break;
4068 case DT_PLTRELSZ:
4069 s = htab->elf.srelplt;
4070 dyn.d_un.d_val = s->size;
4071 break;
4072 default:
4073 continue;
4074 }
4075
4076 bed->s->swap_dyn_out (output_bfd, &dyn, dyncon);
4077 }
4078 return TRUE;
4079}
4080
4081bfd_boolean
4082tilegx_elf_finish_dynamic_sections (bfd *output_bfd,
4083 struct bfd_link_info *info)
4084{
4085 bfd *dynobj;
4086 asection *sdyn;
4087 struct tilegx_elf_link_hash_table *htab;
663b5850 4088 size_t pad_size;
aa137e4d
NC
4089
4090 htab = tilegx_elf_hash_table (info);
4091 BFD_ASSERT (htab != NULL);
4092 dynobj = htab->elf.dynobj;
4093
3d4d4302 4094 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
aa137e4d
NC
4095
4096 if (elf_hash_table (info)->dynamic_sections_created)
4097 {
4098 asection *splt;
4099 bfd_boolean ret;
4100
3d4d4302 4101 splt = htab->elf.splt;
aa137e4d
NC
4102 BFD_ASSERT (splt != NULL && sdyn != NULL);
4103
4104 ret = tilegx_finish_dyn (output_bfd, info, dynobj, sdyn, splt);
4105
535b785f 4106 if (!ret)
aa137e4d
NC
4107 return ret;
4108
4109 /* Fill in the head and tail entries in the procedure linkage table. */
4110 if (splt->size > 0)
4111 {
4112 memcpy (splt->contents,
4113 ABI_64_P (output_bfd) ?
4114 tilegx64_plt0_entry : tilegx32_plt0_entry,
4115 PLT_HEADER_SIZE);
4116
663b5850
WL
4117 memcpy (splt->contents + splt->size
4118 - PLT_ENTRY_SIZE + PLT_HEADER_SIZE,
aa137e4d
NC
4119 ABI_64_P (output_bfd) ?
4120 tilegx64_plt_tail_entry : tilegx32_plt_tail_entry,
4121 PLT_TAIL_SIZE);
663b5850
WL
4122 /* Add padding so that the plt section is a multiple of its
4123 entry size. */
4124 pad_size = PLT_ENTRY_SIZE - PLT_HEADER_SIZE - PLT_TAIL_SIZE;
4125 memset (splt->contents + splt->size - pad_size, 0, pad_size);
aa137e4d 4126
4c7236d3
L
4127 elf_section_data (splt->output_section)->this_hdr.sh_entsize
4128 = PLT_ENTRY_SIZE;
4129 }
aa137e4d
NC
4130 }
4131
4132 if (htab->elf.sgotplt)
4133 {
4134 if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
4135 {
4eca0228 4136 _bfd_error_handler
871b3ab2 4137 (_("discarded output section: `%pA'"), htab->elf.sgotplt);
aa137e4d
NC
4138 return FALSE;
4139 }
4140
4141 if (htab->elf.sgotplt->size > 0)
4142 {
4143 /* Write the first two entries in .got.plt, needed for the dynamic
4144 linker. */
4145 TILEGX_ELF_PUT_WORD (htab, output_bfd, (bfd_vma) -1,
4146 htab->elf.sgotplt->contents);
4147 TILEGX_ELF_PUT_WORD (htab, output_bfd, (bfd_vma) 0,
4148 htab->elf.sgotplt->contents
4149 + GOT_ENTRY_SIZE (htab));
aa137e4d 4150
4c7236d3
L
4151 elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize =
4152 GOT_ENTRY_SIZE (htab);
4153 }
aa137e4d
NC
4154 }
4155
4156 if (htab->elf.sgot)
4157 {
4158 if (htab->elf.sgot->size > 0)
4159 {
4160 /* Set the first entry in the global offset table to the address of
4161 the dynamic section. */
4162 bfd_vma val = (sdyn ?
4163 sdyn->output_section->vma + sdyn->output_offset :
4164 0);
4165 TILEGX_ELF_PUT_WORD (htab, output_bfd, val,
4166 htab->elf.sgot->contents);
aa137e4d 4167
4c7236d3
L
4168 elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize =
4169 GOT_ENTRY_SIZE (htab);
4170 }
aa137e4d
NC
4171 }
4172
4173 return TRUE;
4174}
4175
4176\f
4177
4178/* Return address for Ith PLT stub in section PLT, for relocation REL
4179 or (bfd_vma) -1 if it should not be included. */
4180
4181bfd_vma
4182tilegx_elf_plt_sym_val (bfd_vma i, const asection *plt,
4183 const arelent *rel ATTRIBUTE_UNUSED)
4184{
4185 return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE;
4186}
4187
4188enum elf_reloc_type_class
7e612e98
AM
4189tilegx_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
4190 const asection *rel_sec ATTRIBUTE_UNUSED,
4191 const Elf_Internal_Rela *rela)
aa137e4d
NC
4192{
4193 switch ((int) TILEGX_ELF_R_TYPE (rela->r_info))
4194 {
4195 case R_TILEGX_RELATIVE:
4196 return reloc_class_relative;
4197 case R_TILEGX_JMP_SLOT:
4198 return reloc_class_plt;
4199 case R_TILEGX_COPY:
4200 return reloc_class_copy;
4201 default:
4202 return reloc_class_normal;
4203 }
4204}
4205
4206int
4207tilegx_additional_program_headers (bfd *abfd,
4208 struct bfd_link_info *info ATTRIBUTE_UNUSED)
4209{
4210 /* Each .intrpt section specified by the user adds another PT_LOAD
4211 header since the sections are discontiguous. */
4212 static const char intrpt_sections[4][9] =
4213 {
4214 ".intrpt0", ".intrpt1", ".intrpt2", ".intrpt3"
4215 };
4216 int count = 0;
4217 int i;
4218
4219 for (i = 0; i < 4; i++)
4220 {
4221 asection *sec = bfd_get_section_by_name (abfd, intrpt_sections[i]);
4222 if (sec != NULL && (sec->flags & SEC_LOAD) != 0)
4223 ++count;
4224 }
4225
4226 /* Add four "padding" headers in to leave room in case a custom linker
4227 script does something fancy. Otherwise ld complains that it ran
4228 out of program headers and refuses to link. */
4229 count += 4;
4230
4231 return count;
4232}
4233
4234
4235bfd_boolean
50e03d47 4236_bfd_tilegx_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
aa137e4d 4237{
50e03d47 4238 bfd *obfd = info->output_bfd;
aa137e4d
NC
4239 const char *targ1 = bfd_get_target (ibfd);
4240 const char *targ2 = bfd_get_target (obfd);
4241
4242 if (strcmp (targ1, targ2) != 0)
4243 {
4eca0228 4244 _bfd_error_handler
695344c0 4245 /* xgettext:c-format */
38f14ab8 4246 (_("%pB: cannot link together %s and %s objects"),
aa137e4d
NC
4247 ibfd, targ1, targ2);
4248 bfd_set_error (bfd_error_bad_value);
4249 return FALSE;
4250 }
4251
4252 return TRUE;
4253}
This page took 0.741488 seconds and 4 git commands to generate.