Coverage Report

Created: 2026-09-14 08:07

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