elf32-microblaze.c revision 1.1.1.12 1 /* Xilinx MicroBlaze-specific support for 32-bit ELF
2
3 Copyright (C) 2009-2024 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 int rel_count;
1773 unsigned int shndx;
1774 size_t i, sym_index;
1775 asection *o;
1776 struct elf_link_hash_entry *sym_hash;
1777 Elf_Internal_Sym *isymbuf, *isymend;
1778 Elf_Internal_Sym *isym;
1779 size_t symcount;
1780 size_t offset;
1781 bfd_vma src, dest;
1782 struct _microblaze_elf_section_data *sdata;
1783
1784 /* We only do this once per section. We may be able to delete some code
1785 by running multiple passes, but it is not worth it. */
1786 *again = false;
1787
1788 /* Only do this for a text section. */
1789 if (bfd_link_relocatable (link_info)
1790 || (sec->flags & SEC_RELOC) == 0
1791 || (sec->flags & SEC_CODE) == 0
1792 || sec->reloc_count == 0
1793 || (sdata = microblaze_elf_section_data (sec)) == NULL)
1794 return true;
1795
1796 BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0));
1797
1798 /* If this is the first time we have been called for this section,
1799 initialize the cooked size. */
1800 if (sec->size == 0)
1801 sec->size = sec->rawsize;
1802
1803 /* Get symbols for this section. */
1804 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1805 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1806 symcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
1807 if (isymbuf == NULL)
1808 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount,
1809 0, NULL, NULL, NULL);
1810 BFD_ASSERT (isymbuf != NULL);
1811
1812 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
1813 if (internal_relocs == NULL)
1814 goto error_return;
1815 if (! link_info->keep_memory)
1816 free_relocs = internal_relocs;
1817
1818 sdata->relax_count = 0;
1819 sdata->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
1820 * sizeof (*sdata->relax));
1821 if (sdata->relax == NULL)
1822 goto error_return;
1823
1824 irelend = internal_relocs + sec->reloc_count;
1825 rel_count = 0;
1826 for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1827 {
1828 bfd_vma symval;
1829 if ((ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL)
1830 && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64)
1831 && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_TEXTREL_64))
1832 continue; /* Can't delete this reloc. */
1833
1834 /* Get the section contents. */
1835 if (contents == NULL)
1836 {
1837 if (elf_section_data (sec)->this_hdr.contents != NULL)
1838 contents = elf_section_data (sec)->this_hdr.contents;
1839 else
1840 {
1841 contents = (bfd_byte *) bfd_malloc (sec->size);
1842 if (contents == NULL)
1843 goto error_return;
1844 free_contents = contents;
1845
1846 if (!bfd_get_section_contents (abfd, sec, contents,
1847 (file_ptr) 0, sec->size))
1848 goto error_return;
1849 elf_section_data (sec)->this_hdr.contents = contents;
1850 }
1851 }
1852
1853 /* Get the value of the symbol referred to by the reloc. */
1854 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1855 {
1856 /* A local symbol. */
1857 asection *sym_sec;
1858
1859 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1860 if (isym->st_shndx == SHN_UNDEF)
1861 sym_sec = bfd_und_section_ptr;
1862 else if (isym->st_shndx == SHN_ABS)
1863 sym_sec = bfd_abs_section_ptr;
1864 else if (isym->st_shndx == SHN_COMMON)
1865 sym_sec = bfd_com_section_ptr;
1866 else
1867 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1868
1869 symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
1870 }
1871 else
1872 {
1873 unsigned long indx;
1874 struct elf_link_hash_entry *h;
1875
1876 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1877 h = elf_sym_hashes (abfd)[indx];
1878 BFD_ASSERT (h != NULL);
1879
1880 if (h->root.type != bfd_link_hash_defined
1881 && h->root.type != bfd_link_hash_defweak)
1882 /* This appears to be a reference to an undefined
1883 symbol. Just ignore it--it will be caught by the
1884 regular reloc processing. */
1885 continue;
1886
1887 symval = (h->root.u.def.value
1888 + h->root.u.def.section->output_section->vma
1889 + h->root.u.def.section->output_offset);
1890 }
1891
1892 /* If this is a PC-relative reloc, subtract the instr offset from
1893 the symbol value. */
1894 if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_64_PCREL)
1895 {
1896 symval = symval + irel->r_addend
1897 - (irel->r_offset
1898 + sec->output_section->vma
1899 + sec->output_offset);
1900 }
1901 else if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_TEXTREL_64)
1902 {
1903 symval = symval + irel->r_addend - (sec->output_section->vma);
1904 }
1905 else
1906 symval += irel->r_addend;
1907
1908 if ((symval & 0xffff8000) == 0
1909 || (symval & 0xffff8000) == 0xffff8000)
1910 {
1911 /* We can delete this instruction. */
1912 sdata->relax[sdata->relax_count].addr = irel->r_offset;
1913 sdata->relax[sdata->relax_count].size = INST_WORD_SIZE;
1914 sdata->relax_count++;
1915
1916 /* Rewrite relocation type. */
1917 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1918 {
1919 case R_MICROBLAZE_64_PCREL:
1920 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1921 (int) R_MICROBLAZE_32_PCREL_LO);
1922 break;
1923 case R_MICROBLAZE_64:
1924 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1925 (int) R_MICROBLAZE_32_LO);
1926 break;
1927 case R_MICROBLAZE_TEXTREL_64:
1928 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1929 (int) R_MICROBLAZE_TEXTREL_32_LO);
1930 break;
1931 default:
1932 /* Cannot happen. */
1933 BFD_ASSERT (false);
1934 }
1935 }
1936 } /* Loop through all relocations. */
1937
1938 /* Loop through the relocs again, and see if anything needs to change. */
1939 if (sdata->relax_count > 0)
1940 {
1941 shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1942 rel_count = 0;
1943 sdata->relax[sdata->relax_count].addr = sec->size;
1944
1945 for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1946 {
1947 bfd_vma nraddr;
1948
1949 /* Get the new reloc address. */
1950 nraddr = irel->r_offset - calc_fixup (irel->r_offset, 0, sec);
1951 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1952 {
1953 default:
1954 break;
1955 case R_MICROBLAZE_64_PCREL:
1956 break;
1957 case R_MICROBLAZE_TEXTREL_64:
1958 case R_MICROBLAZE_TEXTREL_32_LO:
1959 case R_MICROBLAZE_64:
1960 case R_MICROBLAZE_32_LO:
1961 /* If this reloc is against a symbol defined in this
1962 section, we must check the addend to see it will put the value in
1963 range to be adjusted, and hence must be changed. */
1964 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1965 {
1966 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1967 /* Only handle relocs against .text. */
1968 if (isym->st_shndx == shndx
1969 && ELF32_ST_TYPE (isym->st_info) == STT_SECTION)
1970 irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
1971 }
1972 break;
1973 case R_MICROBLAZE_NONE:
1974 case R_MICROBLAZE_32_NONE:
1975 {
1976 /* This was a PC-relative instruction that was
1977 completely resolved. */
1978 size_t sfix, efix;
1979 bfd_vma target_address;
1980 target_address = irel->r_addend + irel->r_offset;
1981 sfix = calc_fixup (irel->r_offset, 0, sec);
1982 efix = calc_fixup (target_address, 0, sec);
1983 irel->r_addend -= (efix - sfix);
1984 /* Should use HOWTO. */
1985 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
1986 irel->r_addend);
1987 }
1988 break;
1989 case R_MICROBLAZE_64_NONE:
1990 {
1991 /* This was a PC-relative 64-bit instruction that was
1992 completely resolved. */
1993 size_t sfix, efix;
1994 bfd_vma target_address;
1995 target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE;
1996 sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec);
1997 efix = calc_fixup (target_address, 0, sec);
1998 irel->r_addend -= (efix - sfix);
1999 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset
2000 + INST_WORD_SIZE, irel->r_addend);
2001 }
2002 break;
2003 }
2004 irel->r_offset = nraddr;
2005 } /* Change all relocs in this section. */
2006
2007 /* Look through all other sections. */
2008 for (o = abfd->sections; o != NULL; o = o->next)
2009 {
2010 Elf_Internal_Rela *irelocs;
2011 Elf_Internal_Rela *irelscan, *irelscanend;
2012 bfd_byte *ocontents;
2013
2014 if (o == sec
2015 || (o->flags & SEC_RELOC) == 0
2016 || o->reloc_count == 0)
2017 continue;
2018
2019 /* We always cache the relocs. Perhaps, if info->keep_memory is
2020 FALSE, we should free them, if we are permitted to. */
2021
2022 irelocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, true);
2023 if (irelocs == NULL)
2024 goto error_return;
2025
2026 ocontents = NULL;
2027 irelscanend = irelocs + o->reloc_count;
2028 for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
2029 {
2030 if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
2031 || (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE))
2032 {
2033 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2034
2035 /* Look at the reloc only if the value has been resolved. */
2036 if (isym->st_shndx == shndx
2037 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2038 {
2039 if (ocontents == NULL)
2040 {
2041 if (elf_section_data (o)->this_hdr.contents != NULL)
2042 ocontents = elf_section_data (o)->this_hdr.contents;
2043 else
2044 {
2045 /* We always cache the section contents.
2046 Perhaps, if info->keep_memory is FALSE, we
2047 should free them, if we are permitted to. */
2048 if (o->rawsize == 0)
2049 o->rawsize = o->size;
2050 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2051 if (ocontents == NULL)
2052 goto error_return;
2053 if (!bfd_get_section_contents (abfd, o, ocontents,
2054 (file_ptr) 0,
2055 o->rawsize))
2056 goto error_return;
2057 elf_section_data (o)->this_hdr.contents = ocontents;
2058 }
2059
2060 }
2061 irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
2062 }
2063 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
2064 {
2065 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2066
2067 /* Look at the reloc only if the value has been resolved. */
2068 if (ocontents == NULL)
2069 {
2070 if (elf_section_data (o)->this_hdr.contents != NULL)
2071 ocontents = elf_section_data (o)->this_hdr.contents;
2072 else
2073 {
2074 /* We always cache the section contents.
2075 Perhaps, if info->keep_memory is FALSE, we
2076 should free them, if we are permitted to. */
2077
2078 if (o->rawsize == 0)
2079 o->rawsize = o->size;
2080 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2081 if (ocontents == NULL)
2082 goto error_return;
2083 if (!bfd_get_section_contents (abfd, o, ocontents,
2084 (file_ptr) 0,
2085 o->rawsize))
2086 goto error_return;
2087 elf_section_data (o)->this_hdr.contents = ocontents;
2088 }
2089 }
2090 irelscan->r_addend -= calc_fixup (irelscan->r_addend
2091 + isym->st_value,
2092 0,
2093 sec);
2094 }
2095 }
2096 else if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO)
2097 || (ELF32_R_TYPE (irelscan->r_info)
2098 == (int) R_MICROBLAZE_32_LO)
2099 || (ELF32_R_TYPE (irelscan->r_info)
2100 == (int) R_MICROBLAZE_TEXTREL_32_LO))
2101 {
2102 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2103
2104 /* Look at the reloc only if the value has been resolved. */
2105 if (isym->st_shndx == shndx
2106 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2107 {
2108 bfd_vma immediate;
2109 bfd_vma target_address;
2110
2111 if (ocontents == NULL)
2112 {
2113 if (elf_section_data (o)->this_hdr.contents != NULL)
2114 ocontents = elf_section_data (o)->this_hdr.contents;
2115 else
2116 {
2117 /* We always cache the section contents.
2118 Perhaps, if info->keep_memory is FALSE, we
2119 should free them, if we are permitted to. */
2120 if (o->rawsize == 0)
2121 o->rawsize = o->size;
2122 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2123 if (ocontents == NULL)
2124 goto error_return;
2125 if (!bfd_get_section_contents (abfd, o, ocontents,
2126 (file_ptr) 0,
2127 o->rawsize))
2128 goto error_return;
2129 elf_section_data (o)->this_hdr.contents = ocontents;
2130 }
2131 }
2132
2133 unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
2134 immediate = instr & 0x0000ffff;
2135 target_address = immediate;
2136 offset = calc_fixup (target_address, 0, sec);
2137 immediate -= offset;
2138 irelscan->r_addend -= offset;
2139 microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
2140 irelscan->r_addend);
2141 }
2142 }
2143
2144 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64
2145 || (ELF32_R_TYPE (irelscan->r_info)
2146 == (int) R_MICROBLAZE_TEXTREL_64))
2147 {
2148 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2149
2150 /* Look at the reloc only if the value has been resolved. */
2151 if (isym->st_shndx == shndx
2152 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2153 {
2154 if (ocontents == NULL)
2155 {
2156 if (elf_section_data (o)->this_hdr.contents != NULL)
2157 ocontents = elf_section_data (o)->this_hdr.contents;
2158 else
2159 {
2160 /* We always cache the section contents.
2161 Perhaps, if info->keep_memory is FALSE, we
2162 should free them, if we are permitted to. */
2163
2164 if (o->rawsize == 0)
2165 o->rawsize = o->size;
2166 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2167 if (ocontents == NULL)
2168 goto error_return;
2169 if (!bfd_get_section_contents (abfd, o, ocontents,
2170 (file_ptr) 0,
2171 o->rawsize))
2172 goto error_return;
2173 elf_section_data (o)->this_hdr.contents = ocontents;
2174 }
2175 }
2176 offset = calc_fixup (irelscan->r_addend, 0, sec);
2177 irelscan->r_addend -= offset;
2178 }
2179 }
2180 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
2181 {
2182 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2183
2184 /* Look at the reloc only if the value has been resolved. */
2185 if (isym->st_shndx == shndx
2186 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2187 {
2188 bfd_vma immediate;
2189 bfd_vma target_address;
2190
2191 if (ocontents == NULL)
2192 {
2193 if (elf_section_data (o)->this_hdr.contents != NULL)
2194 ocontents = elf_section_data (o)->this_hdr.contents;
2195 else
2196 {
2197 /* We always cache the section contents.
2198 Perhaps, if info->keep_memory is FALSE, we
2199 should free them, if we are permitted to. */
2200 if (o->rawsize == 0)
2201 o->rawsize = o->size;
2202 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2203 if (ocontents == NULL)
2204 goto error_return;
2205 if (!bfd_get_section_contents (abfd, o, ocontents,
2206 (file_ptr) 0,
2207 o->rawsize))
2208 goto error_return;
2209 elf_section_data (o)->this_hdr.contents = ocontents;
2210 }
2211 }
2212 unsigned long instr_hi = bfd_get_32 (abfd, ocontents
2213 + irelscan->r_offset);
2214 unsigned long instr_lo = bfd_get_32 (abfd, ocontents
2215 + irelscan->r_offset
2216 + INST_WORD_SIZE);
2217 immediate = (instr_hi & 0x0000ffff) << 16;
2218 immediate |= (instr_lo & 0x0000ffff);
2219 target_address = immediate;
2220 offset = calc_fixup (target_address, 0, sec);
2221 immediate -= offset;
2222 irelscan->r_addend -= offset;
2223 microblaze_bfd_write_imm_value_64 (abfd, ocontents
2224 + irelscan->r_offset, immediate);
2225 }
2226 }
2227 }
2228 }
2229
2230 /* Adjust the local symbols defined in this section. */
2231 isymend = isymbuf + symtab_hdr->sh_info;
2232 for (isym = isymbuf; isym < isymend; isym++)
2233 {
2234 if (isym->st_shndx == shndx)
2235 {
2236 isym->st_value -= calc_fixup (isym->st_value, 0, sec);
2237 if (isym->st_size)
2238 isym->st_size -= calc_fixup (isym->st_value, isym->st_size, sec);
2239 }
2240 }
2241
2242 /* Now adjust the global symbols defined in this section. */
2243 isym = isymbuf + symtab_hdr->sh_info;
2244 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)) - symtab_hdr->sh_info;
2245 for (sym_index = 0; sym_index < symcount; sym_index++)
2246 {
2247 sym_hash = elf_sym_hashes (abfd)[sym_index];
2248 if ((sym_hash->root.type == bfd_link_hash_defined
2249 || sym_hash->root.type == bfd_link_hash_defweak)
2250 && sym_hash->root.u.def.section == sec)
2251 {
2252 sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value,
2253 0, sec);
2254 if (sym_hash->size)
2255 sym_hash->size -= calc_fixup (sym_hash->root.u.def.value,
2256 sym_hash->size, sec);
2257 }
2258 }
2259
2260 /* Physically move the code and change the cooked size. */
2261 dest = sdata->relax[0].addr;
2262 for (i = 0; i < sdata->relax_count; i++)
2263 {
2264 size_t len;
2265 src = sdata->relax[i].addr + sdata->relax[i].size;
2266 len = (sdata->relax[i+1].addr - sdata->relax[i].addr
2267 - sdata->relax[i].size);
2268
2269 memmove (contents + dest, contents + src, len);
2270 sec->size -= sdata->relax[i].size;
2271 dest += len;
2272 }
2273
2274 elf_section_data (sec)->relocs = internal_relocs;
2275 free_relocs = NULL;
2276
2277 elf_section_data (sec)->this_hdr.contents = contents;
2278 free_contents = NULL;
2279
2280 symtab_hdr->contents = (bfd_byte *) isymbuf;
2281 }
2282
2283 free (free_relocs);
2284 free_relocs = NULL;
2285
2286 if (free_contents != NULL)
2287 {
2288 if (!link_info->keep_memory)
2289 free (free_contents);
2290 else
2291 /* Cache the section contents for elf_link_input_bfd. */
2292 elf_section_data (sec)->this_hdr.contents = contents;
2293 free_contents = NULL;
2294 }
2295
2296 if (sdata->relax_count == 0)
2297 {
2298 *again = false;
2299 free (sdata->relax);
2300 sdata->relax = NULL;
2301 }
2302 else
2303 *again = true;
2304 return true;
2305
2306 error_return:
2307 free (free_relocs);
2308 free (free_contents);
2309 free (sdata->relax);
2310 sdata->relax = NULL;
2311 sdata->relax_count = 0;
2312 return false;
2313 }
2314
2315 /* Return the section that should be marked against GC for a given
2316 relocation. */
2317
2318 static asection *
2319 microblaze_elf_gc_mark_hook (asection *sec,
2320 struct bfd_link_info * info,
2321 Elf_Internal_Rela * rel,
2322 struct elf_link_hash_entry * h,
2323 Elf_Internal_Sym * sym)
2324 {
2325 if (h != NULL)
2326 switch (ELF32_R_TYPE (rel->r_info))
2327 {
2328 case R_MICROBLAZE_GNU_VTINHERIT:
2329 case R_MICROBLAZE_GNU_VTENTRY:
2330 return NULL;
2331 }
2332
2333 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
2334 }
2335
2336 /* PIC support. */
2337
2338 #define PLT_ENTRY_SIZE 16
2339
2340 #define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
2341 #define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
2342 #define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
2343 #define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
2344 #define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
2345
2346 static bool
2347 update_local_sym_info (bfd *abfd,
2348 Elf_Internal_Shdr *symtab_hdr,
2349 unsigned long r_symndx,
2350 unsigned int tls_type)
2351 {
2352 bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
2353 unsigned char *local_got_tls_masks;
2354
2355 if (local_got_refcounts == NULL)
2356 {
2357 bfd_size_type size = symtab_hdr->sh_info;
2358
2359 size *= (sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks));
2360 local_got_refcounts = bfd_zalloc (abfd, size);
2361 if (local_got_refcounts == NULL)
2362 return false;
2363 elf_local_got_refcounts (abfd) = local_got_refcounts;
2364 }
2365
2366 local_got_tls_masks =
2367 (unsigned char *) (local_got_refcounts + symtab_hdr->sh_info);
2368 local_got_tls_masks[r_symndx] |= tls_type;
2369 local_got_refcounts[r_symndx] += 1;
2370
2371 return true;
2372 }
2373 /* Look through the relocs for a section during the first phase. */
2374
2375 static bool
2376 microblaze_elf_check_relocs (bfd * abfd,
2377 struct bfd_link_info * info,
2378 asection * sec,
2379 const Elf_Internal_Rela * relocs)
2380 {
2381 Elf_Internal_Shdr * symtab_hdr;
2382 struct elf_link_hash_entry ** sym_hashes;
2383 const Elf_Internal_Rela * rel;
2384 const Elf_Internal_Rela * rel_end;
2385 struct elf32_mb_link_hash_table *htab;
2386 asection *sreloc = NULL;
2387
2388 if (bfd_link_relocatable (info))
2389 return true;
2390
2391 htab = elf32_mb_hash_table (info);
2392 if (htab == NULL)
2393 return false;
2394
2395 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
2396 sym_hashes = elf_sym_hashes (abfd);
2397
2398 rel_end = relocs + sec->reloc_count;
2399
2400 for (rel = relocs; rel < rel_end; rel++)
2401 {
2402 unsigned int r_type;
2403 struct elf_link_hash_entry * h;
2404 unsigned long r_symndx;
2405 unsigned char tls_type = 0;
2406
2407 r_symndx = ELF32_R_SYM (rel->r_info);
2408 r_type = ELF32_R_TYPE (rel->r_info);
2409
2410 if (r_symndx < symtab_hdr->sh_info)
2411 h = NULL;
2412 else
2413 {
2414 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
2415 while (h->root.type == bfd_link_hash_indirect
2416 || h->root.type == bfd_link_hash_warning)
2417 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2418 }
2419
2420 switch (r_type)
2421 {
2422 /* This relocation describes the C++ object vtable hierarchy.
2423 Reconstruct it for later use during GC. */
2424 case R_MICROBLAZE_GNU_VTINHERIT:
2425 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2426 return false;
2427 break;
2428
2429 /* This relocation describes which C++ vtable entries are actually
2430 used. Record for later use during GC. */
2431 case R_MICROBLAZE_GNU_VTENTRY:
2432 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
2433 return false;
2434 break;
2435
2436 /* This relocation requires .plt entry. */
2437 case R_MICROBLAZE_PLT_64:
2438 if (h != NULL)
2439 {
2440 h->needs_plt = 1;
2441 h->plt.refcount += 1;
2442 }
2443 break;
2444
2445 /* This relocation requires .got entry. */
2446 case R_MICROBLAZE_TLSGD:
2447 tls_type |= (TLS_TLS | TLS_GD);
2448 goto dogottls;
2449 case R_MICROBLAZE_TLSLD:
2450 tls_type |= (TLS_TLS | TLS_LD);
2451 /* Fall through. */
2452 dogottls:
2453 sec->has_tls_reloc = 1;
2454 /* Fall through. */
2455 case R_MICROBLAZE_GOT_64:
2456 if (htab->elf.sgot == NULL)
2457 {
2458 if (htab->elf.dynobj == NULL)
2459 htab->elf.dynobj = abfd;
2460 if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
2461 return false;
2462 }
2463 if (h != NULL)
2464 {
2465 h->got.refcount += 1;
2466 elf32_mb_hash_entry (h)->tls_mask |= tls_type;
2467 }
2468 else
2469 {
2470 if (! update_local_sym_info(abfd, symtab_hdr, r_symndx, tls_type) )
2471 return false;
2472 }
2473 break;
2474
2475 case R_MICROBLAZE_GOTOFF_64:
2476 case R_MICROBLAZE_GOTOFF_32:
2477 if (htab->elf.sgot == NULL)
2478 {
2479 if (htab->elf.dynobj == NULL)
2480 htab->elf.dynobj = abfd;
2481 if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
2482 return false;
2483 }
2484 break;
2485
2486 case R_MICROBLAZE_64:
2487 case R_MICROBLAZE_64_PCREL:
2488 case R_MICROBLAZE_32:
2489 {
2490 if (h != NULL && !bfd_link_pic (info))
2491 {
2492 /* we may need a copy reloc. */
2493 h->non_got_ref = 1;
2494
2495 /* we may also need a .plt entry. */
2496 h->plt.refcount += 1;
2497 if (ELF32_R_TYPE (rel->r_info) != R_MICROBLAZE_64_PCREL)
2498 h->pointer_equality_needed = 1;
2499 }
2500
2501
2502 /* If we are creating a shared library, and this is a reloc
2503 against a global symbol, or a non PC relative reloc
2504 against a local symbol, then we need to copy the reloc
2505 into the shared library. However, if we are linking with
2506 -Bsymbolic, we do not need to copy a reloc against a
2507 global symbol which is defined in an object we are
2508 including in the link (i.e., DEF_REGULAR is set). At
2509 this point we have not seen all the input files, so it is
2510 possible that DEF_REGULAR is not set now but will be set
2511 later (it is never cleared). In case of a weak definition,
2512 DEF_REGULAR may be cleared later by a strong definition in
2513 a shared library. We account for that possibility below by
2514 storing information in the relocs_copied field of the hash
2515 table entry. A similar situation occurs when creating
2516 shared libraries and symbol visibility changes render the
2517 symbol local.
2518
2519 If on the other hand, we are creating an executable, we
2520 may need to keep relocations for symbols satisfied by a
2521 dynamic library if we manage to avoid copy relocs for the
2522 symbol. */
2523
2524 if ((bfd_link_pic (info)
2525 && (sec->flags & SEC_ALLOC) != 0
2526 && (r_type != R_MICROBLAZE_64_PCREL
2527 || (h != NULL
2528 && (! info->symbolic
2529 || h->root.type == bfd_link_hash_defweak
2530 || !h->def_regular))))
2531 || (!bfd_link_pic (info)
2532 && (sec->flags & SEC_ALLOC) != 0
2533 && h != NULL
2534 && (h->root.type == bfd_link_hash_defweak
2535 || !h->def_regular)))
2536 {
2537 struct elf_dyn_relocs *p;
2538 struct elf_dyn_relocs **head;
2539
2540 /* When creating a shared object, we must copy these
2541 relocs into the output file. We create a reloc
2542 section in dynobj and make room for the reloc. */
2543
2544 if (sreloc == NULL)
2545 {
2546 bfd *dynobj;
2547
2548 if (htab->elf.dynobj == NULL)
2549 htab->elf.dynobj = abfd;
2550 dynobj = htab->elf.dynobj;
2551
2552 sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
2553 2, abfd, 1);
2554 if (sreloc == NULL)
2555 return false;
2556 }
2557
2558 /* If this is a global symbol, we count the number of
2559 relocations we need for this symbol. */
2560 if (h != NULL)
2561 head = &h->dyn_relocs;
2562 else
2563 {
2564 /* Track dynamic relocs needed for local syms too.
2565 We really need local syms available to do this
2566 easily. Oh well. */
2567
2568 asection *s;
2569 Elf_Internal_Sym *isym;
2570 void *vpp;
2571
2572 isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
2573 abfd, r_symndx);
2574 if (isym == NULL)
2575 return false;
2576
2577 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2578 if (s == NULL)
2579 return false;
2580
2581 vpp = &elf_section_data (s)->local_dynrel;
2582 head = (struct elf_dyn_relocs **) vpp;
2583 }
2584
2585 p = *head;
2586 if (p == NULL || p->sec != sec)
2587 {
2588 size_t amt = sizeof *p;
2589 p = ((struct elf_dyn_relocs *)
2590 bfd_alloc (htab->elf.dynobj, amt));
2591 if (p == NULL)
2592 return false;
2593 p->next = *head;
2594 *head = p;
2595 p->sec = sec;
2596 p->count = 0;
2597 p->pc_count = 0;
2598 }
2599
2600 p->count += 1;
2601 if (r_type == R_MICROBLAZE_64_PCREL)
2602 p->pc_count += 1;
2603 }
2604 }
2605 break;
2606 }
2607 }
2608
2609 return true;
2610 }
2611
2612 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2613
2614 static void
2615 microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
2616 struct elf_link_hash_entry *dir,
2617 struct elf_link_hash_entry *ind)
2618 {
2619 struct elf32_mb_link_hash_entry *edir, *eind;
2620
2621 edir = (struct elf32_mb_link_hash_entry *) dir;
2622 eind = (struct elf32_mb_link_hash_entry *) ind;
2623
2624 edir->tls_mask |= eind->tls_mask;
2625
2626 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
2627 }
2628
2629 static bool
2630 microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2631 struct elf_link_hash_entry *h)
2632 {
2633 struct elf32_mb_link_hash_table *htab;
2634 asection *s, *srel;
2635 unsigned int power_of_two;
2636
2637 htab = elf32_mb_hash_table (info);
2638 if (htab == NULL)
2639 return false;
2640
2641 /* If this is a function, put it in the procedure linkage table. We
2642 will fill in the contents of the procedure linkage table later,
2643 when we know the address of the .got section. */
2644 if (h->type == STT_FUNC
2645 || h->needs_plt)
2646 {
2647 if (h->plt.refcount <= 0
2648 || SYMBOL_CALLS_LOCAL (info, h)
2649 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
2650 && h->root.type == bfd_link_hash_undefweak))
2651 {
2652 /* This case can occur if we saw a PLT reloc in an input
2653 file, but the symbol was never referred to by a dynamic
2654 object, or if all references were garbage collected. In
2655 such a case, we don't actually need to build a procedure
2656 linkage table, and we can just do a PC32 reloc instead. */
2657 h->plt.offset = (bfd_vma) -1;
2658 h->needs_plt = 0;
2659 }
2660
2661 return true;
2662 }
2663 else
2664 /* It's possible that we incorrectly decided a .plt reloc was
2665 needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
2666 check_relocs. We can't decide accurately between function and
2667 non-function syms in check-relocs; Objects loaded later in
2668 the link may change h->type. So fix it now. */
2669 h->plt.offset = (bfd_vma) -1;
2670
2671 /* If this is a weak symbol, and there is a real definition, the
2672 processor independent code will have arranged for us to see the
2673 real definition first, and we can just use the same value. */
2674 if (h->is_weakalias)
2675 {
2676 struct elf_link_hash_entry *def = weakdef (h);
2677 BFD_ASSERT (def->root.type == bfd_link_hash_defined);
2678 h->root.u.def.section = def->root.u.def.section;
2679 h->root.u.def.value = def->root.u.def.value;
2680 return true;
2681 }
2682
2683 /* This is a reference to a symbol defined by a dynamic object which
2684 is not a function. */
2685
2686 /* If we are creating a shared library, we must presume that the
2687 only references to the symbol are via the global offset table.
2688 For such cases we need not do anything here; the relocations will
2689 be handled correctly by relocate_section. */
2690 if (bfd_link_pic (info))
2691 return true;
2692
2693 /* If there are no references to this symbol that do not use the
2694 GOT, we don't need to generate a copy reloc. */
2695 if (!h->non_got_ref)
2696 return true;
2697
2698 /* If -z nocopyreloc was given, we won't generate them either. */
2699 if (info->nocopyreloc)
2700 {
2701 h->non_got_ref = 0;
2702 return true;
2703 }
2704
2705 /* If we don't find any dynamic relocs in read-only sections, then
2706 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
2707 if (!_bfd_elf_readonly_dynrelocs (h))
2708 {
2709 h->non_got_ref = 0;
2710 return true;
2711 }
2712
2713 /* We must allocate the symbol in our .dynbss section, which will
2714 become part of the .bss section of the executable. There will be
2715 an entry for this symbol in the .dynsym section. The dynamic
2716 object will contain position independent code, so all references
2717 from the dynamic object to this symbol will go through the global
2718 offset table. The dynamic linker will use the .dynsym entry to
2719 determine the address it must put in the global offset table, so
2720 both the dynamic object and the regular object will refer to the
2721 same memory location for the variable. */
2722
2723 /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
2724 to copy the initial value out of the dynamic object and into the
2725 runtime process image. */
2726 if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
2727 {
2728 s = htab->elf.sdynrelro;
2729 srel = htab->elf.sreldynrelro;
2730 }
2731 else
2732 {
2733 s = htab->elf.sdynbss;
2734 srel = htab->elf.srelbss;
2735 }
2736 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2737 {
2738 srel->size += sizeof (Elf32_External_Rela);
2739 h->needs_copy = 1;
2740 }
2741
2742 /* We need to figure out the alignment required for this symbol. I
2743 have no idea how ELF linkers handle this. */
2744 power_of_two = bfd_log2 (h->size);
2745 if (power_of_two > 3)
2746 power_of_two = 3;
2747
2748 /* Apply the required alignment. */
2749 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
2750 if (power_of_two > s->alignment_power)
2751 {
2752 if (!bfd_set_section_alignment (s, power_of_two))
2753 return false;
2754 }
2755
2756 /* Define the symbol as being at this point in the section. */
2757 h->root.u.def.section = s;
2758 h->root.u.def.value = s->size;
2759
2760 /* Increment the section size to make room for the symbol. */
2761 s->size += h->size;
2762 return true;
2763 }
2764
2765 /* Allocate space in .plt, .got and associated reloc sections for
2766 dynamic relocs. */
2767
2768 static bool
2769 allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
2770 {
2771 struct bfd_link_info *info;
2772 struct elf32_mb_link_hash_table *htab;
2773 struct elf32_mb_link_hash_entry *eh;
2774 struct elf_dyn_relocs *p;
2775
2776 if (h->root.type == bfd_link_hash_indirect)
2777 return true;
2778
2779 info = (struct bfd_link_info *) dat;
2780 htab = elf32_mb_hash_table (info);
2781 if (htab == NULL)
2782 return false;
2783
2784 if (htab->elf.dynamic_sections_created
2785 && h->plt.refcount > 0)
2786 {
2787 /* Make sure this symbol is output as a dynamic symbol.
2788 Undefined weak syms won't yet be marked as dynamic. */
2789 if (h->dynindx == -1
2790 && !h->forced_local)
2791 {
2792 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2793 return false;
2794 }
2795
2796 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
2797 {
2798 asection *s = htab->elf.splt;
2799
2800 /* The first entry in .plt is reserved. */
2801 if (s->size == 0)
2802 s->size = PLT_ENTRY_SIZE;
2803
2804 h->plt.offset = s->size;
2805
2806 /* If this symbol is not defined in a regular file, and we are
2807 not generating a shared library, then set the symbol to this
2808 location in the .plt. This is required to make function
2809 pointers compare as equal between the normal executable and
2810 the shared library. */
2811 if (! bfd_link_pic (info)
2812 && !h->def_regular)
2813 {
2814 h->root.u.def.section = s;
2815 h->root.u.def.value = h->plt.offset;
2816 }
2817
2818 /* Make room for this entry. */
2819 s->size += PLT_ENTRY_SIZE;
2820
2821 /* We also need to make an entry in the .got.plt section, which
2822 will be placed in the .got section by the linker script. */
2823 htab->elf.sgotplt->size += 4;
2824
2825 /* We also need to make an entry in the .rel.plt section. */
2826 htab->elf.srelplt->size += sizeof (Elf32_External_Rela);
2827 }
2828 else
2829 {
2830 h->plt.offset = (bfd_vma) -1;
2831 h->needs_plt = 0;
2832 }
2833 }
2834 else
2835 {
2836 h->plt.offset = (bfd_vma) -1;
2837 h->needs_plt = 0;
2838 }
2839
2840 eh = (struct elf32_mb_link_hash_entry *) h;
2841 if (h->got.refcount > 0)
2842 {
2843 unsigned int need;
2844 asection *s;
2845
2846 /* Make sure this symbol is output as a dynamic symbol.
2847 Undefined weak syms won't yet be marked as dynamic. */
2848 if (h->dynindx == -1
2849 && !h->forced_local)
2850 {
2851 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2852 return false;
2853 }
2854
2855 need = 0;
2856 if ((eh->tls_mask & TLS_TLS) != 0)
2857 {
2858 /* Handle TLS Symbol */
2859 if ((eh->tls_mask & TLS_LD) != 0)
2860 {
2861 if (!eh->elf.def_dynamic)
2862 /* We'll just use htab->tlsld_got.offset. This should
2863 always be the case. It's a little odd if we have
2864 a local dynamic reloc against a non-local symbol. */
2865 htab->tlsld_got.refcount += 1;
2866 else
2867 need += 8;
2868 }
2869 if ((eh->tls_mask & TLS_GD) != 0)
2870 need += 8;
2871 }
2872 else
2873 {
2874 /* Regular (non-TLS) symbol */
2875 need += 4;
2876 }
2877 if (need == 0)
2878 {
2879 h->got.offset = (bfd_vma) -1;
2880 }
2881 else
2882 {
2883 s = htab->elf.sgot;
2884 h->got.offset = s->size;
2885 s->size += need;
2886 htab->elf.srelgot->size += need * (sizeof (Elf32_External_Rela) / 4);
2887 }
2888 }
2889 else
2890 h->got.offset = (bfd_vma) -1;
2891
2892 if (h->dyn_relocs == NULL)
2893 return true;
2894
2895 /* In the shared -Bsymbolic case, discard space allocated for
2896 dynamic pc-relative relocs against symbols which turn out to be
2897 defined in regular objects. For the normal shared case, discard
2898 space for pc-relative relocs that have become local due to symbol
2899 visibility changes. */
2900
2901 if (bfd_link_pic (info))
2902 {
2903 if (h->def_regular
2904 && (h->forced_local
2905 || info->symbolic))
2906 {
2907 struct elf_dyn_relocs **pp;
2908
2909 for (pp = &h->dyn_relocs; (p = *pp) != NULL; )
2910 {
2911 p->count -= p->pc_count;
2912 p->pc_count = 0;
2913 if (p->count == 0)
2914 *pp = p->next;
2915 else
2916 pp = &p->next;
2917 }
2918 }
2919 else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
2920 h->dyn_relocs = NULL;
2921 }
2922 else
2923 {
2924 /* For the non-shared case, discard space for relocs against
2925 symbols which turn out to need copy relocs or are not
2926 dynamic. */
2927
2928 if (!h->non_got_ref
2929 && ((h->def_dynamic
2930 && !h->def_regular)
2931 || (htab->elf.dynamic_sections_created
2932 && (h->root.type == bfd_link_hash_undefweak
2933 || h->root.type == bfd_link_hash_undefined))))
2934 {
2935 /* Make sure this symbol is output as a dynamic symbol.
2936 Undefined weak syms won't yet be marked as dynamic. */
2937 if (h->dynindx == -1
2938 && !h->forced_local)
2939 {
2940 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2941 return false;
2942 }
2943
2944 /* If that succeeded, we know we'll be keeping all the
2945 relocs. */
2946 if (h->dynindx != -1)
2947 goto keep;
2948 }
2949
2950 h->dyn_relocs = NULL;
2951
2952 keep: ;
2953 }
2954
2955 /* Finally, allocate space. */
2956 for (p = h->dyn_relocs; p != NULL; p = p->next)
2957 {
2958 asection *sreloc = elf_section_data (p->sec)->sreloc;
2959 sreloc->size += p->count * sizeof (Elf32_External_Rela);
2960 }
2961
2962 return true;
2963 }
2964
2965 /* Set the sizes of the dynamic sections. */
2966
2967 static bool
2968 microblaze_elf_late_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2969 struct bfd_link_info *info)
2970 {
2971 struct elf32_mb_link_hash_table *htab;
2972 bfd *dynobj;
2973 asection *s;
2974 bfd *ibfd;
2975
2976 htab = elf32_mb_hash_table (info);
2977 if (htab == NULL)
2978 return false;
2979
2980 dynobj = htab->elf.dynobj;
2981 if (dynobj == NULL)
2982 return true;
2983
2984 /* Set up .got offsets for local syms, and space for local dynamic
2985 relocs. */
2986 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
2987 {
2988 bfd_signed_vma *local_got;
2989 bfd_signed_vma *end_local_got;
2990 bfd_size_type locsymcount;
2991 Elf_Internal_Shdr *symtab_hdr;
2992 unsigned char *lgot_masks;
2993 asection *srel;
2994
2995 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
2996 continue;
2997
2998 for (s = ibfd->sections; s != NULL; s = s->next)
2999 {
3000 struct elf_dyn_relocs *p;
3001
3002 for (p = ((struct elf_dyn_relocs *)
3003 elf_section_data (s)->local_dynrel);
3004 p != NULL;
3005 p = p->next)
3006 {
3007 if (!bfd_is_abs_section (p->sec)
3008 && bfd_is_abs_section (p->sec->output_section))
3009 {
3010 /* Input section has been discarded, either because
3011 it is a copy of a linkonce section or due to
3012 linker script /DISCARD/, so we'll be discarding
3013 the relocs too. */
3014 }
3015 else if (p->count != 0)
3016 {
3017 srel = elf_section_data (p->sec)->sreloc;
3018 srel->size += p->count * sizeof (Elf32_External_Rela);
3019 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
3020 info->flags |= DF_TEXTREL;
3021 }
3022 }
3023 }
3024
3025 local_got = elf_local_got_refcounts (ibfd);
3026 if (!local_got)
3027 continue;
3028
3029 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
3030 locsymcount = symtab_hdr->sh_info;
3031 end_local_got = local_got + locsymcount;
3032 lgot_masks = (unsigned char *) end_local_got;
3033 s = htab->elf.sgot;
3034 srel = htab->elf.srelgot;
3035
3036 for (; local_got < end_local_got; ++local_got, ++lgot_masks)
3037 {
3038 if (*local_got > 0)
3039 {
3040 unsigned int need = 0;
3041 if ((*lgot_masks & TLS_TLS) != 0)
3042 {
3043 if ((*lgot_masks & TLS_GD) != 0)
3044 need += 8;
3045 if ((*lgot_masks & TLS_LD) != 0)
3046 htab->tlsld_got.refcount += 1;
3047 }
3048 else
3049 need += 4;
3050
3051 if (need == 0)
3052 {
3053 *local_got = (bfd_vma) -1;
3054 }
3055 else
3056 {
3057 *local_got = s->size;
3058 s->size += need;
3059 if (bfd_link_pic (info))
3060 srel->size += need * (sizeof (Elf32_External_Rela) / 4);
3061 }
3062 }
3063 else
3064 *local_got = (bfd_vma) -1;
3065 }
3066 }
3067
3068 /* Allocate global sym .plt and .got entries, and space for global
3069 sym dynamic relocs. */
3070 elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
3071
3072 if (htab->tlsld_got.refcount > 0)
3073 {
3074 htab->tlsld_got.offset = htab->elf.sgot->size;
3075 htab->elf.sgot->size += 8;
3076 if (bfd_link_pic (info))
3077 htab->elf.srelgot->size += sizeof (Elf32_External_Rela);
3078 }
3079 else
3080 htab->tlsld_got.offset = (bfd_vma) -1;
3081
3082 if (elf_hash_table (info)->dynamic_sections_created)
3083 {
3084 /* Make space for the trailing nop in .plt. */
3085 if (htab->elf.splt->size > 0)
3086 htab->elf.splt->size += 4;
3087 }
3088
3089 /* The check_relocs and adjust_dynamic_symbol entry points have
3090 determined the sizes of the various dynamic sections. Allocate
3091 memory for them. */
3092 for (s = dynobj->sections; s != NULL; s = s->next)
3093 {
3094 const char *name;
3095 bool strip = false;
3096
3097 if ((s->flags & SEC_LINKER_CREATED) == 0)
3098 continue;
3099
3100 /* It's OK to base decisions on the section name, because none
3101 of the dynobj section names depend upon the input files. */
3102 name = bfd_section_name (s);
3103
3104 if (startswith (name, ".rela"))
3105 {
3106 if (s->size == 0)
3107 {
3108 /* If we don't need this section, strip it from the
3109 output file. This is to handle .rela.bss and
3110 .rela.plt. We must create it in
3111 create_dynamic_sections, because it must be created
3112 before the linker maps input sections to output
3113 sections. The linker does that before
3114 adjust_dynamic_symbol is called, and it is that
3115 function which decides whether anything needs to go
3116 into these sections. */
3117 strip = true;
3118 }
3119 else
3120 {
3121 /* We use the reloc_count field as a counter if we need
3122 to copy relocs into the output file. */
3123 s->reloc_count = 0;
3124 }
3125 }
3126 else if (s != htab->elf.splt
3127 && s != htab->elf.sgot
3128 && s != htab->elf.sgotplt
3129 && s != htab->elf.sdynbss
3130 && s != htab->elf.sdynrelro)
3131 {
3132 /* It's not one of our sections, so don't allocate space. */
3133 continue;
3134 }
3135
3136 if (strip)
3137 {
3138 s->flags |= SEC_EXCLUDE;
3139 continue;
3140 }
3141
3142 /* Allocate memory for the section contents. */
3143 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
3144 Unused entries should be reclaimed before the section's contents
3145 are written out, but at the moment this does not happen. Thus in
3146 order to prevent writing out garbage, we initialise the section's
3147 contents to zero. */
3148 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
3149 if (s->contents == NULL && s->size != 0)
3150 return false;
3151 }
3152
3153 /* ??? Force DF_BIND_NOW? */
3154 info->flags |= DF_BIND_NOW;
3155 return _bfd_elf_add_dynamic_tags (output_bfd, info, true);
3156 }
3157
3158 /* Finish up dynamic symbol handling. We set the contents of various
3159 dynamic sections here. */
3160
3161 static bool
3162 microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
3163 struct bfd_link_info *info,
3164 struct elf_link_hash_entry *h,
3165 Elf_Internal_Sym *sym)
3166 {
3167 struct elf32_mb_link_hash_table *htab;
3168 struct elf32_mb_link_hash_entry *eh = elf32_mb_hash_entry(h);
3169
3170 htab = elf32_mb_hash_table (info);
3171
3172 if (h->plt.offset != (bfd_vma) -1)
3173 {
3174 asection *splt;
3175 asection *srela;
3176 asection *sgotplt;
3177 Elf_Internal_Rela rela;
3178 bfd_byte *loc;
3179 bfd_vma plt_index;
3180 bfd_vma got_offset;
3181 bfd_vma got_addr;
3182
3183 /* This symbol has an entry in the procedure linkage table. Set
3184 it up. */
3185 BFD_ASSERT (h->dynindx != -1);
3186
3187 splt = htab->elf.splt;
3188 srela = htab->elf.srelplt;
3189 sgotplt = htab->elf.sgotplt;
3190 BFD_ASSERT (splt != NULL && srela != NULL && sgotplt != NULL);
3191
3192 plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* first entry reserved. */
3193 got_offset = (plt_index + 3) * 4; /* 3 reserved ??? */
3194 got_addr = got_offset;
3195
3196 /* For non-PIC objects we need absolute address of the GOT entry. */
3197 if (!bfd_link_pic (info))
3198 got_addr += sgotplt->output_section->vma + sgotplt->output_offset;
3199
3200 /* Fill in the entry in the procedure linkage table. */
3201 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_0 + ((got_addr >> 16) & 0xffff),
3202 splt->contents + h->plt.offset);
3203 if (bfd_link_pic (info))
3204 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1 + (got_addr & 0xffff),
3205 splt->contents + h->plt.offset + 4);
3206 else
3207 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1_NOPIC + (got_addr & 0xffff),
3208 splt->contents + h->plt.offset + 4);
3209 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_2,
3210 splt->contents + h->plt.offset + 8);
3211 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_3,
3212 splt->contents + h->plt.offset + 12);
3213
3214 /* Any additions to the .got section??? */
3215 /* bfd_put_32 (output_bfd,
3216 splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
3217 sgotplt->contents + got_offset); */
3218
3219 /* Fill in the entry in the .rela.plt section. */
3220 rela.r_offset = (sgotplt->output_section->vma
3221 + sgotplt->output_offset
3222 + got_offset);
3223 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_JUMP_SLOT);
3224 rela.r_addend = 0;
3225 loc = srela->contents;
3226 loc += plt_index * sizeof (Elf32_External_Rela);
3227 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
3228
3229 if (!h->def_regular)
3230 {
3231 /* Mark the symbol as undefined, rather than as defined in
3232 the .plt section. Zero the value. */
3233 sym->st_shndx = SHN_UNDEF;
3234 sym->st_value = 0;
3235 }
3236 }
3237
3238 /* h->got.refcount to be checked ? */
3239 if ((h->got.offset != (bfd_vma) -1)
3240 && ! ((h->got.offset & 1)
3241 || IS_TLS_LD(eh->tls_mask) || IS_TLS_GD(eh->tls_mask)))
3242 {
3243 asection *sgot;
3244 asection *srela;
3245 bfd_vma offset;
3246
3247 /* This symbol has an entry in the global offset table. Set it
3248 up. */
3249
3250 sgot = htab->elf.sgot;
3251 srela = htab->elf.srelgot;
3252 BFD_ASSERT (sgot != NULL && srela != NULL);
3253
3254 offset = (sgot->output_section->vma + sgot->output_offset
3255 + (h->got.offset &~ (bfd_vma) 1));
3256
3257 /* If this is a -Bsymbolic link, and the symbol is defined
3258 locally, we just want to emit a RELATIVE reloc. Likewise if
3259 the symbol was forced to be local because of a version file.
3260 The entry in the global offset table will already have been
3261 initialized in the relocate_section function. */
3262 if (bfd_link_pic (info)
3263 && ((info->symbolic && h->def_regular)
3264 || h->dynindx == -1))
3265 {
3266 asection *sec = h->root.u.def.section;
3267 bfd_vma value;
3268
3269 value = h->root.u.def.value;
3270 if (sec->output_section != NULL)
3271 /* PR 21180: If the output section is NULL, then the symbol is no
3272 longer needed, and in theory the GOT entry is redundant. But
3273 it is too late to change our minds now... */
3274 value += sec->output_section->vma + sec->output_offset;
3275
3276 microblaze_elf_output_dynamic_relocation (output_bfd,
3277 srela, srela->reloc_count++,
3278 /* symindex= */ 0,
3279 R_MICROBLAZE_REL, offset,
3280 value);
3281 }
3282 else
3283 {
3284 microblaze_elf_output_dynamic_relocation (output_bfd,
3285 srela, srela->reloc_count++,
3286 h->dynindx,
3287 R_MICROBLAZE_GLOB_DAT,
3288 offset, 0);
3289 }
3290
3291 bfd_put_32 (output_bfd, (bfd_vma) 0,
3292 sgot->contents + (h->got.offset &~ (bfd_vma) 1));
3293 }
3294
3295 if (h->needs_copy)
3296 {
3297 asection *s;
3298 Elf_Internal_Rela rela;
3299 bfd_byte *loc;
3300
3301 /* This symbols needs a copy reloc. Set it up. */
3302
3303 BFD_ASSERT (h->dynindx != -1);
3304
3305 rela.r_offset = (h->root.u.def.value
3306 + h->root.u.def.section->output_section->vma
3307 + h->root.u.def.section->output_offset);
3308 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_COPY);
3309 rela.r_addend = 0;
3310 if (h->root.u.def.section == htab->elf.sdynrelro)
3311 s = htab->elf.sreldynrelro;
3312 else
3313 s = htab->elf.srelbss;
3314 loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
3315 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
3316 }
3317
3318 /* Mark some specially defined symbols as absolute. */
3319 if (h == htab->elf.hdynamic
3320 || h == htab->elf.hgot
3321 || h == htab->elf.hplt)
3322 sym->st_shndx = SHN_ABS;
3323
3324 return true;
3325 }
3326
3327
3328 /* Finish up the dynamic sections. */
3329
3330 static bool
3331 microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
3332 struct bfd_link_info *info)
3333 {
3334 bfd *dynobj;
3335 asection *sdyn, *sgot;
3336 struct elf32_mb_link_hash_table *htab;
3337
3338 htab = elf32_mb_hash_table (info);
3339 if (htab == NULL)
3340 return false;
3341
3342 dynobj = htab->elf.dynobj;
3343
3344 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
3345
3346 if (htab->elf.dynamic_sections_created)
3347 {
3348 asection *splt;
3349 Elf32_External_Dyn *dyncon, *dynconend;
3350
3351 dyncon = (Elf32_External_Dyn *) sdyn->contents;
3352 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
3353 for (; dyncon < dynconend; dyncon++)
3354 {
3355 Elf_Internal_Dyn dyn;
3356 asection *s;
3357 bool size;
3358
3359 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
3360
3361 switch (dyn.d_tag)
3362 {
3363 case DT_PLTGOT:
3364 s = htab->elf.sgotplt;
3365 size = false;
3366 break;
3367
3368 case DT_PLTRELSZ:
3369 s = htab->elf.srelplt;
3370 size = true;
3371 break;
3372
3373 case DT_JMPREL:
3374 s = htab->elf.srelplt;
3375 size = false;
3376 break;
3377
3378 default:
3379 continue;
3380 }
3381
3382 if (s == NULL)
3383 dyn.d_un.d_val = 0;
3384 else
3385 {
3386 if (!size)
3387 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
3388 else
3389 dyn.d_un.d_val = s->size;
3390 }
3391 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
3392 }
3393
3394 splt = htab->elf.splt;
3395 BFD_ASSERT (splt != NULL && sdyn != NULL);
3396
3397 /* Clear the first entry in the procedure linkage table,
3398 and put a nop in the last four bytes. */
3399 if (splt->size > 0)
3400 {
3401 memset (splt->contents, 0, PLT_ENTRY_SIZE);
3402 bfd_put_32 (output_bfd, (bfd_vma) 0x80000000 /* nop. */,
3403 splt->contents + splt->size - 4);
3404
3405 if (splt->output_section != bfd_abs_section_ptr)
3406 elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
3407 }
3408 }
3409
3410 /* Set the first entry in the global offset table to the address of
3411 the dynamic section. */
3412 sgot = htab->elf.sgotplt;
3413 if (sgot && sgot->size > 0)
3414 {
3415 if (sdyn == NULL)
3416 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
3417 else
3418 bfd_put_32 (output_bfd,
3419 sdyn->output_section->vma + sdyn->output_offset,
3420 sgot->contents);
3421 elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
3422 }
3423
3424 if (htab->elf.sgot && htab->elf.sgot->size > 0)
3425 elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4;
3426
3427 return true;
3428 }
3429
3430 /* Hook called by the linker routine which adds symbols from an object
3431 file. We use it to put .comm items in .sbss, and not .bss. */
3432
3433 static bool
3434 microblaze_elf_add_symbol_hook (bfd *abfd,
3435 struct bfd_link_info *info,
3436 Elf_Internal_Sym *sym,
3437 const char **namep ATTRIBUTE_UNUSED,
3438 flagword *flagsp ATTRIBUTE_UNUSED,
3439 asection **secp,
3440 bfd_vma *valp)
3441 {
3442 if (sym->st_shndx == SHN_COMMON
3443 && !bfd_link_relocatable (info)
3444 && sym->st_size <= elf_gp_size (abfd))
3445 {
3446 /* Common symbols less than or equal to -G nn bytes are automatically
3447 put into .sbss. */
3448 *secp = bfd_make_section_old_way (abfd, ".sbss");
3449 if (*secp == NULL
3450 || !bfd_set_section_flags (*secp, SEC_IS_COMMON | SEC_SMALL_DATA))
3451 return false;
3452
3453 *valp = sym->st_size;
3454 }
3455
3456 return true;
3457 }
3458
3459 #define TARGET_LITTLE_SYM microblaze_elf32_le_vec
3460 #define TARGET_LITTLE_NAME "elf32-microblazeel"
3461
3462 #define TARGET_BIG_SYM microblaze_elf32_vec
3463 #define TARGET_BIG_NAME "elf32-microblaze"
3464
3465 #define ELF_ARCH bfd_arch_microblaze
3466 #define ELF_TARGET_ID MICROBLAZE_ELF_DATA
3467 #define ELF_MACHINE_CODE EM_MICROBLAZE
3468 #define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
3469 #define ELF_MAXPAGESIZE 0x1000
3470 #define elf_info_to_howto microblaze_elf_info_to_howto
3471 #define elf_info_to_howto_rel NULL
3472
3473 #define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
3474 #define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name
3475 #define bfd_elf32_new_section_hook microblaze_elf_new_section_hook
3476 #define elf_backend_relocate_section microblaze_elf_relocate_section
3477 #define bfd_elf32_bfd_relax_section microblaze_elf_relax_section
3478 #define bfd_elf32_bfd_merge_private_bfd_data _bfd_generic_verify_endian_match
3479 #define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
3480
3481 #define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
3482 #define elf_backend_check_relocs microblaze_elf_check_relocs
3483 #define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
3484 #define bfd_elf32_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
3485 #define elf_backend_can_gc_sections 1
3486 #define elf_backend_can_refcount 1
3487 #define elf_backend_want_got_plt 1
3488 #define elf_backend_plt_readonly 1
3489 #define elf_backend_got_header_size 12
3490 #define elf_backend_want_dynrelro 1
3491 #define elf_backend_rela_normal 1
3492 #define elf_backend_dtrel_excludes_plt 1
3493
3494 #define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
3495 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
3496 #define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
3497 #define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
3498 #define elf_backend_late_size_sections microblaze_elf_late_size_sections
3499 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
3500
3501 #include "elf32-target.h"
3502