Coverage Report

Created: 2025-06-24 06:45

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