Coverage Report

Created: 2023-08-28 06:28

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