-Wimplicit-fallthrough noreturn fixes
[deliverable/binutils-gdb.git] / bfd / elf32-microblaze.c
CommitLineData
7ba29e2a
NC
1/* Xilinx MicroBlaze-specific support for 32-bit ELF
2
6f2750fe 3 Copyright (C) 2009-2016 Free Software Foundation, Inc.
7ba29e2a
NC
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 Boston, MA 02110-1301, USA. */
21
22
23int dbg = 0;
24
7ba29e2a 25#include "sysdep.h"
691bf19c 26#include "bfd.h"
7ba29e2a
NC
27#include "bfdlink.h"
28#include "libbfd.h"
29#include "elf-bfd.h"
30#include "elf/microblaze.h"
31#include <assert.h>
32
33#define USE_RELA /* Only USE_REL is actually significant, but this is
34 here are a reminder... */
35#define INST_WORD_SIZE 4
36
37static int ro_small_data_pointer = 0;
38static int rw_small_data_pointer = 0;
39
40static reloc_howto_type * microblaze_elf_howto_table [(int) R_MICROBLAZE_max];
41
42static reloc_howto_type microblaze_elf_howto_raw[] =
43{
44 /* This reloc does nothing. */
45 HOWTO (R_MICROBLAZE_NONE, /* Type. */
46 0, /* Rightshift. */
6346d5ca
AM
47 3, /* Size (0 = byte, 1 = short, 2 = long). */
48 0, /* Bitsize. */
7ba29e2a
NC
49 FALSE, /* PC_relative. */
50 0, /* Bitpos. */
6346d5ca 51 complain_overflow_dont, /* Complain on overflow. */
7ba29e2a
NC
52 NULL, /* Special Function. */
53 "R_MICROBLAZE_NONE", /* Name. */
54 FALSE, /* Partial Inplace. */
55 0, /* Source Mask. */
56 0, /* Dest Mask. */
57 FALSE), /* PC relative offset? */
58
59 /* A standard 32 bit relocation. */
60 HOWTO (R_MICROBLAZE_32, /* Type. */
61 0, /* Rightshift. */
62 2, /* Size (0 = byte, 1 = short, 2 = long). */
63 32, /* Bitsize. */
64 FALSE, /* PC_relative. */
65 0, /* Bitpos. */
66 complain_overflow_bitfield, /* Complain on overflow. */
67 bfd_elf_generic_reloc,/* Special Function. */
68 "R_MICROBLAZE_32", /* Name. */
69 FALSE, /* Partial Inplace. */
70 0, /* Source Mask. */
71 0xffffffff, /* Dest Mask. */
72 FALSE), /* PC relative offset? */
73
74 /* A standard PCREL 32 bit relocation. */
75 HOWTO (R_MICROBLAZE_32_PCREL,/* Type. */
76 0, /* Rightshift. */
77 2, /* Size (0 = byte, 1 = short, 2 = long). */
78 32, /* Bitsize. */
79 TRUE, /* PC_relative. */
80 0, /* Bitpos. */
81 complain_overflow_bitfield, /* Complain on overflow. */
82 bfd_elf_generic_reloc,/* Special Function. */
83 "R_MICROBLAZE_32_PCREL", /* Name. */
84 TRUE, /* Partial Inplace. */
85 0, /* Source Mask. */
86 0xffffffff, /* Dest Mask. */
87 TRUE), /* PC relative offset? */
88
89 /* A 64 bit PCREL relocation. Table-entry not really used. */
90 HOWTO (R_MICROBLAZE_64_PCREL,/* Type. */
91 0, /* Rightshift. */
92 2, /* Size (0 = byte, 1 = short, 2 = long). */
93 16, /* Bitsize. */
94 TRUE, /* PC_relative. */
95 0, /* Bitpos. */
96 complain_overflow_dont, /* Complain on overflow. */
97 bfd_elf_generic_reloc,/* Special Function. */
98 "R_MICROBLAZE_64_PCREL", /* Name. */
99 FALSE, /* Partial Inplace. */
100 0, /* Source Mask. */
101 0x0000ffff, /* Dest Mask. */
102 TRUE), /* PC relative offset? */
103
104 /* The low half of a PCREL 32 bit relocation. */
105 HOWTO (R_MICROBLAZE_32_PCREL_LO, /* Type. */
106 0, /* Rightshift. */
107 2, /* Size (0 = byte, 1 = short, 2 = long). */
108 16, /* Bitsize. */
109 TRUE, /* PC_relative. */
110 0, /* Bitpos. */
111 complain_overflow_signed, /* Complain on overflow. */
112 bfd_elf_generic_reloc, /* Special Function. */
113 "R_MICROBLAZE_32_PCREL_LO", /* Name. */
114 FALSE, /* Partial Inplace. */
115 0, /* Source Mask. */
116 0x0000ffff, /* Dest Mask. */
117 TRUE), /* PC relative offset? */
118
119 /* A 64 bit relocation. Table entry not really used. */
120 HOWTO (R_MICROBLAZE_64, /* Type. */
121 0, /* Rightshift. */
122 2, /* Size (0 = byte, 1 = short, 2 = long). */
123 16, /* Bitsize. */
124 FALSE, /* PC_relative. */
125 0, /* Bitpos. */
126 complain_overflow_dont, /* Complain on overflow. */
127 bfd_elf_generic_reloc,/* Special Function. */
128 "R_MICROBLAZE_64", /* Name. */
129 FALSE, /* Partial Inplace. */
130 0, /* Source Mask. */
131 0x0000ffff, /* Dest Mask. */
132 FALSE), /* PC relative offset? */
133
134 /* The low half of a 32 bit relocation. */
135 HOWTO (R_MICROBLAZE_32_LO, /* Type. */
136 0, /* Rightshift. */
137 2, /* Size (0 = byte, 1 = short, 2 = long). */
138 16, /* Bitsize. */
139 FALSE, /* PC_relative. */
140 0, /* Bitpos. */
141 complain_overflow_signed, /* Complain on overflow. */
142 bfd_elf_generic_reloc,/* Special Function. */
143 "R_MICROBLAZE_32_LO", /* Name. */
144 FALSE, /* Partial Inplace. */
145 0, /* Source Mask. */
146 0x0000ffff, /* Dest Mask. */
147 FALSE), /* PC relative offset? */
148
149 /* Read-only small data section relocation. */
150 HOWTO (R_MICROBLAZE_SRO32, /* Type. */
151 0, /* Rightshift. */
152 2, /* Size (0 = byte, 1 = short, 2 = long). */
153 16, /* Bitsize. */
154 FALSE, /* PC_relative. */
155 0, /* Bitpos. */
156 complain_overflow_bitfield, /* Complain on overflow. */
157 bfd_elf_generic_reloc,/* Special Function. */
158 "R_MICROBLAZE_SRO32", /* Name. */
159 FALSE, /* Partial Inplace. */
160 0, /* Source Mask. */
161 0x0000ffff, /* Dest Mask. */
162 FALSE), /* PC relative offset? */
163
164 /* Read-write small data area relocation. */
165 HOWTO (R_MICROBLAZE_SRW32, /* Type. */
166 0, /* Rightshift. */
167 2, /* Size (0 = byte, 1 = short, 2 = long). */
168 16, /* Bitsize. */
169 FALSE, /* PC_relative. */
170 0, /* Bitpos. */
171 complain_overflow_bitfield, /* Complain on overflow. */
172 bfd_elf_generic_reloc,/* Special Function. */
173 "R_MICROBLAZE_SRW32", /* Name. */
174 FALSE, /* Partial Inplace. */
175 0, /* Source Mask. */
176 0x0000ffff, /* Dest Mask. */
177 FALSE), /* PC relative offset? */
178
179 /* This reloc does nothing. Used for relaxation. */
180 HOWTO (R_MICROBLAZE_64_NONE, /* Type. */
181 0, /* Rightshift. */
6346d5ca
AM
182 3, /* Size (0 = byte, 1 = short, 2 = long). */
183 0, /* Bitsize. */
7ba29e2a
NC
184 TRUE, /* PC_relative. */
185 0, /* Bitpos. */
6346d5ca 186 complain_overflow_dont, /* Complain on overflow. */
7ba29e2a
NC
187 NULL, /* Special Function. */
188 "R_MICROBLAZE_64_NONE",/* Name. */
189 FALSE, /* Partial Inplace. */
190 0, /* Source Mask. */
191 0, /* Dest Mask. */
192 FALSE), /* PC relative offset? */
193
194 /* Symbol Op Symbol relocation. */
195 HOWTO (R_MICROBLAZE_32_SYM_OP_SYM, /* Type. */
196 0, /* Rightshift. */
197 2, /* Size (0 = byte, 1 = short, 2 = long). */
198 32, /* Bitsize. */
199 FALSE, /* PC_relative. */
200 0, /* Bitpos. */
201 complain_overflow_bitfield, /* Complain on overflow. */
202 bfd_elf_generic_reloc,/* Special Function. */
203 "R_MICROBLAZE_32_SYM_OP_SYM", /* Name. */
204 FALSE, /* Partial Inplace. */
205 0, /* Source Mask. */
206 0xffffffff, /* Dest Mask. */
207 FALSE), /* PC relative offset? */
208
209 /* GNU extension to record C++ vtable hierarchy. */
210 HOWTO (R_MICROBLAZE_GNU_VTINHERIT, /* Type. */
211 0, /* Rightshift. */
212 2, /* Size (0 = byte, 1 = short, 2 = long). */
213 0, /* Bitsize. */
214 FALSE, /* PC_relative. */
215 0, /* Bitpos. */
216 complain_overflow_dont,/* Complain on overflow. */
217 NULL, /* Special Function. */
218 "R_MICROBLAZE_GNU_VTINHERIT", /* Name. */
219 FALSE, /* Partial Inplace. */
220 0, /* Source Mask. */
221 0, /* Dest Mask. */
222 FALSE), /* PC relative offset? */
223
224 /* GNU extension to record C++ vtable member usage. */
225 HOWTO (R_MICROBLAZE_GNU_VTENTRY, /* Type. */
226 0, /* Rightshift. */
227 2, /* Size (0 = byte, 1 = short, 2 = long). */
228 0, /* Bitsize. */
229 FALSE, /* PC_relative. */
230 0, /* Bitpos. */
231 complain_overflow_dont,/* Complain on overflow. */
232 _bfd_elf_rel_vtable_reloc_fn, /* Special Function. */
233 "R_MICROBLAZE_GNU_VTENTRY", /* Name. */
234 FALSE, /* Partial Inplace. */
235 0, /* Source Mask. */
236 0, /* Dest Mask. */
237 FALSE), /* PC relative offset? */
238
239 /* A 64 bit GOTPC relocation. Table-entry not really used. */
240 HOWTO (R_MICROBLAZE_GOTPC_64, /* Type. */
241 0, /* Rightshift. */
242 2, /* Size (0 = byte, 1 = short, 2 = long). */
243 16, /* Bitsize. */
244 TRUE, /* PC_relative. */
245 0, /* Bitpos. */
246 complain_overflow_dont, /* Complain on overflow. */
247 bfd_elf_generic_reloc, /* Special Function. */
248 "R_MICROBLAZE_GOTPC_64", /* Name. */
249 FALSE, /* Partial Inplace. */
250 0, /* Source Mask. */
251 0x0000ffff, /* Dest Mask. */
252 TRUE), /* PC relative offset? */
253
254 /* A 64 bit GOT relocation. Table-entry not really used. */
255 HOWTO (R_MICROBLAZE_GOT_64, /* Type. */
256 0, /* Rightshift. */
257 2, /* Size (0 = byte, 1 = short, 2 = long). */
258 16, /* Bitsize. */
259 FALSE, /* PC_relative. */
260 0, /* Bitpos. */
261 complain_overflow_dont, /* Complain on overflow. */
262 bfd_elf_generic_reloc,/* Special Function. */
263 "R_MICROBLAZE_GOT_64",/* Name. */
264 FALSE, /* Partial Inplace. */
265 0, /* Source Mask. */
266 0x0000ffff, /* Dest Mask. */
267 FALSE), /* PC relative offset? */
268
269 /* A 64 bit PLT relocation. Table-entry not really used. */
270 HOWTO (R_MICROBLAZE_PLT_64, /* Type. */
271 0, /* Rightshift. */
272 2, /* Size (0 = byte, 1 = short, 2 = long). */
273 16, /* Bitsize. */
274 TRUE, /* PC_relative. */
275 0, /* Bitpos. */
276 complain_overflow_dont, /* Complain on overflow. */
277 bfd_elf_generic_reloc,/* Special Function. */
278 "R_MICROBLAZE_PLT_64",/* Name. */
279 FALSE, /* Partial Inplace. */
280 0, /* Source Mask. */
281 0x0000ffff, /* Dest Mask. */
282 TRUE), /* PC relative offset? */
283
284 /* Table-entry not really used. */
285 HOWTO (R_MICROBLAZE_REL, /* Type. */
286 0, /* Rightshift. */
287 2, /* Size (0 = byte, 1 = short, 2 = long). */
288 16, /* Bitsize. */
289 TRUE, /* PC_relative. */
290 0, /* Bitpos. */
291 complain_overflow_dont, /* Complain on overflow. */
292 bfd_elf_generic_reloc,/* Special Function. */
293 "R_MICROBLAZE_REL", /* Name. */
294 FALSE, /* Partial Inplace. */
295 0, /* Source Mask. */
296 0x0000ffff, /* Dest Mask. */
297 TRUE), /* PC relative offset? */
298
299 /* Table-entry not really used. */
300 HOWTO (R_MICROBLAZE_JUMP_SLOT,/* Type. */
301 0, /* Rightshift. */
302 2, /* Size (0 = byte, 1 = short, 2 = long). */
303 16, /* Bitsize. */
304 TRUE, /* PC_relative. */
305 0, /* Bitpos. */
306 complain_overflow_dont, /* Complain on overflow. */
307 bfd_elf_generic_reloc,/* Special Function. */
308 "R_MICROBLAZE_JUMP_SLOT", /* Name. */
309 FALSE, /* Partial Inplace. */
310 0, /* Source Mask. */
311 0x0000ffff, /* Dest Mask. */
312 TRUE), /* PC relative offset? */
313
314 /* Table-entry not really used. */
315 HOWTO (R_MICROBLAZE_GLOB_DAT,/* Type. */
316 0, /* Rightshift. */
317 2, /* Size (0 = byte, 1 = short, 2 = long). */
318 16, /* Bitsize. */
319 TRUE, /* PC_relative. */
320 0, /* Bitpos. */
321 complain_overflow_dont, /* Complain on overflow. */
322 bfd_elf_generic_reloc,/* Special Function. */
323 "R_MICROBLAZE_GLOB_DAT", /* Name. */
324 FALSE, /* Partial Inplace. */
325 0, /* Source Mask. */
326 0x0000ffff, /* Dest Mask. */
327 TRUE), /* PC relative offset? */
328
329 /* A 64 bit GOT relative relocation. Table-entry not really used. */
330 HOWTO (R_MICROBLAZE_GOTOFF_64, /* Type. */
331 0, /* Rightshift. */
332 2, /* Size (0 = byte, 1 = short, 2 = long). */
333 16, /* Bitsize. */
334 FALSE, /* PC_relative. */
335 0, /* Bitpos. */
336 complain_overflow_dont, /* Complain on overflow. */
337 bfd_elf_generic_reloc,/* Special Function. */
338 "R_MICROBLAZE_GOTOFF_64", /* Name. */
339 FALSE, /* Partial Inplace. */
340 0, /* Source Mask. */
341 0x0000ffff, /* Dest Mask. */
342 FALSE), /* PC relative offset? */
343
344 /* A 32 bit GOT relative relocation. Table-entry not really used. */
345 HOWTO (R_MICROBLAZE_GOTOFF_32, /* Type. */
346 0, /* Rightshift. */
347 2, /* Size (0 = byte, 1 = short, 2 = long). */
348 16, /* Bitsize. */
349 FALSE, /* PC_relative. */
350 0, /* Bitpos. */
351 complain_overflow_dont, /* Complain on overflow. */
352 bfd_elf_generic_reloc, /* Special Function. */
353 "R_MICROBLAZE_GOTOFF_32", /* Name. */
354 FALSE, /* Partial Inplace. */
355 0, /* Source Mask. */
356 0x0000ffff, /* Dest Mask. */
357 FALSE), /* PC relative offset? */
358
359 /* COPY relocation. Table-entry not really used. */
360 HOWTO (R_MICROBLAZE_COPY, /* Type. */
361 0, /* Rightshift. */
362 2, /* Size (0 = byte, 1 = short, 2 = long). */
363 16, /* Bitsize. */
364 FALSE, /* PC_relative. */
365 0, /* Bitpos. */
366 complain_overflow_dont, /* Complain on overflow. */
367 bfd_elf_generic_reloc,/* Special Function. */
368 "R_MICROBLAZE_COPY", /* Name. */
369 FALSE, /* Partial Inplace. */
370 0, /* Source Mask. */
371 0x0000ffff, /* Dest Mask. */
372 FALSE), /* PC relative offset? */
69b06cc8
ME
373
374 /* Marker relocs for TLS. */
375 HOWTO (R_MICROBLAZE_TLS,
376 0, /* rightshift */
377 2, /* size (0 = byte, 1 = short, 2 = long) */
378 32, /* bitsize */
379 FALSE, /* pc_relative */
380 0, /* bitpos */
381 complain_overflow_dont, /* complain_on_overflow */
382 bfd_elf_generic_reloc, /* special_function */
383 "R_MICROBLAZE_TLS", /* name */
384 FALSE, /* partial_inplace */
385 0, /* src_mask */
386 0x0000ffff, /* dst_mask */
387 FALSE), /* pcrel_offset */
388
389 HOWTO (R_MICROBLAZE_TLSGD,
390 0, /* rightshift */
391 2, /* size (0 = byte, 1 = short, 2 = long) */
392 32, /* bitsize */
393 FALSE, /* pc_relative */
394 0, /* bitpos */
395 complain_overflow_dont, /* complain_on_overflow */
396 bfd_elf_generic_reloc, /* special_function */
397 "R_MICROBLAZE_TLSGD", /* name */
398 FALSE, /* partial_inplace */
399 0, /* src_mask */
400 0x0000ffff, /* dst_mask */
401 FALSE), /* pcrel_offset */
402
403 HOWTO (R_MICROBLAZE_TLSLD,
404 0, /* rightshift */
405 2, /* size (0 = byte, 1 = short, 2 = long) */
406 32, /* bitsize */
407 FALSE, /* pc_relative */
408 0, /* bitpos */
409 complain_overflow_dont, /* complain_on_overflow */
410 bfd_elf_generic_reloc, /* special_function */
411 "R_MICROBLAZE_TLSLD", /* name */
412 FALSE, /* partial_inplace */
413 0, /* src_mask */
414 0x0000ffff, /* dst_mask */
415 FALSE), /* pcrel_offset */
416
417 /* Computes the load module index of the load module that contains the
418 definition of its TLS sym. */
419 HOWTO (R_MICROBLAZE_TLSDTPMOD32,
420 0, /* rightshift */
421 2, /* size (0 = byte, 1 = short, 2 = long) */
422 32, /* bitsize */
423 FALSE, /* pc_relative */
424 0, /* bitpos */
425 complain_overflow_dont, /* complain_on_overflow */
426 bfd_elf_generic_reloc, /* special_function */
427 "R_MICROBLAZE_TLSDTPMOD32", /* name */
428 FALSE, /* partial_inplace */
429 0, /* src_mask */
430 0x0000ffff, /* dst_mask */
431 FALSE), /* pcrel_offset */
432
433 /* Computes a dtv-relative displacement, the difference between the value
434 of sym+add and the base address of the thread-local storage block that
435 contains the definition of sym, minus 0x8000. Used for initializing GOT */
436 HOWTO (R_MICROBLAZE_TLSDTPREL32,
437 0, /* rightshift */
438 2, /* size (0 = byte, 1 = short, 2 = long) */
439 32, /* bitsize */
440 FALSE, /* pc_relative */
441 0, /* bitpos */
442 complain_overflow_dont, /* complain_on_overflow */
443 bfd_elf_generic_reloc, /* special_function */
444 "R_MICROBLAZE_TLSDTPREL32", /* name */
445 FALSE, /* partial_inplace */
446 0, /* src_mask */
447 0x0000ffff, /* dst_mask */
448 FALSE), /* pcrel_offset */
449
450 /* Computes a dtv-relative displacement, the difference between the value
451 of sym+add and the base address of the thread-local storage block that
452 contains the definition of sym, minus 0x8000. */
453 HOWTO (R_MICROBLAZE_TLSDTPREL64,
454 0, /* rightshift */
455 2, /* size (0 = byte, 1 = short, 2 = long) */
456 32, /* bitsize */
457 FALSE, /* pc_relative */
458 0, /* bitpos */
459 complain_overflow_dont, /* complain_on_overflow */
460 bfd_elf_generic_reloc, /* special_function */
461 "R_MICROBLAZE_TLSDTPREL64", /* name */
462 FALSE, /* partial_inplace */
463 0, /* src_mask */
464 0x0000ffff, /* dst_mask */
465 FALSE), /* pcrel_offset */
466
467 /* Computes a tp-relative displacement, the difference between the value of
468 sym+add and the value of the thread pointer (r13). */
469 HOWTO (R_MICROBLAZE_TLSGOTTPREL32,
470 0, /* rightshift */
471 2, /* size (0 = byte, 1 = short, 2 = long) */
472 32, /* bitsize */
473 FALSE, /* pc_relative */
474 0, /* bitpos */
475 complain_overflow_dont, /* complain_on_overflow */
476 bfd_elf_generic_reloc, /* special_function */
477 "R_MICROBLAZE_TLSGOTTPREL32", /* name */
478 FALSE, /* partial_inplace */
479 0, /* src_mask */
480 0x0000ffff, /* dst_mask */
481 FALSE), /* pcrel_offset */
482
483 /* Computes a tp-relative displacement, the difference between the value of
484 sym+add and the value of the thread pointer (r13). */
485 HOWTO (R_MICROBLAZE_TLSTPREL32,
486 0, /* rightshift */
487 2, /* size (0 = byte, 1 = short, 2 = long) */
488 32, /* bitsize */
489 FALSE, /* pc_relative */
490 0, /* bitpos */
491 complain_overflow_dont, /* complain_on_overflow */
492 bfd_elf_generic_reloc, /* special_function */
493 "R_MICROBLAZE_TLSTPREL32", /* name */
494 FALSE, /* partial_inplace */
495 0, /* src_mask */
496 0x0000ffff, /* dst_mask */
497 FALSE), /* pcrel_offset */
498
7ba29e2a
NC
499};
500
501#ifndef NUM_ELEM
502#define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
503#endif
504\f
505/* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */
506
507static void
508microblaze_elf_howto_init (void)
509{
510 unsigned int i;
511
512 for (i = NUM_ELEM (microblaze_elf_howto_raw); i--;)
513 {
514 unsigned int type;
515
516 type = microblaze_elf_howto_raw[i].type;
517
518 BFD_ASSERT (type < NUM_ELEM (microblaze_elf_howto_table));
519
520 microblaze_elf_howto_table [type] = & microblaze_elf_howto_raw [i];
521 }
522}
523\f
524static reloc_howto_type *
525microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
526 bfd_reloc_code_real_type code)
527{
528 enum elf_microblaze_reloc_type microblaze_reloc = R_MICROBLAZE_NONE;
529
530 switch (code)
531 {
532 case BFD_RELOC_NONE:
533 microblaze_reloc = R_MICROBLAZE_NONE;
534 break;
535 case BFD_RELOC_MICROBLAZE_64_NONE:
536 microblaze_reloc = R_MICROBLAZE_64_NONE;
537 break;
538 case BFD_RELOC_32:
539 microblaze_reloc = R_MICROBLAZE_32;
540 break;
541 /* RVA is treated the same as 32 */
542 case BFD_RELOC_RVA:
543 microblaze_reloc = R_MICROBLAZE_32;
544 break;
545 case BFD_RELOC_32_PCREL:
546 microblaze_reloc = R_MICROBLAZE_32_PCREL;
547 break;
548 case BFD_RELOC_64_PCREL:
549 microblaze_reloc = R_MICROBLAZE_64_PCREL;
550 break;
551 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
552 microblaze_reloc = R_MICROBLAZE_32_PCREL_LO;
553 break;
554 case BFD_RELOC_64:
555 microblaze_reloc = R_MICROBLAZE_64;
556 break;
557 case BFD_RELOC_MICROBLAZE_32_LO:
558 microblaze_reloc = R_MICROBLAZE_32_LO;
559 break;
560 case BFD_RELOC_MICROBLAZE_32_ROSDA:
561 microblaze_reloc = R_MICROBLAZE_SRO32;
562 break;
563 case BFD_RELOC_MICROBLAZE_32_RWSDA:
564 microblaze_reloc = R_MICROBLAZE_SRW32;
565 break;
566 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
567 microblaze_reloc = R_MICROBLAZE_32_SYM_OP_SYM;
568 break;
569 case BFD_RELOC_VTABLE_INHERIT:
570 microblaze_reloc = R_MICROBLAZE_GNU_VTINHERIT;
571 break;
572 case BFD_RELOC_VTABLE_ENTRY:
573 microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
574 break;
575 case BFD_RELOC_MICROBLAZE_64_GOTPC:
576 microblaze_reloc = R_MICROBLAZE_GOTPC_64;
577 break;
578 case BFD_RELOC_MICROBLAZE_64_GOT:
579 microblaze_reloc = R_MICROBLAZE_GOT_64;
580 break;
581 case BFD_RELOC_MICROBLAZE_64_PLT:
582 microblaze_reloc = R_MICROBLAZE_PLT_64;
583 break;
584 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
585 microblaze_reloc = R_MICROBLAZE_GOTOFF_64;
586 break;
587 case BFD_RELOC_MICROBLAZE_32_GOTOFF:
588 microblaze_reloc = R_MICROBLAZE_GOTOFF_32;
589 break;
69b06cc8
ME
590 case BFD_RELOC_MICROBLAZE_64_TLSGD:
591 microblaze_reloc = R_MICROBLAZE_TLSGD;
592 break;
593 case BFD_RELOC_MICROBLAZE_64_TLSLD:
594 microblaze_reloc = R_MICROBLAZE_TLSLD;
595 break;
596 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
597 microblaze_reloc = R_MICROBLAZE_TLSDTPREL32;
598 break;
599 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
600 microblaze_reloc = R_MICROBLAZE_TLSDTPREL64;
601 break;
602 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
603 microblaze_reloc = R_MICROBLAZE_TLSDTPMOD32;
604 break;
605 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
606 microblaze_reloc = R_MICROBLAZE_TLSGOTTPREL32;
607 break;
608 case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
609 microblaze_reloc = R_MICROBLAZE_TLSTPREL32;
610 break;
7ba29e2a
NC
611 case BFD_RELOC_MICROBLAZE_COPY:
612 microblaze_reloc = R_MICROBLAZE_COPY;
613 break;
614 default:
615 return (reloc_howto_type *) NULL;
616 }
617
618 if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
619 /* Initialize howto table if needed. */
620 microblaze_elf_howto_init ();
621
622 return microblaze_elf_howto_table [(int) microblaze_reloc];
623};
624
625static reloc_howto_type *
626microblaze_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
627 const char *r_name)
628{
629 unsigned int i;
630
631 for (i = 0; i < NUM_ELEM (microblaze_elf_howto_raw); i++)
632 if (microblaze_elf_howto_raw[i].name != NULL
633 && strcasecmp (microblaze_elf_howto_raw[i].name, r_name) == 0)
634 return &microblaze_elf_howto_raw[i];
635
636 return NULL;
637}
638
639/* Set the howto pointer for a RCE ELF reloc. */
640
641static void
642microblaze_elf_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
643 arelent * cache_ptr,
644 Elf_Internal_Rela * dst)
645{
cd21f5da
NC
646 unsigned int r_type;
647
7ba29e2a
NC
648 if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
649 /* Initialize howto table if needed. */
650 microblaze_elf_howto_init ();
651
cd21f5da
NC
652 r_type = ELF32_R_TYPE (dst->r_info);
653 if (r_type >= R_MICROBLAZE_max)
654 {
4eca0228
AM
655 _bfd_error_handler (_("%B: unrecognised MicroBlaze reloc number: %d"),
656 abfd, r_type);
cd21f5da
NC
657 bfd_set_error (bfd_error_bad_value);
658 r_type = R_MICROBLAZE_NONE;
659 }
7ba29e2a 660
cd21f5da 661 cache_ptr->howto = microblaze_elf_howto_table [r_type];
7ba29e2a
NC
662}
663
664/* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
665
666static bfd_boolean
667microblaze_elf_is_local_label_name (bfd *abfd, const char *name)
668{
669 if (name[0] == 'L' && name[1] == '.')
670 return TRUE;
671
672 if (name[0] == '$' && name[1] == 'L')
673 return TRUE;
674
675 /* With gcc, the labels go back to starting with '.', so we accept
676 the generic ELF local label syntax as well. */
677 return _bfd_elf_is_local_label_name (abfd, name);
678}
679
680/* The microblaze linker (like many others) needs to keep track of
681 the number of relocs that it decides to copy as dynamic relocs in
682 check_relocs for each symbol. This is so that it can later discard
683 them if they are found to be unnecessary. We store the information
684 in a field extending the regular ELF linker hash table. */
685
686struct elf32_mb_dyn_relocs
687{
688 struct elf32_mb_dyn_relocs *next;
689
690 /* The input section of the reloc. */
691 asection *sec;
692
693 /* Total number of relocs copied for the input section. */
694 bfd_size_type count;
695
696 /* Number of pc-relative relocs copied for the input section. */
697 bfd_size_type pc_count;
698};
699
700/* ELF linker hash entry. */
701
702struct elf32_mb_link_hash_entry
703{
704 struct elf_link_hash_entry elf;
705
706 /* Track dynamic relocs copied for this symbol. */
707 struct elf32_mb_dyn_relocs *dyn_relocs;
708
69b06cc8
ME
709 /* TLS Reference Types for the symbol; Updated by check_relocs */
710#define TLS_GD 1 /* GD reloc. */
711#define TLS_LD 2 /* LD reloc. */
712#define TLS_TPREL 4 /* TPREL reloc, => IE. */
713#define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
714#define TLS_TLS 16 /* Any TLS reloc. */
715 unsigned char tls_mask;
716
7ba29e2a
NC
717};
718
69b06cc8
ME
719#define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD))
720#define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD))
721#define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL))
722#define IS_TLS_NONE(x) (x == 0)
723
7ba29e2a
NC
724#define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent))
725
726/* ELF linker hash table. */
727
728struct elf32_mb_link_hash_table
729{
730 struct elf_link_hash_table elf;
731
732 /* Short-cuts to get to dynamic linker sections. */
733 asection *sgot;
734 asection *sgotplt;
735 asection *srelgot;
736 asection *splt;
737 asection *srelplt;
738 asection *sdynbss;
739 asection *srelbss;
740
741 /* Small local sym to section mapping cache. */
742 struct sym_cache sym_sec;
69b06cc8
ME
743
744 /* TLS Local Dynamic GOT Entry */
745 union {
746 bfd_signed_vma refcount;
747 bfd_vma offset;
748 } tlsld_got;
7ba29e2a
NC
749};
750
69b06cc8
ME
751/* Nonzero if this section has TLS related relocations. */
752#define has_tls_reloc sec_flg0
753
7ba29e2a
NC
754/* Get the ELF linker hash table from a link_info structure. */
755
756#define elf32_mb_hash_table(p) \
4dfe6ac6
NC
757 (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
758 == MICROBLAZE_ELF_DATA ? ((struct elf32_mb_link_hash_table *) ((p)->hash)) : NULL)
7ba29e2a
NC
759
760/* Create an entry in a microblaze ELF linker hash table. */
761
762static struct bfd_hash_entry *
763link_hash_newfunc (struct bfd_hash_entry *entry,
764 struct bfd_hash_table *table,
765 const char *string)
766{
767 /* Allocate the structure if it has not already been allocated by a
768 subclass. */
769 if (entry == NULL)
770 {
771 entry = bfd_hash_allocate (table,
772 sizeof (struct elf32_mb_link_hash_entry));
773 if (entry == NULL)
774 return entry;
775 }
776
777 /* Call the allocation method of the superclass. */
778 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
779 if (entry != NULL)
780 {
781 struct elf32_mb_link_hash_entry *eh;
782
783 eh = (struct elf32_mb_link_hash_entry *) entry;
784 eh->dyn_relocs = NULL;
69b06cc8 785 eh->tls_mask = 0;
7ba29e2a
NC
786 }
787
788 return entry;
789}
790
791/* Create a mb ELF linker hash table. */
792
793static struct bfd_link_hash_table *
794microblaze_elf_link_hash_table_create (bfd *abfd)
795{
796 struct elf32_mb_link_hash_table *ret;
797 bfd_size_type amt = sizeof (struct elf32_mb_link_hash_table);
798
799 ret = (struct elf32_mb_link_hash_table *) bfd_zmalloc (amt);
800 if (ret == NULL)
801 return NULL;
802
803 if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
4dfe6ac6
NC
804 sizeof (struct elf32_mb_link_hash_entry),
805 MICROBLAZE_ELF_DATA))
7ba29e2a
NC
806 {
807 free (ret);
808 return NULL;
809 }
810
811 return &ret->elf.root;
812}
813\f
814/* Set the values of the small data pointers. */
815
816static void
817microblaze_elf_final_sdp (struct bfd_link_info *info)
818{
819 struct bfd_link_hash_entry *h;
820
821 h = bfd_link_hash_lookup (info->hash, RO_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE);
822 if (h != (struct bfd_link_hash_entry *) NULL
823 && h->type == bfd_link_hash_defined)
824 ro_small_data_pointer = (h->u.def.value
825 + h->u.def.section->output_section->vma
826 + h->u.def.section->output_offset);
827
828 h = bfd_link_hash_lookup (info->hash, RW_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE);
829 if (h != (struct bfd_link_hash_entry *) NULL
830 && h->type == bfd_link_hash_defined)
831 rw_small_data_pointer = (h->u.def.value
832 + h->u.def.section->output_section->vma
833 + h->u.def.section->output_offset);
834}
835
69b06cc8
ME
836static bfd_vma
837dtprel_base (struct bfd_link_info *info)
838{
839 /* If tls_sec is NULL, we should have signalled an error already. */
840 if (elf_hash_table (info)->tls_sec == NULL)
841 return 0;
842 return elf_hash_table (info)->tls_sec->vma;
843}
844
845/* The size of the thread control block. */
846#define TCB_SIZE 8
847
848/* Output a simple dynamic relocation into SRELOC. */
849
850static void
851microblaze_elf_output_dynamic_relocation (bfd *output_bfd,
852 asection *sreloc,
853 unsigned long reloc_index,
854 unsigned long indx,
855 int r_type,
856 bfd_vma offset,
857 bfd_vma addend)
858{
859
860 Elf_Internal_Rela rel;
861
862 rel.r_info = ELF32_R_INFO (indx, r_type);
863 rel.r_offset = offset;
864 rel.r_addend = addend;
865
866 bfd_elf32_swap_reloca_out (output_bfd, &rel,
867 (sreloc->contents + reloc_index * sizeof (Elf32_External_Rela)));
868}
869
7ba29e2a
NC
870/* This code is taken from elf32-m32r.c
871 There is some attempt to make this function usable for many architectures,
872 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
873 if only to serve as a learning tool.
874
875 The RELOCATE_SECTION function is called by the new ELF backend linker
876 to handle the relocations for a section.
877
878 The relocs are always passed as Rela structures; if the section
879 actually uses Rel structures, the r_addend field will always be
880 zero.
881
882 This function is responsible for adjust the section contents as
883 necessary, and (if using Rela relocs and generating a
884 relocatable output file) adjusting the reloc addend as
885 necessary.
886
887 This function does not have to worry about setting the reloc
888 address or the reloc symbol index.
889
890 LOCAL_SYMS is a pointer to the swapped in local symbols.
891
892 LOCAL_SECTIONS is an array giving the section in the input file
893 corresponding to the st_shndx field of each local symbol.
894
895 The global hash table entry for the global symbols can be found
896 via elf_sym_hashes (input_bfd).
897
898 When generating relocatable output, this function must handle
899 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
900 going to be the section symbol corresponding to the output
901 section, which means that the addend must be adjusted
902 accordingly. */
903
904static bfd_boolean
905microblaze_elf_relocate_section (bfd *output_bfd,
906 struct bfd_link_info *info,
907 bfd *input_bfd,
908 asection *input_section,
909 bfd_byte *contents,
910 Elf_Internal_Rela *relocs,
911 Elf_Internal_Sym *local_syms,
912 asection **local_sections)
913{
914 struct elf32_mb_link_hash_table *htab;
915 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
916 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
917 Elf_Internal_Rela *rel, *relend;
f23200ad 918 int endian = (bfd_little_endian (output_bfd)) ? 0 : 2;
7ba29e2a
NC
919 /* Assume success. */
920 bfd_boolean ret = TRUE;
921 asection *sreloc;
922 bfd_vma *local_got_offsets;
69b06cc8 923 unsigned int tls_type;
7ba29e2a
NC
924
925 if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1])
926 microblaze_elf_howto_init ();
927
928 htab = elf32_mb_hash_table (info);
4dfe6ac6
NC
929 if (htab == NULL)
930 return FALSE;
931
7ba29e2a
NC
932 local_got_offsets = elf_local_got_offsets (input_bfd);
933
934 sreloc = elf_section_data (input_section)->sreloc;
935
936 rel = relocs;
937 relend = relocs + input_section->reloc_count;
938 for (; rel < relend; rel++)
939 {
940 int r_type;
941 reloc_howto_type *howto;
942 unsigned long r_symndx;
943 bfd_vma addend = rel->r_addend;
944 bfd_vma offset = rel->r_offset;
945 struct elf_link_hash_entry *h;
946 Elf_Internal_Sym *sym;
947 asection *sec;
948 const char *sym_name;
949 bfd_reloc_status_type r = bfd_reloc_ok;
950 const char *errmsg = NULL;
951 bfd_boolean unresolved_reloc = FALSE;
952
953 h = NULL;
954 r_type = ELF32_R_TYPE (rel->r_info);
69b06cc8
ME
955 tls_type = 0;
956
7ba29e2a
NC
957 if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max)
958 {
4eca0228
AM
959 _bfd_error_handler (_("%s: unknown relocation type %d"),
960 bfd_get_filename (input_bfd), (int) r_type);
7ba29e2a
NC
961 bfd_set_error (bfd_error_bad_value);
962 ret = FALSE;
963 continue;
964 }
965
966 howto = microblaze_elf_howto_table[r_type];
967 r_symndx = ELF32_R_SYM (rel->r_info);
968
0e1862bb 969 if (bfd_link_relocatable (info))
7ba29e2a
NC
970 {
971 /* This is a relocatable link. We don't have to change
972 anything, unless the reloc is against a section symbol,
973 in which case we have to adjust according to where the
974 section symbol winds up in the output section. */
975 sec = NULL;
976 if (r_symndx >= symtab_hdr->sh_info)
977 /* External symbol. */
978 continue;
979
980 /* Local symbol. */
981 sym = local_syms + r_symndx;
982 sym_name = "<local symbol>";
983 /* STT_SECTION: symbol is associated with a section. */
984 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
985 /* Symbol isn't associated with a section. Nothing to do. */
986 continue;
987
988 sec = local_sections[r_symndx];
989 addend += sec->output_offset + sym->st_value;
990#ifndef USE_REL
991 /* This can't be done for USE_REL because it doesn't mean anything
992 and elf_link_input_bfd asserts this stays zero. */
993 /* rel->r_addend = addend; */
994#endif
995
996#ifndef USE_REL
997 /* Addends are stored with relocs. We're done. */
998 continue;
999#else /* USE_REL */
1000 /* If partial_inplace, we need to store any additional addend
1001 back in the section. */
1002 if (!howto->partial_inplace)
1003 continue;
1004 /* ??? Here is a nice place to call a special_function like handler. */
1005 r = _bfd_relocate_contents (howto, input_bfd, addend,
1006 contents + offset);
1007#endif /* USE_REL */
1008 }
1009 else
1010 {
1011 bfd_vma relocation;
1012
1013 /* This is a final link. */
1014 sym = NULL;
1015 sec = NULL;
1016 unresolved_reloc = FALSE;
1017
1018 if (r_symndx < symtab_hdr->sh_info)
1019 {
1020 /* Local symbol. */
1021 sym = local_syms + r_symndx;
1022 sec = local_sections[r_symndx];
1023 if (sec == 0)
1024 continue;
1025 sym_name = "<local symbol>";
1026 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1027 /* r_addend may have changed if the reference section was
1028 a merge section. */
1029 addend = rel->r_addend;
1030 }
1031 else
1032 {
1033 /* External symbol. */
1034 bfd_boolean warned ATTRIBUTE_UNUSED;
62d887d4 1035 bfd_boolean ignored ATTRIBUTE_UNUSED;
7ba29e2a
NC
1036
1037 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1038 r_symndx, symtab_hdr, sym_hashes,
1039 h, sec, relocation,
62d887d4 1040 unresolved_reloc, warned, ignored);
7ba29e2a
NC
1041 sym_name = h->root.root.string;
1042 }
1043
1044 /* Sanity check the address. */
e57278ef 1045 if (offset > bfd_get_section_limit (input_bfd, input_section))
7ba29e2a
NC
1046 {
1047 r = bfd_reloc_outofrange;
1048 goto check_reloc;
1049 }
1050
1051 switch ((int) r_type)
1052 {
1053 case (int) R_MICROBLAZE_SRO32 :
1054 {
1055 const char *name;
1056
1057 /* Only relocate if the symbol is defined. */
1058 if (sec)
1059 {
a0f49396 1060 name = bfd_get_section_name (sec->owner, sec);
7ba29e2a
NC
1061
1062 if (strcmp (name, ".sdata2") == 0
1063 || strcmp (name, ".sbss2") == 0)
1064 {
1065 if (ro_small_data_pointer == 0)
1066 microblaze_elf_final_sdp (info);
1067 if (ro_small_data_pointer == 0)
1068 {
1069 ret = FALSE;
1070 r = bfd_reloc_undefined;
1071 goto check_reloc;
1072 }
1073
1074 /* At this point `relocation' contains the object's
1075 address. */
1076 relocation -= ro_small_data_pointer;
1077 /* Now it contains the offset from _SDA2_BASE_. */
1078 r = _bfd_final_link_relocate (howto, input_bfd,
1079 input_section,
1080 contents, offset,
1081 relocation, addend);
1082 }
1083 else
1084 {
4eca0228
AM
1085 _bfd_error_handler
1086 (_("%s: The target (%s) of an %s relocation "
1087 "is in the wrong section (%s)"),
1088 bfd_get_filename (input_bfd),
1089 sym_name,
1090 microblaze_elf_howto_table[(int) r_type]->name,
1091 bfd_get_section_name (sec->owner, sec));
7ba29e2a
NC
1092 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1093 ret = FALSE;
1094 continue;
1095 }
1096 }
1097 }
1098 break;
1099
1100 case (int) R_MICROBLAZE_SRW32 :
1101 {
1102 const char *name;
1103
1104 /* Only relocate if the symbol is defined. */
1105 if (sec)
1106 {
a0f49396 1107 name = bfd_get_section_name (sec->owner, sec);
7ba29e2a
NC
1108
1109 if (strcmp (name, ".sdata") == 0
1110 || strcmp (name, ".sbss") == 0)
1111 {
1112 if (rw_small_data_pointer == 0)
1113 microblaze_elf_final_sdp (info);
1114 if (rw_small_data_pointer == 0)
1115 {
1116 ret = FALSE;
1117 r = bfd_reloc_undefined;
1118 goto check_reloc;
1119 }
1120
1121 /* At this point `relocation' contains the object's
1122 address. */
1123 relocation -= rw_small_data_pointer;
1124 /* Now it contains the offset from _SDA_BASE_. */
1125 r = _bfd_final_link_relocate (howto, input_bfd,
1126 input_section,
1127 contents, offset,
1128 relocation, addend);
1129 }
1130 else
1131 {
4eca0228
AM
1132 _bfd_error_handler
1133 (_("%s: The target (%s) of an %s relocation "
1134 "is in the wrong section (%s)"),
1135 bfd_get_filename (input_bfd),
1136 sym_name,
1137 microblaze_elf_howto_table[(int) r_type]->name,
1138 bfd_get_section_name (sec->owner, sec));
7ba29e2a
NC
1139 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1140 ret = FALSE;
1141 continue;
1142 }
1143 }
1144 }
1145 break;
1146
1147 case (int) R_MICROBLAZE_32_SYM_OP_SYM:
1148 break; /* Do nothing. */
1149
1150 case (int) R_MICROBLAZE_GOTPC_64:
1151 relocation = htab->sgotplt->output_section->vma
1152 + htab->sgotplt->output_offset;
1153 relocation -= (input_section->output_section->vma
1154 + input_section->output_offset
1155 + offset + INST_WORD_SIZE);
1156 relocation += addend;
1157 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
f23200ad 1158 contents + offset + endian);
7ba29e2a 1159 bfd_put_16 (input_bfd, relocation & 0xffff,
f23200ad 1160 contents + offset + endian + INST_WORD_SIZE);
7ba29e2a
NC
1161 break;
1162
1163 case (int) R_MICROBLAZE_PLT_64:
1164 {
1165 bfd_vma immediate;
1166 if (htab->splt != NULL && h != NULL
1167 && h->plt.offset != (bfd_vma) -1)
1168 {
1169 relocation = (htab->splt->output_section->vma
1170 + htab->splt->output_offset
1171 + h->plt.offset);
1172 unresolved_reloc = FALSE;
1173 immediate = relocation - (input_section->output_section->vma
1174 + input_section->output_offset
1175 + offset + INST_WORD_SIZE);
1176 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
f23200ad 1177 contents + offset + endian);
7ba29e2a 1178 bfd_put_16 (input_bfd, immediate & 0xffff,
f23200ad 1179 contents + offset + endian + INST_WORD_SIZE);
7ba29e2a
NC
1180 }
1181 else
1182 {
1183 relocation -= (input_section->output_section->vma
1184 + input_section->output_offset
1185 + offset + INST_WORD_SIZE);
1186 immediate = relocation;
1187 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
f23200ad 1188 contents + offset + endian);
7ba29e2a 1189 bfd_put_16 (input_bfd, immediate & 0xffff,
f23200ad 1190 contents + offset + endian + INST_WORD_SIZE);
7ba29e2a
NC
1191 }
1192 break;
1193 }
1194
69b06cc8
ME
1195 case (int) R_MICROBLAZE_TLSGD:
1196 tls_type = (TLS_TLS | TLS_GD);
1197 goto dogot;
1198 case (int) R_MICROBLAZE_TLSLD:
1199 tls_type = (TLS_TLS | TLS_LD);
1200 dogot:
7ba29e2a
NC
1201 case (int) R_MICROBLAZE_GOT_64:
1202 {
69b06cc8
ME
1203 bfd_vma *offp;
1204 bfd_vma off, off2;
1205 unsigned long indx;
1206 bfd_vma static_value;
1207
1208 bfd_boolean need_relocs = FALSE;
7ba29e2a
NC
1209 if (htab->sgot == NULL)
1210 abort ();
69b06cc8
ME
1211
1212 indx = 0;
1213 offp = NULL;
1214
1215 /* 1. Identify GOT Offset;
1216 2. Compute Static Values
1217 3. Process Module Id, Process Offset
1218 4. Fixup Relocation with GOT offset value. */
1219
1220 /* 1. Determine GOT Offset to use : TLS_LD, global, local */
1221 if (IS_TLS_LD (tls_type))
1222 offp = &htab->tlsld_got.offset;
1223 else if (h != NULL)
1224 {
1225 if (htab->sgotplt != NULL && h->got.offset != (bfd_vma) -1)
1226 offp = &h->got.offset;
1227 else
1228 abort ();
1229 }
1230 else
7ba29e2a 1231 {
7ba29e2a
NC
1232 if (local_got_offsets == NULL)
1233 abort ();
69b06cc8
ME
1234 offp = &local_got_offsets[r_symndx];
1235 }
1236
1237 if (!offp)
1238 abort ();
1239
1240 off = (*offp) & ~1;
1241 off2 = off;
1242
1243 if (IS_TLS_LD(tls_type) || IS_TLS_GD(tls_type))
1244 off2 = off + 4;
1245
1246 /* Symbol index to use for relocs */
1247 if (h != NULL)
1248 {
1249 bfd_boolean dyn =
1250 elf_hash_table (info)->dynamic_sections_created;
1251
0e1862bb
L
1252 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
1253 bfd_link_pic (info),
1254 h)
1255 && (!bfd_link_pic (info)
1256 || !SYMBOL_REFERENCES_LOCAL (info, h)))
69b06cc8
ME
1257 indx = h->dynindx;
1258 }
7ba29e2a 1259
69b06cc8 1260 /* Need to generate relocs ? */
0e1862bb 1261 if ((bfd_link_pic (info) || indx != 0)
69b06cc8
ME
1262 && (h == NULL
1263 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1264 || h->root.type != bfd_link_hash_undefweak))
1265 need_relocs = TRUE;
1266
1267 /* 2. Compute/Emit Static value of r-expression */
1268 static_value = relocation + addend;
1269
1270 /* 3. Process module-id and offset */
1271 if (! ((*offp) & 1) )
1272 {
1273 bfd_vma got_offset;
1274
1275 got_offset = (htab->sgot->output_section->vma
1276 + htab->sgot->output_offset
1277 + off);
1278
1279 /* Process module-id */
1280 if (IS_TLS_LD(tls_type))
1281 {
0e1862bb 1282 if (! bfd_link_pic (info))
7ba29e2a 1283 {
69b06cc8
ME
1284 bfd_put_32 (output_bfd, 1, htab->sgot->contents + off);
1285 }
1286 else
1287 {
1288 microblaze_elf_output_dynamic_relocation (output_bfd,
1289 htab->srelgot, htab->srelgot->reloc_count++,
1290 /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32,
1291 got_offset, 0);
7ba29e2a 1292 }
7ba29e2a 1293 }
69b06cc8
ME
1294 else if (IS_TLS_GD(tls_type))
1295 {
1296 if (! need_relocs)
1297 {
1298 bfd_put_32 (output_bfd, 1, htab->sgot->contents + off);
1299 }
1300 else
1301 {
1302 microblaze_elf_output_dynamic_relocation (output_bfd,
1303 htab->srelgot,
1304 htab->srelgot->reloc_count++,
1305 /* symindex= */ indx, R_MICROBLAZE_TLSDTPMOD32,
1306 got_offset, indx ? 0 : static_value);
1307 }
1308 }
1309
1310 /* Process Offset */
1311 if (htab->srelgot == NULL)
1312 abort ();
1313
1314 got_offset = (htab->sgot->output_section->vma
1315 + htab->sgot->output_offset
1316 + off2);
1317 if (IS_TLS_LD(tls_type))
1318 {
1319 /* For LD, offset should be 0 */
1320 *offp |= 1;
1321 bfd_put_32 (output_bfd, 0, htab->sgot->contents + off2);
1322 }
1323 else if (IS_TLS_GD(tls_type))
7ba29e2a 1324 {
69b06cc8
ME
1325 *offp |= 1;
1326 static_value -= dtprel_base(info);
1327 if (need_relocs)
1328 {
1329 microblaze_elf_output_dynamic_relocation (output_bfd,
1330 htab->srelgot, htab->srelgot->reloc_count++,
1331 /* symindex= */ indx, R_MICROBLAZE_TLSDTPREL32,
1332 got_offset, indx ? 0 : static_value);
1333 }
1334 else
1335 {
1336 bfd_put_32 (output_bfd, static_value,
1337 htab->sgot->contents + off2);
1338 }
7ba29e2a
NC
1339 }
1340 else
69b06cc8
ME
1341 {
1342 bfd_put_32 (output_bfd, static_value,
1343 htab->sgot->contents + off2);
1344
1345 /* Relocs for dyn symbols generated by
1346 finish_dynamic_symbols */
0e1862bb 1347 if (bfd_link_pic (info) && h == NULL)
69b06cc8
ME
1348 {
1349 *offp |= 1;
1350 microblaze_elf_output_dynamic_relocation (output_bfd,
1351 htab->srelgot, htab->srelgot->reloc_count++,
1352 /* symindex= */ indx, R_MICROBLAZE_REL,
1353 got_offset, static_value);
1354 }
1355 }
7ba29e2a 1356 }
69b06cc8
ME
1357
1358 /* 4. Fixup Relocation with GOT offset value
1359 Compute relative address of GOT entry for applying
1360 the current relocation */
1361 relocation = htab->sgot->output_section->vma
1362 + htab->sgot->output_offset
1363 + off
1364 - htab->sgotplt->output_section->vma
1365 - htab->sgotplt->output_offset;
1366
1367 /* Apply Current Relocation */
7ba29e2a 1368 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
f23200ad 1369 contents + offset + endian);
7ba29e2a 1370 bfd_put_16 (input_bfd, relocation & 0xffff,
f23200ad 1371 contents + offset + endian + INST_WORD_SIZE);
69b06cc8
ME
1372
1373 unresolved_reloc = FALSE;
7ba29e2a
NC
1374 break;
1375 }
1376
1377 case (int) R_MICROBLAZE_GOTOFF_64:
1378 {
1379 bfd_vma immediate;
1380 unsigned short lo, high;
1381 relocation += addend;
1382 relocation -= htab->sgotplt->output_section->vma
1383 + htab->sgotplt->output_offset;
1384 /* Write this value into correct location. */
1385 immediate = relocation;
1386 lo = immediate & 0x0000ffff;
1387 high = (immediate >> 16) & 0x0000ffff;
f23200ad
ME
1388 bfd_put_16 (input_bfd, high, contents + offset + endian);
1389 bfd_put_16 (input_bfd, lo, contents + offset + INST_WORD_SIZE + endian);
7ba29e2a
NC
1390 break;
1391 }
1392
1393 case (int) R_MICROBLAZE_GOTOFF_32:
1394 {
1395 relocation += addend;
1396 relocation -= htab->sgotplt->output_section->vma
1397 + htab->sgotplt->output_offset;
1398 /* Write this value into correct location. */
1399 bfd_put_32 (input_bfd, relocation, contents + offset);
1400 break;
1401 }
1402
69b06cc8
ME
1403 case (int) R_MICROBLAZE_TLSDTPREL64:
1404 relocation += addend;
1405 relocation -= dtprel_base(info);
1406 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1407 contents + offset + 2);
1408 bfd_put_16 (input_bfd, relocation & 0xffff,
1409 contents + offset + 2 + INST_WORD_SIZE);
1410 break;
7ba29e2a
NC
1411 case (int) R_MICROBLAZE_64_PCREL :
1412 case (int) R_MICROBLAZE_64:
1413 case (int) R_MICROBLAZE_32:
1414 {
cf35638d 1415 /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
7ba29e2a
NC
1416 from removed linkonce sections, or sections discarded by
1417 a linker script. */
cf35638d 1418 if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
7ba29e2a
NC
1419 {
1420 relocation += addend;
1421 if (r_type == R_MICROBLAZE_32)
1422 bfd_put_32 (input_bfd, relocation, contents + offset);
1423 else
1424 {
1425 if (r_type == R_MICROBLAZE_64_PCREL)
1426 relocation -= (input_section->output_section->vma
1427 + input_section->output_offset
1428 + offset + INST_WORD_SIZE);
1429 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
f23200ad 1430 contents + offset + endian);
7ba29e2a 1431 bfd_put_16 (input_bfd, relocation & 0xffff,
f23200ad 1432 contents + offset + endian + INST_WORD_SIZE);
7ba29e2a
NC
1433 }
1434 break;
1435 }
1436
0e1862bb 1437 if ((bfd_link_pic (info)
7ba29e2a
NC
1438 && (h == NULL
1439 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1440 || h->root.type != bfd_link_hash_undefweak)
1441 && (!howto->pc_relative
1442 || (h != NULL
1443 && h->dynindx != -1
1444 && (!info->symbolic
1445 || !h->def_regular))))
0e1862bb 1446 || (!bfd_link_pic (info)
7ba29e2a
NC
1447 && h != NULL
1448 && h->dynindx != -1
1449 && !h->non_got_ref
1450 && ((h->def_dynamic
1451 && !h->def_regular)
1452 || h->root.type == bfd_link_hash_undefweak
1453 || h->root.type == bfd_link_hash_undefined)))
1454 {
1455 Elf_Internal_Rela outrel;
1456 bfd_byte *loc;
c7e2358a 1457 bfd_boolean skip;
7ba29e2a
NC
1458
1459 /* When generating a shared object, these relocations
1460 are copied into the output file to be resolved at run
1461 time. */
1462
1463 BFD_ASSERT (sreloc != NULL);
1464
1465 skip = FALSE;
1466
1467 outrel.r_offset =
1468 _bfd_elf_section_offset (output_bfd, info, input_section,
1469 rel->r_offset);
1470 if (outrel.r_offset == (bfd_vma) -1)
1471 skip = TRUE;
1472 else if (outrel.r_offset == (bfd_vma) -2)
c7e2358a 1473 skip = TRUE;
7ba29e2a
NC
1474 outrel.r_offset += (input_section->output_section->vma
1475 + input_section->output_offset);
1476
1477 if (skip)
1478 memset (&outrel, 0, sizeof outrel);
1479 /* h->dynindx may be -1 if the symbol was marked to
1480 become local. */
1481 else if (h != NULL
1482 && ((! info->symbolic && h->dynindx != -1)
1483 || !h->def_regular))
1484 {
1485 BFD_ASSERT (h->dynindx != -1);
1486 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1487 outrel.r_addend = addend;
1488 }
1489 else
1490 {
1491 if (r_type == R_MICROBLAZE_32)
1492 {
1493 outrel.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL);
1494 outrel.r_addend = relocation + addend;
1495 }
1496 else
1497 {
1498 BFD_FAIL ();
4eca0228 1499 _bfd_error_handler
7ba29e2a
NC
1500 (_("%B: probably compiled without -fPIC?"),
1501 input_bfd);
1502 bfd_set_error (bfd_error_bad_value);
1503 return FALSE;
1504 }
1505 }
1506
1507 loc = sreloc->contents;
1508 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
1509 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1510 break;
1511 }
1512 else
1513 {
1514 relocation += addend;
1515 if (r_type == R_MICROBLAZE_32)
1516 bfd_put_32 (input_bfd, relocation, contents + offset);
1517 else
1518 {
1519 if (r_type == R_MICROBLAZE_64_PCREL)
1520 relocation -= (input_section->output_section->vma
1521 + input_section->output_offset
1522 + offset + INST_WORD_SIZE);
1523 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
f23200ad 1524 contents + offset + endian);
7ba29e2a 1525 bfd_put_16 (input_bfd, relocation & 0xffff,
f23200ad 1526 contents + offset + endian + INST_WORD_SIZE);
7ba29e2a
NC
1527 }
1528 break;
1529 }
1530 }
1531
1532 default :
1533 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1534 contents, offset,
1535 relocation, addend);
1536 break;
1537 }
1538 }
1539
1540 check_reloc:
1541
1542 if (r != bfd_reloc_ok)
1543 {
1544 /* FIXME: This should be generic enough to go in a utility. */
1545 const char *name;
1546
1547 if (h != NULL)
1548 name = h->root.root.string;
1549 else
1550 {
1551 name = (bfd_elf_string_from_elf_section
1552 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1553 if (name == NULL || *name == '\0')
1554 name = bfd_section_name (input_bfd, sec);
1555 }
1556
1557 if (errmsg != NULL)
1558 goto common_error;
1559
1560 switch (r)
1561 {
1562 case bfd_reloc_overflow:
1a72702b
AM
1563 (*info->callbacks->reloc_overflow)
1564 (info, (h ? &h->root : NULL), name, howto->name,
1565 (bfd_vma) 0, input_bfd, input_section, offset);
7ba29e2a
NC
1566 break;
1567
1568 case bfd_reloc_undefined:
1a72702b
AM
1569 (*info->callbacks->undefined_symbol)
1570 (info, name, input_bfd, input_section, offset, TRUE);
7ba29e2a
NC
1571 break;
1572
1573 case bfd_reloc_outofrange:
1574 errmsg = _("internal error: out of range error");
1575 goto common_error;
1576
1577 case bfd_reloc_notsupported:
1578 errmsg = _("internal error: unsupported relocation error");
1579 goto common_error;
1580
1581 case bfd_reloc_dangerous:
1582 errmsg = _("internal error: dangerous error");
1583 goto common_error;
1584
1585 default:
1586 errmsg = _("internal error: unknown error");
1587 /* Fall through. */
1588 common_error:
1a72702b
AM
1589 (*info->callbacks->warning) (info, errmsg, name, input_bfd,
1590 input_section, offset);
7ba29e2a
NC
1591 break;
1592 }
1593 }
1594 }
1595
1596 return ret;
1597}
f23200ad
ME
1598
1599/* Merge backend specific data from an object file to the output
1600 object file when linking.
1601
1602 Note: We only use this hook to catch endian mismatches. */
1603static bfd_boolean
1604microblaze_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
1605{
1606 /* Check if we have the same endianess. */
1607 if (! _bfd_generic_verify_endian_match (ibfd, obfd))
1608 return FALSE;
1609
1610 return TRUE;
1611}
1612
7ba29e2a
NC
1613\f
1614/* Calculate fixup value for reference. */
1615
1616static int
886e427f 1617calc_fixup (bfd_vma start, bfd_vma size, asection *sec)
7ba29e2a 1618{
886e427f 1619 bfd_vma end = start + size;
7ba29e2a
NC
1620 int i, fixup = 0;
1621
1622 if (sec == NULL || sec->relax == NULL)
1623 return 0;
1624
1625 /* Look for addr in relax table, total fixup value. */
1626 for (i = 0; i < sec->relax_count; i++)
1627 {
886e427f 1628 if (end <= sec->relax[i].addr)
7ba29e2a 1629 break;
886e427f
ME
1630 if ((end != start) && (start > sec->relax[i].addr))
1631 continue;
7ba29e2a
NC
1632 fixup += sec->relax[i].size;
1633 }
7ba29e2a
NC
1634 return fixup;
1635}
1636
f23200ad
ME
1637/* Read-modify-write into the bfd, an immediate value into appropriate fields of
1638 a 32-bit instruction. */
1639static void
1640microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1641{
1642 unsigned long instr = bfd_get_32 (abfd, bfd_addr);
1643 instr &= ~0x0000ffff;
1644 instr |= (val & 0x0000ffff);
1645 bfd_put_32 (abfd, instr, bfd_addr);
1646}
1647
1648/* Read-modify-write into the bfd, an immediate value into appropriate fields of
1649 two consecutive 32-bit instructions. */
1650static void
1651microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1652{
1653 unsigned long instr_hi;
1654 unsigned long instr_lo;
1655
1656 instr_hi = bfd_get_32 (abfd, bfd_addr);
1657 instr_hi &= ~0x0000ffff;
1658 instr_hi |= ((val >> 16) & 0x0000ffff);
1659 bfd_put_32 (abfd, instr_hi, bfd_addr);
1660
1661 instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE);
1662 instr_lo &= ~0x0000ffff;
1663 instr_lo |= (val & 0x0000ffff);
1664 bfd_put_32 (abfd, instr_lo, bfd_addr + INST_WORD_SIZE);
1665}
1666
7ba29e2a
NC
1667static bfd_boolean
1668microblaze_elf_relax_section (bfd *abfd,
1669 asection *sec,
1670 struct bfd_link_info *link_info,
1671 bfd_boolean *again)
1672{
1673 Elf_Internal_Shdr *symtab_hdr;
1674 Elf_Internal_Rela *internal_relocs;
1675 Elf_Internal_Rela *free_relocs = NULL;
1676 Elf_Internal_Rela *irel, *irelend;
1677 bfd_byte *contents = NULL;
1678 bfd_byte *free_contents = NULL;
1679 int rel_count;
1680 unsigned int shndx;
91d6fa6a 1681 int i, sym_index;
7ba29e2a
NC
1682 asection *o;
1683 struct elf_link_hash_entry *sym_hash;
1684 Elf_Internal_Sym *isymbuf, *isymend;
1685 Elf_Internal_Sym *isym;
1686 int symcount;
1687 int offset;
1688 bfd_vma src, dest;
1689
1690 /* We only do this once per section. We may be able to delete some code
1691 by running multiple passes, but it is not worth it. */
1692 *again = FALSE;
1693
1694 /* Only do this for a text section. */
0e1862bb 1695 if (bfd_link_relocatable (link_info)
7ba29e2a 1696 || (sec->flags & SEC_RELOC) == 0
f23200ad
ME
1697 || (sec->reloc_count == 0)
1698 || (sec->flags & SEC_CODE) == 0)
7ba29e2a
NC
1699 return TRUE;
1700
1701 BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0));
1702
1703 /* If this is the first time we have been called for this section,
1704 initialize the cooked size. */
1705 if (sec->size == 0)
1706 sec->size = sec->rawsize;
1707
1708 /* Get symbols for this section. */
1709 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1710 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1711 symcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
1712 if (isymbuf == NULL)
1713 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount,
1714 0, NULL, NULL, NULL);
1715 BFD_ASSERT (isymbuf != NULL);
1716
91d6fa6a 1717 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
7ba29e2a
NC
1718 if (internal_relocs == NULL)
1719 goto error_return;
1720 if (! link_info->keep_memory)
1721 free_relocs = internal_relocs;
1722
1723 sec->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
1724 * sizeof (struct relax_table));
1725 if (sec->relax == NULL)
1726 goto error_return;
1727 sec->relax_count = 0;
1728
1729 irelend = internal_relocs + sec->reloc_count;
1730 rel_count = 0;
1731 for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1732 {
1733 bfd_vma symval;
1734 if ((ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL)
1735 && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64 ))
1736 continue; /* Can't delete this reloc. */
1737
1738 /* Get the section contents. */
1739 if (contents == NULL)
1740 {
1741 if (elf_section_data (sec)->this_hdr.contents != NULL)
1742 contents = elf_section_data (sec)->this_hdr.contents;
1743 else
1744 {
1745 contents = (bfd_byte *) bfd_malloc (sec->size);
1746 if (contents == NULL)
1747 goto error_return;
1748 free_contents = contents;
1749
1750 if (!bfd_get_section_contents (abfd, sec, contents,
1751 (file_ptr) 0, sec->size))
1752 goto error_return;
1753 elf_section_data (sec)->this_hdr.contents = contents;
1754 }
1755 }
1756
1757 /* Get the value of the symbol referred to by the reloc. */
1758 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1759 {
1760 /* A local symbol. */
7ba29e2a
NC
1761 asection *sym_sec;
1762
1763 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1764 if (isym->st_shndx == SHN_UNDEF)
1765 sym_sec = bfd_und_section_ptr;
1766 else if (isym->st_shndx == SHN_ABS)
1767 sym_sec = bfd_abs_section_ptr;
1768 else if (isym->st_shndx == SHN_COMMON)
1769 sym_sec = bfd_com_section_ptr;
1770 else
1771 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1772
1773 symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
1774 }
1775 else
1776 {
1777 unsigned long indx;
1778 struct elf_link_hash_entry *h;
1779
1780 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1781 h = elf_sym_hashes (abfd)[indx];
1782 BFD_ASSERT (h != NULL);
1783
1784 if (h->root.type != bfd_link_hash_defined
1785 && h->root.type != bfd_link_hash_defweak)
1786 /* This appears to be a reference to an undefined
1787 symbol. Just ignore it--it will be caught by the
1788 regular reloc processing. */
1789 continue;
1790
1791 symval = (h->root.u.def.value
1792 + h->root.u.def.section->output_section->vma
1793 + h->root.u.def.section->output_offset);
1794 }
1795
1796 /* If this is a PC-relative reloc, subtract the instr offset from
1797 the symbol value. */
1798 if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_64_PCREL)
1799 {
1800 symval = symval + irel->r_addend
1801 - (irel->r_offset
1802 + sec->output_section->vma
1803 + sec->output_offset);
1804 }
1805 else
1806 symval += irel->r_addend;
1807
1808 if ((symval & 0xffff8000) == 0
1809 || (symval & 0xffff8000) == 0xffff8000)
1810 {
1811 /* We can delete this instruction. */
1812 sec->relax[sec->relax_count].addr = irel->r_offset;
1813 sec->relax[sec->relax_count].size = INST_WORD_SIZE;
1814 sec->relax_count++;
1815
1816 /* Rewrite relocation type. */
1817 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1818 {
1819 case R_MICROBLAZE_64_PCREL:
1820 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1821 (int) R_MICROBLAZE_32_PCREL_LO);
1822 break;
1823 case R_MICROBLAZE_64:
1824 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1825 (int) R_MICROBLAZE_32_LO);
1826 break;
1827 default:
1828 /* Cannot happen. */
1829 BFD_ASSERT (FALSE);
1830 }
1831 }
1832 } /* Loop through all relocations. */
1833
1834 /* Loop through the relocs again, and see if anything needs to change. */
1835 if (sec->relax_count > 0)
1836 {
1837 shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1838 rel_count = 0;
1839 sec->relax[sec->relax_count].addr = sec->size;
1840
1841 for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1842 {
1843 bfd_vma nraddr;
1844
1845 /* Get the new reloc address. */
886e427f 1846 nraddr = irel->r_offset - calc_fixup (irel->r_offset, 0, sec);
7ba29e2a
NC
1847 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1848 {
1849 default:
1850 break;
1851 case R_MICROBLAZE_64_PCREL:
1852 break;
1853 case R_MICROBLAZE_64:
1854 case R_MICROBLAZE_32_LO:
1855 /* If this reloc is against a symbol defined in this
1856 section, we must check the addend to see it will put the value in
1857 range to be adjusted, and hence must be changed. */
1858 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1859 {
7ba29e2a
NC
1860 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1861 /* Only handle relocs against .text. */
1862 if (isym->st_shndx == shndx
1863 && ELF32_ST_TYPE (isym->st_info) == STT_SECTION)
886e427f 1864 irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
7ba29e2a
NC
1865 }
1866 break;
1867 case R_MICROBLAZE_NONE:
1868 {
1869 /* This was a PC-relative instruction that was
1870 completely resolved. */
1871 int sfix, efix;
1872 bfd_vma target_address;
1873 target_address = irel->r_addend + irel->r_offset;
886e427f
ME
1874 sfix = calc_fixup (irel->r_offset, 0, sec);
1875 efix = calc_fixup (target_address, 0, sec);
7ba29e2a
NC
1876 irel->r_addend -= (efix - sfix);
1877 /* Should use HOWTO. */
f23200ad
ME
1878 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
1879 irel->r_addend);
7ba29e2a
NC
1880 }
1881 break;
1882 case R_MICROBLAZE_64_NONE:
1883 {
1884 /* This was a PC-relative 64-bit instruction that was
1885 completely resolved. */
1886 int sfix, efix;
1887 bfd_vma target_address;
1888 target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE;
886e427f
ME
1889 sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec);
1890 efix = calc_fixup (target_address, 0, sec);
7ba29e2a 1891 irel->r_addend -= (efix - sfix);
f23200ad
ME
1892 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset
1893 + INST_WORD_SIZE, irel->r_addend);
7ba29e2a
NC
1894 }
1895 break;
1896 }
1897 irel->r_offset = nraddr;
1898 } /* Change all relocs in this section. */
1899
1900 /* Look through all other sections. */
1901 for (o = abfd->sections; o != NULL; o = o->next)
1902 {
91d6fa6a 1903 Elf_Internal_Rela *irelocs;
7ba29e2a
NC
1904 Elf_Internal_Rela *irelscan, *irelscanend;
1905 bfd_byte *ocontents;
1906
1907 if (o == sec
1908 || (o->flags & SEC_RELOC) == 0
1909 || o->reloc_count == 0)
1910 continue;
1911
1912 /* We always cache the relocs. Perhaps, if info->keep_memory is
1913 FALSE, we should free them, if we are permitted to. */
1914
91d6fa6a
NC
1915 irelocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, TRUE);
1916 if (irelocs == NULL)
7ba29e2a
NC
1917 goto error_return;
1918
1919 ocontents = NULL;
91d6fa6a
NC
1920 irelscanend = irelocs + o->reloc_count;
1921 for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
7ba29e2a
NC
1922 {
1923 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
1924 {
1925 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1926
1927 /* Look at the reloc only if the value has been resolved. */
1928 if (isym->st_shndx == shndx
1929 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
1930 {
1931 if (ocontents == NULL)
1932 {
1933 if (elf_section_data (o)->this_hdr.contents != NULL)
1934 ocontents = elf_section_data (o)->this_hdr.contents;
1935 else
1936 {
1937 /* We always cache the section contents.
1938 Perhaps, if info->keep_memory is FALSE, we
1939 should free them, if we are permitted to. */
1940 if (o->rawsize == 0)
1941 o->rawsize = o->size;
1942 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
1943 if (ocontents == NULL)
1944 goto error_return;
1945 if (!bfd_get_section_contents (abfd, o, ocontents,
1946 (file_ptr) 0,
1947 o->rawsize))
1948 goto error_return;
1949 elf_section_data (o)->this_hdr.contents = ocontents;
1950 }
1951
1952 }
886e427f 1953 irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
7ba29e2a
NC
1954 }
1955 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
1956 {
1957 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1958
1959 /* Look at the reloc only if the value has been resolved. */
1960 if (ocontents == NULL)
1961 {
1962 if (elf_section_data (o)->this_hdr.contents != NULL)
1963 ocontents = elf_section_data (o)->this_hdr.contents;
1964 else
1965 {
1966 /* We always cache the section contents.
1967 Perhaps, if info->keep_memory is FALSE, we
1968 should free them, if we are permitted to. */
1969
1970 if (o->rawsize == 0)
1971 o->rawsize = o->size;
1972 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
1973 if (ocontents == NULL)
1974 goto error_return;
1975 if (!bfd_get_section_contents (abfd, o, ocontents,
1976 (file_ptr) 0,
1977 o->rawsize))
1978 goto error_return;
1979 elf_section_data (o)->this_hdr.contents = ocontents;
1980 }
1981 }
1982 irelscan->r_addend -= calc_fixup (irel->r_addend
1983 + isym->st_value,
886e427f 1984 0,
7ba29e2a
NC
1985 sec);
1986 }
1987 }
1988 else if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO)
1989 || (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_LO))
1990 {
1991 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1992
1993 /* Look at the reloc only if the value has been resolved. */
1994 if (isym->st_shndx == shndx
1995 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
1996 {
1997 bfd_vma immediate;
1998 bfd_vma target_address;
1999
2000 if (ocontents == NULL)
2001 {
2002 if (elf_section_data (o)->this_hdr.contents != NULL)
2003 ocontents = elf_section_data (o)->this_hdr.contents;
2004 else
2005 {
2006 /* We always cache the section contents.
2007 Perhaps, if info->keep_memory is FALSE, we
2008 should free them, if we are permitted to. */
2009 if (o->rawsize == 0)
2010 o->rawsize = o->size;
2011 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2012 if (ocontents == NULL)
2013 goto error_return;
2014 if (!bfd_get_section_contents (abfd, o, ocontents,
2015 (file_ptr) 0,
2016 o->rawsize))
2017 goto error_return;
2018 elf_section_data (o)->this_hdr.contents = ocontents;
2019 }
2020 }
2021
f23200ad
ME
2022 unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
2023 immediate = instr & 0x0000ffff;
7ba29e2a 2024 target_address = immediate;
886e427f 2025 offset = calc_fixup (target_address, 0, sec);
7ba29e2a
NC
2026 immediate -= offset;
2027 irelscan->r_addend -= offset;
f23200ad
ME
2028 microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
2029 irelscan->r_addend);
7ba29e2a
NC
2030 }
2031 }
2032
2033 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64)
2034 {
2035 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2036
2037 /* Look at the reloc only if the value has been resolved. */
2038 if (isym->st_shndx == shndx
2039 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2040 {
2041 bfd_vma immediate;
2042
2043 if (ocontents == NULL)
2044 {
2045 if (elf_section_data (o)->this_hdr.contents != NULL)
2046 ocontents = elf_section_data (o)->this_hdr.contents;
2047 else
2048 {
2049 /* We always cache the section contents.
2050 Perhaps, if info->keep_memory is FALSE, we
2051 should free them, if we are permitted to. */
2052
2053 if (o->rawsize == 0)
2054 o->rawsize = o->size;
2055 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2056 if (ocontents == NULL)
2057 goto error_return;
2058 if (!bfd_get_section_contents (abfd, o, ocontents,
2059 (file_ptr) 0,
2060 o->rawsize))
2061 goto error_return;
2062 elf_section_data (o)->this_hdr.contents = ocontents;
2063 }
2064 }
f23200ad
ME
2065 unsigned long instr_hi = bfd_get_32 (abfd, ocontents
2066 + irelscan->r_offset);
2067 unsigned long instr_lo = bfd_get_32 (abfd, ocontents
2068 + irelscan->r_offset
2069 + INST_WORD_SIZE);
2070 immediate = (instr_hi & 0x0000ffff) << 16;
2071 immediate |= (instr_lo & 0x0000ffff);
886e427f 2072 offset = calc_fixup (irelscan->r_addend, 0, sec);
7ba29e2a
NC
2073 immediate -= offset;
2074 irelscan->r_addend -= offset;
2075 }
2076 }
2077 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
2078 {
2079 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2080
2081 /* Look at the reloc only if the value has been resolved. */
2082 if (isym->st_shndx == shndx
2083 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2084 {
2085 bfd_vma immediate;
2086 bfd_vma target_address;
2087
2088 if (ocontents == NULL)
2089 {
2090 if (elf_section_data (o)->this_hdr.contents != NULL)
2091 ocontents = elf_section_data (o)->this_hdr.contents;
2092 else
2093 {
2094 /* We always cache the section contents.
2095 Perhaps, if info->keep_memory is FALSE, we
2096 should free them, if we are permitted to. */
2097 if (o->rawsize == 0)
2098 o->rawsize = o->size;
2099 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2100 if (ocontents == NULL)
2101 goto error_return;
2102 if (!bfd_get_section_contents (abfd, o, ocontents,
2103 (file_ptr) 0,
2104 o->rawsize))
2105 goto error_return;
2106 elf_section_data (o)->this_hdr.contents = ocontents;
2107 }
2108 }
f23200ad
ME
2109 unsigned long instr_hi = bfd_get_32 (abfd, ocontents
2110 + irelscan->r_offset);
2111 unsigned long instr_lo = bfd_get_32 (abfd, ocontents
2112 + irelscan->r_offset
2113 + INST_WORD_SIZE);
2114 immediate = (instr_hi & 0x0000ffff) << 16;
2115 immediate |= (instr_lo & 0x0000ffff);
7ba29e2a 2116 target_address = immediate;
886e427f 2117 offset = calc_fixup (target_address, 0, sec);
7ba29e2a
NC
2118 immediate -= offset;
2119 irelscan->r_addend -= offset;
f23200ad
ME
2120 microblaze_bfd_write_imm_value_64 (abfd, ocontents
2121 + irelscan->r_offset, immediate);
7ba29e2a
NC
2122 }
2123 }
2124 }
2125 }
2126
2127 /* Adjust the local symbols defined in this section. */
2128 isymend = isymbuf + symtab_hdr->sh_info;
2129 for (isym = isymbuf; isym < isymend; isym++)
2130 {
2131 if (isym->st_shndx == shndx)
886e427f
ME
2132 {
2133 isym->st_value -= calc_fixup (isym->st_value, 0, sec);
2134 if (isym->st_size)
2135 isym->st_size -= calc_fixup (isym->st_value, isym->st_size, sec);
2136 }
7ba29e2a
NC
2137 }
2138
2139 /* Now adjust the global symbols defined in this section. */
2140 isym = isymbuf + symtab_hdr->sh_info;
886e427f
ME
2141 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)) - symtab_hdr->sh_info;
2142 for (sym_index = 0; sym_index < symcount; sym_index++)
7ba29e2a 2143 {
91d6fa6a 2144 sym_hash = elf_sym_hashes (abfd)[sym_index];
886e427f 2145 if ((sym_hash->root.type == bfd_link_hash_defined
7ba29e2a
NC
2146 || sym_hash->root.type == bfd_link_hash_defweak)
2147 && sym_hash->root.u.def.section == sec)
886e427f
ME
2148 {
2149 sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value,
2150 0, sec);
2151 if (sym_hash->size)
2152 sym_hash->size -= calc_fixup (sym_hash->root.u.def.value,
2153 sym_hash->size, sec);
2154 }
2155 }
7ba29e2a
NC
2156
2157 /* Physically move the code and change the cooked size. */
2158 dest = sec->relax[0].addr;
2159 for (i = 0; i < sec->relax_count; i++)
2160 {
2161 int len;
2162 src = sec->relax[i].addr + sec->relax[i].size;
2163 len = sec->relax[i+1].addr - sec->relax[i].addr - sec->relax[i].size;
2164
2165 memmove (contents + dest, contents + src, len);
2166 sec->size -= sec->relax[i].size;
2167 dest += len;
2168 }
2169
2170 elf_section_data (sec)->relocs = internal_relocs;
2171 free_relocs = NULL;
2172
2173 elf_section_data (sec)->this_hdr.contents = contents;
2174 free_contents = NULL;
2175
2176 symtab_hdr->contents = (bfd_byte *) isymbuf;
2177 }
2178
2179 if (free_relocs != NULL)
2180 {
2181 free (free_relocs);
2182 free_relocs = NULL;
2183 }
2184
2185 if (free_contents != NULL)
2186 {
2187 if (!link_info->keep_memory)
2188 free (free_contents);
2189 else
2190 /* Cache the section contents for elf_link_input_bfd. */
2191 elf_section_data (sec)->this_hdr.contents = contents;
2192 free_contents = NULL;
2193 }
2194
2195 if (sec->relax_count == 0)
2196 {
f23200ad 2197 *again = FALSE;
7ba29e2a
NC
2198 free (sec->relax);
2199 sec->relax = NULL;
2200 }
f23200ad
ME
2201 else
2202 *again = TRUE;
7ba29e2a
NC
2203 return TRUE;
2204
2205 error_return:
2206 if (free_relocs != NULL)
2207 free (free_relocs);
2208 if (free_contents != NULL)
2209 free (free_contents);
2210 if (sec->relax != NULL)
2211 {
2212 free (sec->relax);
2213 sec->relax = NULL;
2214 sec->relax_count = 0;
2215 }
2216 return FALSE;
2217}
2218
2219/* Return the section that should be marked against GC for a given
2220 relocation. */
2221
2222static asection *
2223microblaze_elf_gc_mark_hook (asection *sec,
fb34365b 2224 struct bfd_link_info * info,
7ba29e2a
NC
2225 Elf_Internal_Rela * rel,
2226 struct elf_link_hash_entry * h,
2227 Elf_Internal_Sym * sym)
2228{
2229 if (h != NULL)
fb34365b
AM
2230 switch (ELF32_R_TYPE (rel->r_info))
2231 {
2232 case R_MICROBLAZE_GNU_VTINHERIT:
2233 case R_MICROBLAZE_GNU_VTENTRY:
2234 return NULL;
2235 }
2236
2237 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
7ba29e2a
NC
2238}
2239
2240/* Update the got entry reference counts for the section being removed. */
2241
2242static bfd_boolean
2243microblaze_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
2244 struct bfd_link_info * info ATTRIBUTE_UNUSED,
2245 asection * sec ATTRIBUTE_UNUSED,
2246 const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
2247{
2248 return TRUE;
2249}
2250
2251/* PIC support. */
2252
2253#define PLT_ENTRY_SIZE 16
2254
2255#define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
2256#define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
2257#define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
2258#define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
2259#define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
2260
2261/* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
2262 shortcuts to them in our hash table. */
2263
2264static bfd_boolean
2265create_got_section (bfd *dynobj, struct bfd_link_info *info)
2266{
2267 struct elf32_mb_link_hash_table *htab;
2268
2269 if (! _bfd_elf_create_got_section (dynobj, info))
2270 return FALSE;
2271 htab = elf32_mb_hash_table (info);
4dfe6ac6
NC
2272 if (htab == NULL)
2273 return FALSE;
2274
3d4d4302
AM
2275 htab->sgot = bfd_get_linker_section (dynobj, ".got");
2276 htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
7ba29e2a
NC
2277 if (!htab->sgot || !htab->sgotplt)
2278 return FALSE;
2279
3d4d4302
AM
2280 if ((htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got")) == NULL)
2281 htab->srelgot = bfd_make_section_anyway (dynobj, ".rela.got");
7ba29e2a
NC
2282 if (htab->srelgot == NULL
2283 || ! bfd_set_section_flags (dynobj, htab->srelgot, SEC_ALLOC
2284 | SEC_LOAD
2285 | SEC_HAS_CONTENTS
2286 | SEC_IN_MEMORY
2287 | SEC_LINKER_CREATED
2288 | SEC_READONLY)
2289 || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
2290 return FALSE;
2291 return TRUE;
2292}
2293
69b06cc8
ME
2294static bfd_boolean
2295update_local_sym_info (bfd *abfd,
2296 Elf_Internal_Shdr *symtab_hdr,
2297 unsigned long r_symndx,
2298 unsigned int tls_type)
2299{
2300 bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
2301 unsigned char *local_got_tls_masks;
2302
2303 if (local_got_refcounts == NULL)
2304 {
2305 bfd_size_type size = symtab_hdr->sh_info;
2306
2307 size *= (sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks));
2308 local_got_refcounts = bfd_zalloc (abfd, size);
2309 if (local_got_refcounts == NULL)
2310 return FALSE;
2311 elf_local_got_refcounts (abfd) = local_got_refcounts;
2312 }
2313
2314 local_got_tls_masks =
2315 (unsigned char *) (local_got_refcounts + symtab_hdr->sh_info);
2316 local_got_tls_masks[r_symndx] |= tls_type;
2317 local_got_refcounts[r_symndx] += 1;
2318
2319 return TRUE;
2320}
7ba29e2a
NC
2321/* Look through the relocs for a section during the first phase. */
2322
2323static bfd_boolean
2324microblaze_elf_check_relocs (bfd * abfd,
2325 struct bfd_link_info * info,
2326 asection * sec,
2327 const Elf_Internal_Rela * relocs)
2328{
2329 Elf_Internal_Shdr * symtab_hdr;
2330 struct elf_link_hash_entry ** sym_hashes;
2331 struct elf_link_hash_entry ** sym_hashes_end;
2332 const Elf_Internal_Rela * rel;
2333 const Elf_Internal_Rela * rel_end;
2334 struct elf32_mb_link_hash_table *htab;
7ba29e2a
NC
2335 asection *sreloc = NULL;
2336
0e1862bb 2337 if (bfd_link_relocatable (info))
7ba29e2a
NC
2338 return TRUE;
2339
2340 htab = elf32_mb_hash_table (info);
4dfe6ac6
NC
2341 if (htab == NULL)
2342 return FALSE;
2343
7ba29e2a
NC
2344 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
2345 sym_hashes = elf_sym_hashes (abfd);
2346 sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
2347 if (!elf_bad_symtab (abfd))
2348 sym_hashes_end -= symtab_hdr->sh_info;
2349
2350 rel_end = relocs + sec->reloc_count;
2351
2352 for (rel = relocs; rel < rel_end; rel++)
2353 {
2354 unsigned int r_type;
2355 struct elf_link_hash_entry * h;
2356 unsigned long r_symndx;
69b06cc8 2357 unsigned char tls_type = 0;
7ba29e2a
NC
2358
2359 r_symndx = ELF32_R_SYM (rel->r_info);
2360 r_type = ELF32_R_TYPE (rel->r_info);
2361
2362 if (r_symndx < symtab_hdr->sh_info)
2363 h = NULL;
2364 else
81fbe831
AM
2365 {
2366 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
2367
2368 /* PR15323, ref flags aren't set for references in the same
2369 object. */
2370 h->root.non_ir_ref = 1;
2371 }
7ba29e2a
NC
2372
2373 switch (r_type)
2374 {
2375 /* This relocation describes the C++ object vtable hierarchy.
2376 Reconstruct it for later use during GC. */
2377 case R_MICROBLAZE_GNU_VTINHERIT:
2378 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2379 return FALSE;
2380 break;
2381
2382 /* This relocation describes which C++ vtable entries are actually
2383 used. Record for later use during GC. */
2384 case R_MICROBLAZE_GNU_VTENTRY:
2385 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
2386 return FALSE;
2387 break;
2388
2389 /* This relocation requires .plt entry. */
2390 case R_MICROBLAZE_PLT_64:
2391 if (h != NULL)
2392 {
2393 h->needs_plt = 1;
2394 h->plt.refcount += 1;
2395 }
2396 break;
2397
2398 /* This relocation requires .got entry. */
69b06cc8
ME
2399 case R_MICROBLAZE_TLSGD:
2400 tls_type |= (TLS_TLS | TLS_GD);
2401 goto dogottls;
2402 case R_MICROBLAZE_TLSLD:
2403 tls_type |= (TLS_TLS | TLS_LD);
2404 dogottls:
2405 sec->has_tls_reloc = 1;
7ba29e2a
NC
2406 case R_MICROBLAZE_GOT_64:
2407 if (htab->sgot == NULL)
2408 {
2409 if (htab->elf.dynobj == NULL)
2410 htab->elf.dynobj = abfd;
2411 if (!create_got_section (htab->elf.dynobj, info))
2412 return FALSE;
2413 }
2414 if (h != NULL)
2415 {
2416 h->got.refcount += 1;
69b06cc8 2417 elf32_mb_hash_entry (h)->tls_mask |= tls_type;
7ba29e2a
NC
2418 }
2419 else
2420 {
69b06cc8
ME
2421 if (! update_local_sym_info(abfd, symtab_hdr, r_symndx, tls_type) )
2422 return FALSE;
7ba29e2a
NC
2423 }
2424 break;
2425
2426 case R_MICROBLAZE_64:
2427 case R_MICROBLAZE_64_PCREL:
2428 case R_MICROBLAZE_32:
2429 {
0e1862bb 2430 if (h != NULL && !bfd_link_pic (info))
7ba29e2a
NC
2431 {
2432 /* we may need a copy reloc. */
2433 h->non_got_ref = 1;
2434
2435 /* we may also need a .plt entry. */
2436 h->plt.refcount += 1;
2437 if (ELF32_R_TYPE (rel->r_info) != R_MICROBLAZE_64_PCREL)
2438 h->pointer_equality_needed = 1;
2439 }
2440
2441
2442 /* If we are creating a shared library, and this is a reloc
2443 against a global symbol, or a non PC relative reloc
2444 against a local symbol, then we need to copy the reloc
2445 into the shared library. However, if we are linking with
2446 -Bsymbolic, we do not need to copy a reloc against a
2447 global symbol which is defined in an object we are
2448 including in the link (i.e., DEF_REGULAR is set). At
2449 this point we have not seen all the input files, so it is
2450 possible that DEF_REGULAR is not set now but will be set
2451 later (it is never cleared). In case of a weak definition,
2452 DEF_REGULAR may be cleared later by a strong definition in
2453 a shared library. We account for that possibility below by
2454 storing information in the relocs_copied field of the hash
2455 table entry. A similar situation occurs when creating
2456 shared libraries and symbol visibility changes render the
2457 symbol local.
2458
2459 If on the other hand, we are creating an executable, we
2460 may need to keep relocations for symbols satisfied by a
2461 dynamic library if we manage to avoid copy relocs for the
2462 symbol. */
2463
0e1862bb 2464 if ((bfd_link_pic (info)
7ba29e2a
NC
2465 && (sec->flags & SEC_ALLOC) != 0
2466 && (r_type != R_MICROBLAZE_64_PCREL
2467 || (h != NULL
2468 && (! info->symbolic
2469 || h->root.type == bfd_link_hash_defweak
2470 || !h->def_regular))))
0e1862bb 2471 || (!bfd_link_pic (info)
7ba29e2a
NC
2472 && (sec->flags & SEC_ALLOC) != 0
2473 && h != NULL
2474 && (h->root.type == bfd_link_hash_defweak
2475 || !h->def_regular)))
2476 {
2477 struct elf32_mb_dyn_relocs *p;
2478 struct elf32_mb_dyn_relocs **head;
2479
2480 /* When creating a shared object, we must copy these
2481 relocs into the output file. We create a reloc
2482 section in dynobj and make room for the reloc. */
2483
2484 if (sreloc == NULL)
2485 {
7ba29e2a 2486 bfd *dynobj;
7ba29e2a
NC
2487
2488 if (htab->elf.dynobj == NULL)
2489 htab->elf.dynobj = abfd;
2490 dynobj = htab->elf.dynobj;
2491
69b06cc8
ME
2492 sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
2493 2, abfd, 1);
7ba29e2a 2494 if (sreloc == NULL)
69b06cc8 2495 return FALSE;
7ba29e2a
NC
2496 }
2497
2498 /* If this is a global symbol, we count the number of
2499 relocations we need for this symbol. */
2500 if (h != NULL)
2501 head = &((struct elf32_mb_link_hash_entry *) h)->dyn_relocs;
2502 else
2503 {
2504 /* Track dynamic relocs needed for local syms too.
2505 We really need local syms available to do this
2506 easily. Oh well. */
2507
2508 asection *s;
2509 Elf_Internal_Sym *isym;
918d9742 2510 void *vpp;
7ba29e2a
NC
2511
2512 isym = bfd_sym_from_r_symndx (&htab->sym_sec,
2513 abfd, r_symndx);
2514 if (isym == NULL)
2515 return FALSE;
2516
2517 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2518 if (s == NULL)
2519 return FALSE;
2520
918d9742
TT
2521 vpp = &elf_section_data (s)->local_dynrel;
2522 head = (struct elf32_mb_dyn_relocs **) vpp;
7ba29e2a
NC
2523 }
2524
2525 p = *head;
2526 if (p == NULL || p->sec != sec)
2527 {
2528 bfd_size_type amt = sizeof *p;
2529 p = ((struct elf32_mb_dyn_relocs *)
2530 bfd_alloc (htab->elf.dynobj, amt));
2531 if (p == NULL)
2532 return FALSE;
2533 p->next = *head;
2534 *head = p;
2535 p->sec = sec;
2536 p->count = 0;
2537 p->pc_count = 0;
2538 }
2539
2540 p->count += 1;
2541 if (r_type == R_MICROBLAZE_64_PCREL)
2542 p->pc_count += 1;
2543 }
2544 }
2545 break;
2546 }
2547 }
2548
2549 return TRUE;
2550}
2551
2552static bfd_boolean
2553microblaze_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
2554{
2555 struct elf32_mb_link_hash_table *htab;
2556
2557 htab = elf32_mb_hash_table (info);
4dfe6ac6
NC
2558 if (htab == NULL)
2559 return FALSE;
2560
7ba29e2a
NC
2561 if (!htab->sgot && !create_got_section (dynobj, info))
2562 return FALSE;
2563
2564 if (!_bfd_elf_create_dynamic_sections (dynobj, info))
2565 return FALSE;
2566
3d4d4302
AM
2567 htab->splt = bfd_get_linker_section (dynobj, ".plt");
2568 htab->srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
2569 htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
0e1862bb 2570 if (!bfd_link_pic (info))
3d4d4302 2571 htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
7ba29e2a
NC
2572
2573 if (!htab->splt || !htab->srelplt || !htab->sdynbss
0e1862bb 2574 || (!bfd_link_pic (info) && !htab->srelbss))
7ba29e2a
NC
2575 abort ();
2576
2577 return TRUE;
2578}
2579
2580/* Copy the extra info we tack onto an elf_link_hash_entry. */
2581
2582static void
2583microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
2584 struct elf_link_hash_entry *dir,
2585 struct elf_link_hash_entry *ind)
2586{
2587 struct elf32_mb_link_hash_entry *edir, *eind;
2588
2589 edir = (struct elf32_mb_link_hash_entry *) dir;
2590 eind = (struct elf32_mb_link_hash_entry *) ind;
2591
2592 if (eind->dyn_relocs != NULL)
2593 {
2594 if (edir->dyn_relocs != NULL)
2595 {
2596 struct elf32_mb_dyn_relocs **pp;
2597 struct elf32_mb_dyn_relocs *p;
2598
2599 if (ind->root.type == bfd_link_hash_indirect)
2600 abort ();
2601
2602 /* Add reloc counts against the weak sym to the strong sym
2603 list. Merge any entries against the same section. */
2604 for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
2605 {
2606 struct elf32_mb_dyn_relocs *q;
2607
2608 for (q = edir->dyn_relocs; q != NULL; q = q->next)
2609 if (q->sec == p->sec)
2610 {
2611 q->pc_count += p->pc_count;
2612 q->count += p->count;
2613 *pp = p->next;
2614 break;
2615 }
2616 if (q == NULL)
2617 pp = &p->next;
2618 }
2619 *pp = edir->dyn_relocs;
2620 }
2621
2622 edir->dyn_relocs = eind->dyn_relocs;
2623 eind->dyn_relocs = NULL;
2624 }
2625
69b06cc8
ME
2626 edir->tls_mask |= eind->tls_mask;
2627
7ba29e2a
NC
2628 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
2629}
2630
2631static bfd_boolean
2632microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2633 struct elf_link_hash_entry *h)
2634{
2635 struct elf32_mb_link_hash_table *htab;
2636 struct elf32_mb_link_hash_entry * eh;
2637 struct elf32_mb_dyn_relocs *p;
2638 asection *sdynbss, *s;
2639 unsigned int power_of_two;
2640 bfd *dynobj;
2641
2642 htab = elf32_mb_hash_table (info);
4dfe6ac6
NC
2643 if (htab == NULL)
2644 return FALSE;
7ba29e2a
NC
2645
2646 /* If this is a function, put it in the procedure linkage table. We
2647 will fill in the contents of the procedure linkage table later,
2648 when we know the address of the .got section. */
2649 if (h->type == STT_FUNC
2650 || h->needs_plt)
2651 {
2652 if (h->plt.refcount <= 0
2653 || SYMBOL_CALLS_LOCAL (info, h)
2654 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
2655 && h->root.type == bfd_link_hash_undefweak))
2656 {
2657 /* This case can occur if we saw a PLT reloc in an input
2658 file, but the symbol was never referred to by a dynamic
2659 object, or if all references were garbage collected. In
2660 such a case, we don't actually need to build a procedure
2661 linkage table, and we can just do a PC32 reloc instead. */
2662 h->plt.offset = (bfd_vma) -1;
2663 h->needs_plt = 0;
2664 }
2665
2666 return TRUE;
2667 }
2668 else
2669 /* It's possible that we incorrectly decided a .plt reloc was
2670 needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
2671 check_relocs. We can't decide accurately between function and
2672 non-function syms in check-relocs; Objects loaded later in
2673 the link may change h->type. So fix it now. */
2674 h->plt.offset = (bfd_vma) -1;
2675
2676 /* If this is a weak symbol, and there is a real definition, the
2677 processor independent code will have arranged for us to see the
2678 real definition first, and we can just use the same value. */
2679 if (h->u.weakdef != NULL)
2680 {
2681 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2682 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2683 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2684 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2685 return TRUE;
2686 }
2687
2688 /* This is a reference to a symbol defined by a dynamic object which
2689 is not a function. */
2690
2691 /* If we are creating a shared library, we must presume that the
2692 only references to the symbol are via the global offset table.
2693 For such cases we need not do anything here; the relocations will
2694 be handled correctly by relocate_section. */
0e1862bb 2695 if (bfd_link_pic (info))
7ba29e2a
NC
2696 return TRUE;
2697
2698 /* If there are no references to this symbol that do not use the
2699 GOT, we don't need to generate a copy reloc. */
2700 if (!h->non_got_ref)
2701 return TRUE;
2702
2703 /* If -z nocopyreloc was given, we won't generate them either. */
2704 if (info->nocopyreloc)
2705 {
2706 h->non_got_ref = 0;
2707 return TRUE;
2708 }
2709
2710 eh = (struct elf32_mb_link_hash_entry *) h;
2711 for (p = eh->dyn_relocs; p != NULL; p = p->next)
2712 {
2713 s = p->sec->output_section;
2714 if (s != NULL && (s->flags & SEC_READONLY) != 0)
2715 break;
2716 }
2717
2718 /* If we didn't find any dynamic relocs in read-only sections, then
2719 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
2720 if (p == NULL)
2721 {
2722 h->non_got_ref = 0;
2723 return TRUE;
2724 }
2725
2726 /* We must allocate the symbol in our .dynbss section, which will
2727 become part of the .bss section of the executable. There will be
2728 an entry for this symbol in the .dynsym section. The dynamic
2729 object will contain position independent code, so all references
2730 from the dynamic object to this symbol will go through the global
2731 offset table. The dynamic linker will use the .dynsym entry to
2732 determine the address it must put in the global offset table, so
2733 both the dynamic object and the regular object will refer to the
2734 same memory location for the variable. */
2735
2736 /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
2737 to copy the initial value out of the dynamic object and into the
2738 runtime process image. */
2739 dynobj = elf_hash_table (info)->dynobj;
2740 BFD_ASSERT (dynobj != NULL);
2741 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2742 {
2743 htab->srelbss->size += sizeof (Elf32_External_Rela);
2744 h->needs_copy = 1;
2745 }
2746
2747 /* We need to figure out the alignment required for this symbol. I
2748 have no idea how ELF linkers handle this. */
2749 power_of_two = bfd_log2 (h->size);
2750 if (power_of_two > 3)
2751 power_of_two = 3;
2752
2753 sdynbss = htab->sdynbss;
2754 /* Apply the required alignment. */
2755 sdynbss->size = BFD_ALIGN (sdynbss->size, (bfd_size_type) (1 << power_of_two));
2756 if (power_of_two > bfd_get_section_alignment (dynobj, sdynbss))
2757 {
2758 if (! bfd_set_section_alignment (dynobj, sdynbss, power_of_two))
2759 return FALSE;
2760 }
2761
2762 /* Define the symbol as being at this point in the section. */
2763 h->root.u.def.section = sdynbss;
2764 h->root.u.def.value = sdynbss->size;
2765
2766 /* Increment the section size to make room for the symbol. */
2767 sdynbss->size += h->size;
2768 return TRUE;
2769}
2770
2771/* Allocate space in .plt, .got and associated reloc sections for
2772 dynamic relocs. */
2773
2774static bfd_boolean
2775allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
2776{
2777 struct bfd_link_info *info;
2778 struct elf32_mb_link_hash_table *htab;
2779 struct elf32_mb_link_hash_entry *eh;
2780 struct elf32_mb_dyn_relocs *p;
2781
2782 if (h->root.type == bfd_link_hash_indirect)
2783 return TRUE;
2784
7ba29e2a
NC
2785 info = (struct bfd_link_info *) dat;
2786 htab = elf32_mb_hash_table (info);
4dfe6ac6
NC
2787 if (htab == NULL)
2788 return FALSE;
7ba29e2a
NC
2789
2790 if (htab->elf.dynamic_sections_created
2791 && h->plt.refcount > 0)
2792 {
2793 /* Make sure this symbol is output as a dynamic symbol.
2794 Undefined weak syms won't yet be marked as dynamic. */
2795 if (h->dynindx == -1
2796 && !h->forced_local)
2797 {
2798 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2799 return FALSE;
2800 }
2801
0e1862bb 2802 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
7ba29e2a
NC
2803 {
2804 asection *s = htab->splt;
2805
2806 /* The first entry in .plt is reserved. */
2807 if (s->size == 0)
2808 s->size = PLT_ENTRY_SIZE;
2809
2810 h->plt.offset = s->size;
2811
2812 /* If this symbol is not defined in a regular file, and we are
2813 not generating a shared library, then set the symbol to this
2814 location in the .plt. This is required to make function
2815 pointers compare as equal between the normal executable and
2816 the shared library. */
0e1862bb 2817 if (! bfd_link_pic (info)
7ba29e2a
NC
2818 && !h->def_regular)
2819 {
2820 h->root.u.def.section = s;
2821 h->root.u.def.value = h->plt.offset;
2822 }
2823
2824 /* Make room for this entry. */
2825 s->size += PLT_ENTRY_SIZE;
2826
2827 /* We also need to make an entry in the .got.plt section, which
2828 will be placed in the .got section by the linker script. */
2829 htab->sgotplt->size += 4;
2830
2831 /* We also need to make an entry in the .rel.plt section. */
2832 htab->srelplt->size += sizeof (Elf32_External_Rela);
2833 }
2834 else
2835 {
2836 h->plt.offset = (bfd_vma) -1;
2837 h->needs_plt = 0;
2838 }
2839 }
2840 else
2841 {
2842 h->plt.offset = (bfd_vma) -1;
2843 h->needs_plt = 0;
2844 }
2845
69b06cc8 2846 eh = (struct elf32_mb_link_hash_entry *) h;
7ba29e2a
NC
2847 if (h->got.refcount > 0)
2848 {
69b06cc8 2849 unsigned int need;
7ba29e2a
NC
2850 asection *s;
2851
2852 /* Make sure this symbol is output as a dynamic symbol.
2853 Undefined weak syms won't yet be marked as dynamic. */
2854 if (h->dynindx == -1
2855 && !h->forced_local)
2856 {
2857 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2858 return FALSE;
2859 }
2860
69b06cc8
ME
2861 need = 0;
2862 if ((eh->tls_mask & TLS_TLS) != 0)
2863 {
2864 /* Handle TLS Symbol */
2865 if ((eh->tls_mask & TLS_LD) != 0)
2866 {
2867 if (!eh->elf.def_dynamic)
2868 /* We'll just use htab->tlsld_got.offset. This should
2869 always be the case. It's a little odd if we have
2870 a local dynamic reloc against a non-local symbol. */
2871 htab->tlsld_got.refcount += 1;
2872 else
2873 need += 8;
2874 }
2875 if ((eh->tls_mask & TLS_GD) != 0)
2876 need += 8;
2877 }
2878 else
2879 {
2880 /* Regular (non-TLS) symbol */
2881 need += 4;
2882 }
2883 if (need == 0)
2884 {
2885 h->got.offset = (bfd_vma) -1;
2886 }
2887 else
2888 {
2889 s = htab->sgot;
2890 h->got.offset = s->size;
2891 s->size += need;
2892 htab->srelgot->size += need * (sizeof (Elf32_External_Rela) / 4);
2893 }
7ba29e2a
NC
2894 }
2895 else
2896 h->got.offset = (bfd_vma) -1;
2897
7ba29e2a
NC
2898 if (eh->dyn_relocs == NULL)
2899 return TRUE;
2900
2901 /* In the shared -Bsymbolic case, discard space allocated for
2902 dynamic pc-relative relocs against symbols which turn out to be
2903 defined in regular objects. For the normal shared case, discard
2904 space for pc-relative relocs that have become local due to symbol
2905 visibility changes. */
2906
0e1862bb 2907 if (bfd_link_pic (info))
7ba29e2a
NC
2908 {
2909 if (h->def_regular
2910 && (h->forced_local
2911 || info->symbolic))
2912 {
2913 struct elf32_mb_dyn_relocs **pp;
2914
2915 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
2916 {
2917 p->count -= p->pc_count;
2918 p->pc_count = 0;
2919 if (p->count == 0)
2920 *pp = p->next;
2921 else
2922 pp = &p->next;
2923 }
2924 }
2925 }
2926 else
2927 {
2928 /* For the non-shared case, discard space for relocs against
2929 symbols which turn out to need copy relocs or are not
2930 dynamic. */
2931
2932 if (!h->non_got_ref
2933 && ((h->def_dynamic
2934 && !h->def_regular)
2935 || (htab->elf.dynamic_sections_created
2936 && (h->root.type == bfd_link_hash_undefweak
2937 || h->root.type == bfd_link_hash_undefined))))
2938 {
2939 /* Make sure this symbol is output as a dynamic symbol.
2940 Undefined weak syms won't yet be marked as dynamic. */
2941 if (h->dynindx == -1
2942 && !h->forced_local)
2943 {
2944 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2945 return FALSE;
2946 }
2947
2948 /* If that succeeded, we know we'll be keeping all the
2949 relocs. */
2950 if (h->dynindx != -1)
2951 goto keep;
2952 }
2953
2954 eh->dyn_relocs = NULL;
2955
2956 keep: ;
2957 }
2958
2959 /* Finally, allocate space. */
2960 for (p = eh->dyn_relocs; p != NULL; p = p->next)
2961 {
2962 asection *sreloc = elf_section_data (p->sec)->sreloc;
2963 sreloc->size += p->count * sizeof (Elf32_External_Rela);
2964 }
2965
2966 return TRUE;
2967}
2968
2969/* Set the sizes of the dynamic sections. */
2970
2971static bfd_boolean
2972microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2973 struct bfd_link_info *info)
2974{
2975 struct elf32_mb_link_hash_table *htab;
2976 bfd *dynobj;
2977 asection *s;
2978 bfd *ibfd;
2979
2980 htab = elf32_mb_hash_table (info);
4dfe6ac6
NC
2981 if (htab == NULL)
2982 return FALSE;
2983
7ba29e2a
NC
2984 dynobj = htab->elf.dynobj;
2985 BFD_ASSERT (dynobj != NULL);
2986
2987 /* Set up .got offsets for local syms, and space for local dynamic
2988 relocs. */
c72f2fb2 2989 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
7ba29e2a
NC
2990 {
2991 bfd_signed_vma *local_got;
2992 bfd_signed_vma *end_local_got;
2993 bfd_size_type locsymcount;
2994 Elf_Internal_Shdr *symtab_hdr;
69b06cc8 2995 unsigned char *lgot_masks;
7ba29e2a
NC
2996 asection *srel;
2997
2998 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
2999 continue;
3000
3001 for (s = ibfd->sections; s != NULL; s = s->next)
3002 {
3003 struct elf32_mb_dyn_relocs *p;
3004
3005 for (p = ((struct elf32_mb_dyn_relocs *)
3006 elf_section_data (s)->local_dynrel);
3007 p != NULL;
3008 p = p->next)
3009 {
3010 if (!bfd_is_abs_section (p->sec)
3011 && bfd_is_abs_section (p->sec->output_section))
3012 {
3013 /* Input section has been discarded, either because
3014 it is a copy of a linkonce section or due to
3015 linker script /DISCARD/, so we'll be discarding
3016 the relocs too. */
3017 }
3018 else if (p->count != 0)
3019 {
3020 srel = elf_section_data (p->sec)->sreloc;
3021 srel->size += p->count * sizeof (Elf32_External_Rela);
3022 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
3023 info->flags |= DF_TEXTREL;
3024 }
3025 }
3026 }
3027
3028 local_got = elf_local_got_refcounts (ibfd);
3029 if (!local_got)
3030 continue;
3031
3032 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
3033 locsymcount = symtab_hdr->sh_info;
3034 end_local_got = local_got + locsymcount;
69b06cc8 3035 lgot_masks = (unsigned char *) end_local_got;
7ba29e2a
NC
3036 s = htab->sgot;
3037 srel = htab->srelgot;
3038
69b06cc8
ME
3039 for (; local_got < end_local_got; ++local_got, ++lgot_masks)
3040 {
3041 if (*local_got > 0)
3042 {
3043 unsigned int need = 0;
3044 if ((*lgot_masks & TLS_TLS) != 0)
3045 {
3046 if ((*lgot_masks & TLS_GD) != 0)
3047 need += 8;
3048 if ((*lgot_masks & TLS_LD) != 0)
3049 htab->tlsld_got.refcount += 1;
3050 }
3051 else
3052 need += 4;
3053
3054 if (need == 0)
3055 {
3056 *local_got = (bfd_vma) -1;
3057 }
3058 else
3059 {
3060 *local_got = s->size;
3061 s->size += need;
0e1862bb 3062 if (bfd_link_pic (info))
69b06cc8
ME
3063 srel->size += need * (sizeof (Elf32_External_Rela) / 4);
3064 }
7ba29e2a
NC
3065 }
3066 else
3067 *local_got = (bfd_vma) -1;
3068 }
3069 }
3070
3071 /* Allocate global sym .plt and .got entries, and space for global
3072 sym dynamic relocs. */
3073 elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
3074
69b06cc8
ME
3075 if (htab->tlsld_got.refcount > 0)
3076 {
3077 htab->tlsld_got.offset = htab->sgot->size;
3078 htab->sgot->size += 8;
0e1862bb 3079 if (bfd_link_pic (info))
69b06cc8
ME
3080 htab->srelgot->size += sizeof (Elf32_External_Rela);
3081 }
3082 else
3083 htab->tlsld_got.offset = (bfd_vma) -1;
3084
7ba29e2a
NC
3085 if (elf_hash_table (info)->dynamic_sections_created)
3086 {
3087 /* Make space for the trailing nop in .plt. */
3088 if (htab->splt->size > 0)
3089 htab->splt->size += 4;
3090 }
3091
3092 /* The check_relocs and adjust_dynamic_symbol entry points have
3093 determined the sizes of the various dynamic sections. Allocate
3094 memory for them. */
3095 for (s = dynobj->sections; s != NULL; s = s->next)
3096 {
3097 const char *name;
3098 bfd_boolean strip = FALSE;
3099
3100 if ((s->flags & SEC_LINKER_CREATED) == 0)
3101 continue;
3102
3103 /* It's OK to base decisions on the section name, because none
3104 of the dynobj section names depend upon the input files. */
3105 name = bfd_get_section_name (dynobj, s);
3106
3107 if (strncmp (name, ".rela", 5) == 0)
3108 {
3109 if (s->size == 0)
3110 {
3111 /* If we don't need this section, strip it from the
3112 output file. This is to handle .rela.bss and
3113 .rela.plt. We must create it in
3114 create_dynamic_sections, because it must be created
3115 before the linker maps input sections to output
3116 sections. The linker does that before
3117 adjust_dynamic_symbol is called, and it is that
3118 function which decides whether anything needs to go
3119 into these sections. */
3120 strip = TRUE;
3121 }
3122 else
3123 {
3124 /* We use the reloc_count field as a counter if we need
3125 to copy relocs into the output file. */
3126 s->reloc_count = 0;
3127 }
3128 }
3129 else if (s != htab->splt && s != htab->sgot && s != htab->sgotplt)
3130 {
3131 /* It's not one of our sections, so don't allocate space. */
3132 continue;
3133 }
3134
3135 if (strip)
3136 {
3137 s->flags |= SEC_EXCLUDE;
3138 continue;
3139 }
3140
3141 /* Allocate memory for the section contents. */
3142 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
3143 Unused entries should be reclaimed before the section's contents
3144 are written out, but at the moment this does not happen. Thus in
3145 order to prevent writing out garbage, we initialise the section's
3146 contents to zero. */
3147 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
3148 if (s->contents == NULL && s->size != 0)
3149 return FALSE;
3150 }
3151
3152 if (elf_hash_table (info)->dynamic_sections_created)
3153 {
3154 /* Add some entries to the .dynamic section. We fill in the
3155 values later, in microblaze_elf_finish_dynamic_sections, but we
3156 must add the entries now so that we get the correct size for
3157 the .dynamic section. The DT_DEBUG entry is filled in by the
3158 dynamic linker and used by the debugger. */
3159#define add_dynamic_entry(TAG, VAL) \
3160 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3161
0e1862bb 3162 if (bfd_link_executable (info))
7ba29e2a
NC
3163 {
3164 if (!add_dynamic_entry (DT_DEBUG, 0))
3165 return FALSE;
3166 }
3167
3168 if (!add_dynamic_entry (DT_RELA, 0)
3169 || !add_dynamic_entry (DT_RELASZ, 0)
3170 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
3171 return FALSE;
3172
3173 if (htab->splt->size != 0)
3174 {
3175 if (!add_dynamic_entry (DT_PLTGOT, 0)
3176 || !add_dynamic_entry (DT_PLTRELSZ, 0)
3177 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3178 || !add_dynamic_entry (DT_JMPREL, 0)
3179 || !add_dynamic_entry (DT_BIND_NOW, 1))
3180 return FALSE;
3181 }
3182
3183 if (info->flags & DF_TEXTREL)
3184 {
3185 if (!add_dynamic_entry (DT_TEXTREL, 0))
3186 return FALSE;
3187 }
3188 }
3189#undef add_dynamic_entry
3190 return TRUE;
3191}
3192
3193/* Finish up dynamic symbol handling. We set the contents of various
3194 dynamic sections here. */
3195
3196static bfd_boolean
3197microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
3198 struct bfd_link_info *info,
3199 struct elf_link_hash_entry *h,
3200 Elf_Internal_Sym *sym)
3201{
7ba29e2a 3202 struct elf32_mb_link_hash_table *htab;
69b06cc8 3203 struct elf32_mb_link_hash_entry *eh = elf32_mb_hash_entry(h);
7ba29e2a
NC
3204
3205 htab = elf32_mb_hash_table (info);
4dfe6ac6
NC
3206 if (htab == NULL)
3207 return FALSE;
3208
7ba29e2a
NC
3209 if (h->plt.offset != (bfd_vma) -1)
3210 {
3211 asection *splt;
3212 asection *srela;
3213 asection *sgotplt;
3214 Elf_Internal_Rela rela;
3215 bfd_byte *loc;
3216 bfd_vma plt_index;
3217 bfd_vma got_offset;
3218 bfd_vma got_addr;
3219
3220 /* This symbol has an entry in the procedure linkage table. Set
3221 it up. */
3222 BFD_ASSERT (h->dynindx != -1);
3223
3224 splt = htab->splt;
3225 srela = htab->srelplt;
3226 sgotplt = htab->sgotplt;
3227 BFD_ASSERT (splt != NULL && srela != NULL && sgotplt != NULL);
3228
3229 plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* first entry reserved. */
3230 got_offset = (plt_index + 3) * 4; /* 3 reserved ??? */
3231 got_addr = got_offset;
3232
3233 /* For non-PIC objects we need absolute address of the GOT entry. */
0e1862bb 3234 if (!bfd_link_pic (info))
7ba29e2a
NC
3235 got_addr += htab->sgotplt->output_section->vma + sgotplt->output_offset;
3236
3237 /* Fill in the entry in the procedure linkage table. */
3238 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_0 + ((got_addr >> 16) & 0xffff),
3239 splt->contents + h->plt.offset);
0e1862bb 3240 if (bfd_link_pic (info))
7ba29e2a
NC
3241 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1 + (got_addr & 0xffff),
3242 splt->contents + h->plt.offset + 4);
3243 else
3244 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1_NOPIC + (got_addr & 0xffff),
3245 splt->contents + h->plt.offset + 4);
3246 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_2,
3247 splt->contents + h->plt.offset + 8);
3248 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_3,
3249 splt->contents + h->plt.offset + 12);
3250
3251 /* Any additions to the .got section??? */
3252 /* bfd_put_32 (output_bfd,
3253 splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
3254 sgotplt->contents + got_offset); */
3255
3256 /* Fill in the entry in the .rela.plt section. */
3257 rela.r_offset = (sgotplt->output_section->vma
3258 + sgotplt->output_offset
3259 + got_offset);
3260 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_JUMP_SLOT);
3261 rela.r_addend = 0;
3262 loc = srela->contents;
3263 loc += plt_index * sizeof (Elf32_External_Rela);
3264 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
3265
3266 if (!h->def_regular)
3267 {
3268 /* Mark the symbol as undefined, rather than as defined in
3269 the .plt section. Zero the value. */
3270 sym->st_shndx = SHN_UNDEF;
3271 sym->st_value = 0;
3272 }
3273 }
3274
69b06cc8
ME
3275 /* h->got.refcount to be checked ? */
3276 if (h->got.offset != (bfd_vma) -1 &&
3277 ! ((h->got.offset & 1) ||
3278 IS_TLS_LD(eh->tls_mask) || IS_TLS_GD(eh->tls_mask)))
7ba29e2a
NC
3279 {
3280 asection *sgot;
3281 asection *srela;
69b06cc8 3282 bfd_vma offset;
7ba29e2a
NC
3283
3284 /* This symbol has an entry in the global offset table. Set it
3285 up. */
3286
3287 sgot = htab->sgot;
3288 srela = htab->srelgot;
3289 BFD_ASSERT (sgot != NULL && srela != NULL);
3290
69b06cc8 3291 offset = (sgot->output_section->vma + sgot->output_offset
47993b4a 3292 + (h->got.offset &~ (bfd_vma) 1));
7ba29e2a
NC
3293
3294 /* If this is a -Bsymbolic link, and the symbol is defined
3295 locally, we just want to emit a RELATIVE reloc. Likewise if
3296 the symbol was forced to be local because of a version file.
3297 The entry in the global offset table will already have been
3298 initialized in the relocate_section function. */
0e1862bb 3299 if (bfd_link_pic (info)
47993b4a
RF
3300 && ((info->symbolic && h->def_regular)
3301 || h->dynindx == -1))
7ba29e2a
NC
3302 {
3303 asection *sec = h->root.u.def.section;
69b06cc8
ME
3304 microblaze_elf_output_dynamic_relocation (output_bfd,
3305 srela, srela->reloc_count++,
3306 /* symindex= */ 0,
3307 R_MICROBLAZE_REL, offset,
3308 h->root.u.def.value
3309 + sec->output_section->vma
3310 + sec->output_offset);
7ba29e2a
NC
3311 }
3312 else
3313 {
69b06cc8
ME
3314 microblaze_elf_output_dynamic_relocation (output_bfd,
3315 srela, srela->reloc_count++,
3316 h->dynindx,
3317 R_MICROBLAZE_GLOB_DAT,
3318 offset, 0);
7ba29e2a
NC
3319 }
3320
3321 bfd_put_32 (output_bfd, (bfd_vma) 0,
3322 sgot->contents + (h->got.offset &~ (bfd_vma) 1));
7ba29e2a
NC
3323 }
3324
3325 if (h->needs_copy)
3326 {
3327 asection *s;
3328 Elf_Internal_Rela rela;
3329 bfd_byte *loc;
3330
3331 /* This symbols needs a copy reloc. Set it up. */
3332
3333 BFD_ASSERT (h->dynindx != -1);
3334
3d4d4302 3335 s = bfd_get_linker_section (htab->elf.dynobj, ".rela.bss");
7ba29e2a
NC
3336 BFD_ASSERT (s != NULL);
3337
3338 rela.r_offset = (h->root.u.def.value
3339 + h->root.u.def.section->output_section->vma
3340 + h->root.u.def.section->output_offset);
3341 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_COPY);
3342 rela.r_addend = 0;
3343 loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
3344 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
3345 }
3346
3347 /* Mark some specially defined symbols as absolute. */
9637f6ef
L
3348 if (h == htab->elf.hdynamic
3349 || h == htab->elf.hgot
3350 || h == htab->elf.hplt)
7ba29e2a
NC
3351 sym->st_shndx = SHN_ABS;
3352
3353 return TRUE;
3354}
3355
3356
3357/* Finish up the dynamic sections. */
3358
3359static bfd_boolean
3360microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
3361 struct bfd_link_info *info)
3362{
3363 bfd *dynobj;
3364 asection *sdyn, *sgot;
3365 struct elf32_mb_link_hash_table *htab;
3366
3367 htab = elf32_mb_hash_table (info);
4dfe6ac6
NC
3368 if (htab == NULL)
3369 return FALSE;
3370
7ba29e2a
NC
3371 dynobj = htab->elf.dynobj;
3372
3d4d4302 3373 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
7ba29e2a
NC
3374
3375 if (htab->elf.dynamic_sections_created)
3376 {
3377 asection *splt;
3378 Elf32_External_Dyn *dyncon, *dynconend;
3379
3d4d4302 3380 splt = bfd_get_linker_section (dynobj, ".plt");
7ba29e2a
NC
3381 BFD_ASSERT (splt != NULL && sdyn != NULL);
3382
3383 dyncon = (Elf32_External_Dyn *) sdyn->contents;
3384 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
3385 for (; dyncon < dynconend; dyncon++)
3386 {
3387 Elf_Internal_Dyn dyn;
3388 const char *name;
3389 bfd_boolean size;
3390
3391 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
3392
3393 switch (dyn.d_tag)
3394 {
3395 case DT_PLTGOT: name = ".got.plt"; size = FALSE; break;
3396 case DT_PLTRELSZ: name = ".rela.plt"; size = TRUE; break;
3397 case DT_JMPREL: name = ".rela.plt"; size = FALSE; break;
3398 case DT_RELA: name = ".rela.dyn"; size = FALSE; break;
3399 case DT_RELASZ: name = ".rela.dyn"; size = TRUE; break;
3400 default: name = NULL; size = FALSE; break;
3401 }
3402
3403 if (name != NULL)
3404 {
3405 asection *s;
3406
4ade44b7 3407 s = bfd_get_linker_section (dynobj, name);
7ba29e2a
NC
3408 if (s == NULL)
3409 dyn.d_un.d_val = 0;
3410 else
3411 {
3412 if (! size)
4ade44b7 3413 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
7ba29e2a
NC
3414 else
3415 dyn.d_un.d_val = s->size;
3416 }
3417 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
3418 }
3419 }
3420
3421 /* Clear the first entry in the procedure linkage table,
3422 and put a nop in the last four bytes. */
3423 if (splt->size > 0)
3424 {
3425 memset (splt->contents, 0, PLT_ENTRY_SIZE);
3426 bfd_put_32 (output_bfd, (bfd_vma) 0x80000000 /* nop. */,
3427 splt->contents + splt->size - 4);
3428 }
3429
3430 elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
3431 }
3432
3433 /* Set the first entry in the global offset table to the address of
3434 the dynamic section. */
3d4d4302 3435 sgot = bfd_get_linker_section (dynobj, ".got.plt");
7ba29e2a
NC
3436 if (sgot && sgot->size > 0)
3437 {
3438 if (sdyn == NULL)
3439 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
3440 else
3441 bfd_put_32 (output_bfd,
3442 sdyn->output_section->vma + sdyn->output_offset,
3443 sgot->contents);
3444 elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
3445 }
3446
3447 if (htab->sgot && htab->sgot->size > 0)
3448 elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 4;
3449
3450 return TRUE;
3451}
3452
3453/* Hook called by the linker routine which adds symbols from an object
3454 file. We use it to put .comm items in .sbss, and not .bss. */
3455
3456static bfd_boolean
3457microblaze_elf_add_symbol_hook (bfd *abfd,
3458 struct bfd_link_info *info,
3459 Elf_Internal_Sym *sym,
3460 const char **namep ATTRIBUTE_UNUSED,
3461 flagword *flagsp ATTRIBUTE_UNUSED,
3462 asection **secp,
3463 bfd_vma *valp)
3464{
3465 if (sym->st_shndx == SHN_COMMON
0e1862bb 3466 && !bfd_link_relocatable (info)
7ba29e2a
NC
3467 && sym->st_size <= elf_gp_size (abfd))
3468 {
3469 /* Common symbols less than or equal to -G nn bytes are automatically
3470 put into .sbss. */
3d4d4302 3471 *secp = bfd_make_section_old_way (abfd, ".sbss");
7ba29e2a
NC
3472 if (*secp == NULL
3473 || ! bfd_set_section_flags (abfd, *secp, SEC_IS_COMMON))
3474 return FALSE;
3475
3476 *valp = sym->st_size;
3477 }
3478
3479 return TRUE;
3480}
3481
6d00b590 3482#define TARGET_LITTLE_SYM microblaze_elf32_le_vec
f23200ad 3483#define TARGET_LITTLE_NAME "elf32-microblazeel"
7ba29e2a 3484
6d00b590 3485#define TARGET_BIG_SYM microblaze_elf32_vec
7ba29e2a
NC
3486#define TARGET_BIG_NAME "elf32-microblaze"
3487
3488#define ELF_ARCH bfd_arch_microblaze
ae95ffa6 3489#define ELF_TARGET_ID MICROBLAZE_ELF_DATA
7ba29e2a
NC
3490#define ELF_MACHINE_CODE EM_MICROBLAZE
3491#define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
69b06cc8 3492#define ELF_MAXPAGESIZE 0x1000
7ba29e2a
NC
3493#define elf_info_to_howto microblaze_elf_info_to_howto
3494#define elf_info_to_howto_rel NULL
3495
3496#define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
3497#define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name
3498#define elf_backend_relocate_section microblaze_elf_relocate_section
3499#define bfd_elf32_bfd_relax_section microblaze_elf_relax_section
f23200ad 3500#define bfd_elf32_bfd_merge_private_bfd_data microblaze_elf_merge_private_bfd_data
7ba29e2a
NC
3501#define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
3502
3503#define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
3504#define elf_backend_gc_sweep_hook microblaze_elf_gc_sweep_hook
3505#define elf_backend_check_relocs microblaze_elf_check_relocs
3506#define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
3507#define bfd_elf32_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
3508#define elf_backend_can_gc_sections 1
3509#define elf_backend_can_refcount 1
3510#define elf_backend_want_got_plt 1
3511#define elf_backend_plt_readonly 1
3512#define elf_backend_got_header_size 12
3513#define elf_backend_rela_normal 1
3514
3515#define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
3516#define elf_backend_create_dynamic_sections microblaze_elf_create_dynamic_sections
3517#define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
3518#define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
3519#define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
3520#define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
3521
3522#include "elf32-target.h"
This page took 0.843297 seconds and 4 git commands to generate.