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