]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - bfd/elf32-microblaze.c
Automatic date update in version.in
[thirdparty/binutils-gdb.git] / bfd / elf32-microblaze.c
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 \f
548 /* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */
549
550 static void
551 microblaze_elf_howto_init (void)
552 {
553 unsigned int i;
554
555 for (i = NUM_ELEM (microblaze_elf_howto_raw); i--;)
556 {
557 unsigned int type;
558
559 type = microblaze_elf_howto_raw[i].type;
560
561 BFD_ASSERT (type < NUM_ELEM (microblaze_elf_howto_table));
562
563 microblaze_elf_howto_table [type] = & microblaze_elf_howto_raw [i];
564 }
565 }
566 \f
567 static reloc_howto_type *
568 microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
569 bfd_reloc_code_real_type code)
570 {
571 enum elf_microblaze_reloc_type microblaze_reloc = R_MICROBLAZE_NONE;
572
573 switch (code)
574 {
575 case BFD_RELOC_NONE:
576 microblaze_reloc = R_MICROBLAZE_NONE;
577 break;
578 case BFD_RELOC_MICROBLAZE_32_NONE:
579 microblaze_reloc = R_MICROBLAZE_32_NONE;
580 break;
581 case BFD_RELOC_MICROBLAZE_64_NONE:
582 microblaze_reloc = R_MICROBLAZE_64_NONE;
583 break;
584 case BFD_RELOC_32:
585 microblaze_reloc = R_MICROBLAZE_32;
586 break;
587 /* RVA is treated the same as 32 */
588 case BFD_RELOC_RVA:
589 microblaze_reloc = R_MICROBLAZE_32;
590 break;
591 case BFD_RELOC_32_PCREL:
592 microblaze_reloc = R_MICROBLAZE_32_PCREL;
593 break;
594 case BFD_RELOC_64_PCREL:
595 microblaze_reloc = R_MICROBLAZE_64_PCREL;
596 break;
597 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
598 microblaze_reloc = R_MICROBLAZE_32_PCREL_LO;
599 break;
600 case BFD_RELOC_64:
601 microblaze_reloc = R_MICROBLAZE_64;
602 break;
603 case BFD_RELOC_MICROBLAZE_32_LO:
604 microblaze_reloc = R_MICROBLAZE_32_LO;
605 break;
606 case BFD_RELOC_MICROBLAZE_32_ROSDA:
607 microblaze_reloc = R_MICROBLAZE_SRO32;
608 break;
609 case BFD_RELOC_MICROBLAZE_32_RWSDA:
610 microblaze_reloc = R_MICROBLAZE_SRW32;
611 break;
612 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
613 microblaze_reloc = R_MICROBLAZE_32_SYM_OP_SYM;
614 break;
615 case BFD_RELOC_VTABLE_INHERIT:
616 microblaze_reloc = R_MICROBLAZE_GNU_VTINHERIT;
617 break;
618 case BFD_RELOC_VTABLE_ENTRY:
619 microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
620 break;
621 case BFD_RELOC_MICROBLAZE_64_GOTPC:
622 microblaze_reloc = R_MICROBLAZE_GOTPC_64;
623 break;
624 case BFD_RELOC_MICROBLAZE_64_GOT:
625 microblaze_reloc = R_MICROBLAZE_GOT_64;
626 break;
627 case BFD_RELOC_MICROBLAZE_64_TEXTPCREL:
628 microblaze_reloc = R_MICROBLAZE_TEXTPCREL_64;
629 break;
630 case BFD_RELOC_MICROBLAZE_64_TEXTREL:
631 microblaze_reloc = R_MICROBLAZE_TEXTREL_64;
632 break;
633 case BFD_RELOC_MICROBLAZE_64_PLT:
634 microblaze_reloc = R_MICROBLAZE_PLT_64;
635 break;
636 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
637 microblaze_reloc = R_MICROBLAZE_GOTOFF_64;
638 break;
639 case BFD_RELOC_MICROBLAZE_32_GOTOFF:
640 microblaze_reloc = R_MICROBLAZE_GOTOFF_32;
641 break;
642 case BFD_RELOC_MICROBLAZE_64_TLSGD:
643 microblaze_reloc = R_MICROBLAZE_TLSGD;
644 break;
645 case BFD_RELOC_MICROBLAZE_64_TLSLD:
646 microblaze_reloc = R_MICROBLAZE_TLSLD;
647 break;
648 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
649 microblaze_reloc = R_MICROBLAZE_TLSDTPREL32;
650 break;
651 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
652 microblaze_reloc = R_MICROBLAZE_TLSDTPREL64;
653 break;
654 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
655 microblaze_reloc = R_MICROBLAZE_TLSDTPMOD32;
656 break;
657 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
658 microblaze_reloc = R_MICROBLAZE_TLSGOTTPREL32;
659 break;
660 case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
661 microblaze_reloc = R_MICROBLAZE_TLSTPREL32;
662 break;
663 case BFD_RELOC_MICROBLAZE_COPY:
664 microblaze_reloc = R_MICROBLAZE_COPY;
665 break;
666 default:
667 return (reloc_howto_type *) NULL;
668 }
669
670 if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
671 /* Initialize howto table if needed. */
672 microblaze_elf_howto_init ();
673
674 return microblaze_elf_howto_table [(int) microblaze_reloc];
675 };
676
677 static reloc_howto_type *
678 microblaze_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
679 const char *r_name)
680 {
681 unsigned int i;
682
683 for (i = 0; i < NUM_ELEM (microblaze_elf_howto_raw); i++)
684 if (microblaze_elf_howto_raw[i].name != NULL
685 && strcasecmp (microblaze_elf_howto_raw[i].name, r_name) == 0)
686 return &microblaze_elf_howto_raw[i];
687
688 return NULL;
689 }
690
691 /* Set the howto pointer for a RCE ELF reloc. */
692
693 static bool
694 microblaze_elf_info_to_howto (bfd * abfd,
695 arelent * cache_ptr,
696 Elf_Internal_Rela * dst)
697 {
698 unsigned int r_type;
699
700 if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
701 /* Initialize howto table if needed. */
702 microblaze_elf_howto_init ();
703
704 r_type = ELF32_R_TYPE (dst->r_info);
705 if (r_type >= R_MICROBLAZE_max)
706 {
707 /* xgettext:c-format */
708 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
709 abfd, r_type);
710 bfd_set_error (bfd_error_bad_value);
711 return false;
712 }
713
714 cache_ptr->howto = microblaze_elf_howto_table [r_type];
715 return true;
716 }
717
718 /* Relax table contains information about instructions which can
719 be removed by relaxation -- replacing a long address with a
720 short address. */
721 struct relax_table
722 {
723 /* Address where bytes may be deleted. */
724 bfd_vma addr;
725
726 /* Number of bytes to be deleted. */
727 size_t size;
728 };
729
730 struct _microblaze_elf_section_data
731 {
732 struct bfd_elf_section_data elf;
733 /* Count of used relaxation table entries. */
734 size_t relax_count;
735 /* Relaxation table. */
736 struct relax_table *relax;
737 };
738
739 #define microblaze_elf_section_data(sec) \
740 ((struct _microblaze_elf_section_data *) elf_section_data (sec))
741
742 static bool
743 microblaze_elf_new_section_hook (bfd *abfd, asection *sec)
744 {
745 if (!sec->used_by_bfd)
746 {
747 struct _microblaze_elf_section_data *sdata;
748 size_t amt = sizeof (*sdata);
749
750 sdata = bfd_zalloc (abfd, amt);
751 if (sdata == NULL)
752 return false;
753 sec->used_by_bfd = sdata;
754 }
755
756 return _bfd_elf_new_section_hook (abfd, sec);
757 }
758
759 /* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
760
761 static bool
762 microblaze_elf_is_local_label_name (bfd *abfd, const char *name)
763 {
764 if (name[0] == 'L' && name[1] == '.')
765 return true;
766
767 if (name[0] == '$' && name[1] == 'L')
768 return true;
769
770 /* With gcc, the labels go back to starting with '.', so we accept
771 the generic ELF local label syntax as well. */
772 return _bfd_elf_is_local_label_name (abfd, name);
773 }
774
775 /* ELF linker hash entry. */
776
777 struct elf32_mb_link_hash_entry
778 {
779 struct elf_link_hash_entry elf;
780
781 /* TLS Reference Types for the symbol; Updated by check_relocs */
782 #define TLS_GD 1 /* GD reloc. */
783 #define TLS_LD 2 /* LD reloc. */
784 #define TLS_TPREL 4 /* TPREL reloc, => IE. */
785 #define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
786 #define TLS_TLS 16 /* Any TLS reloc. */
787 unsigned char tls_mask;
788
789 };
790
791 #define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD))
792 #define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD))
793 #define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL))
794 #define IS_TLS_NONE(x) (x == 0)
795
796 #define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent))
797
798 /* ELF linker hash table. */
799
800 struct elf32_mb_link_hash_table
801 {
802 struct elf_link_hash_table elf;
803
804 /* TLS Local Dynamic GOT Entry */
805 union {
806 bfd_signed_vma refcount;
807 bfd_vma offset;
808 } tlsld_got;
809 };
810
811 /* Nonzero if this section has TLS related relocations. */
812 #define has_tls_reloc sec_flg0
813
814 /* Get the ELF linker hash table from a link_info structure. */
815
816 #define elf32_mb_hash_table(p) \
817 ((is_elf_hash_table ((p)->hash) \
818 && elf_hash_table_id (elf_hash_table (p)) == MICROBLAZE_ELF_DATA) \
819 ? (struct elf32_mb_link_hash_table *) (p)->hash : NULL)
820
821 /* Create an entry in a microblaze ELF linker hash table. */
822
823 static struct bfd_hash_entry *
824 link_hash_newfunc (struct bfd_hash_entry *entry,
825 struct bfd_hash_table *table,
826 const char *string)
827 {
828 /* Allocate the structure if it has not already been allocated by a
829 subclass. */
830 if (entry == NULL)
831 {
832 entry = bfd_hash_allocate (table,
833 sizeof (struct elf32_mb_link_hash_entry));
834 if (entry == NULL)
835 return entry;
836 }
837
838 /* Call the allocation method of the superclass. */
839 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
840 if (entry != NULL)
841 {
842 struct elf32_mb_link_hash_entry *eh;
843
844 eh = (struct elf32_mb_link_hash_entry *) entry;
845 eh->tls_mask = 0;
846 }
847
848 return entry;
849 }
850
851 /* Create a mb ELF linker hash table. */
852
853 static struct bfd_link_hash_table *
854 microblaze_elf_link_hash_table_create (bfd *abfd)
855 {
856 struct elf32_mb_link_hash_table *ret;
857 size_t amt = sizeof (struct elf32_mb_link_hash_table);
858
859 ret = (struct elf32_mb_link_hash_table *) bfd_zmalloc (amt);
860 if (ret == NULL)
861 return NULL;
862
863 if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
864 sizeof (struct elf32_mb_link_hash_entry),
865 MICROBLAZE_ELF_DATA))
866 {
867 free (ret);
868 return NULL;
869 }
870
871 return &ret->elf.root;
872 }
873 \f
874 /* Set the values of the small data pointers. */
875
876 static void
877 microblaze_elf_final_sdp (struct bfd_link_info *info)
878 {
879 struct bfd_link_hash_entry *h;
880
881 h = bfd_link_hash_lookup (info->hash, RO_SDA_ANCHOR_NAME, false, false, true);
882 if (h != (struct bfd_link_hash_entry *) NULL
883 && h->type == bfd_link_hash_defined)
884 ro_small_data_pointer = (h->u.def.value
885 + h->u.def.section->output_section->vma
886 + h->u.def.section->output_offset);
887
888 h = bfd_link_hash_lookup (info->hash, RW_SDA_ANCHOR_NAME, false, false, true);
889 if (h != (struct bfd_link_hash_entry *) NULL
890 && h->type == bfd_link_hash_defined)
891 rw_small_data_pointer = (h->u.def.value
892 + h->u.def.section->output_section->vma
893 + h->u.def.section->output_offset);
894 }
895
896 static bfd_vma
897 dtprel_base (struct bfd_link_info *info)
898 {
899 /* If tls_sec is NULL, we should have signalled an error already. */
900 if (elf_hash_table (info)->tls_sec == NULL)
901 return 0;
902 return elf_hash_table (info)->tls_sec->vma;
903 }
904
905 /* The size of the thread control block. */
906 #define TCB_SIZE 8
907
908 /* Output a simple dynamic relocation into SRELOC. */
909
910 static void
911 microblaze_elf_output_dynamic_relocation (bfd *output_bfd,
912 asection *sreloc,
913 unsigned long reloc_index,
914 unsigned long indx,
915 int r_type,
916 bfd_vma offset,
917 bfd_vma addend)
918 {
919
920 Elf_Internal_Rela rel;
921
922 rel.r_info = ELF32_R_INFO (indx, r_type);
923 rel.r_offset = offset;
924 rel.r_addend = addend;
925
926 bfd_elf32_swap_reloca_out (output_bfd, &rel,
927 (sreloc->contents + reloc_index * sizeof (Elf32_External_Rela)));
928 }
929
930 /* This code is taken from elf32-m32r.c
931 There is some attempt to make this function usable for many architectures,
932 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
933 if only to serve as a learning tool.
934
935 The RELOCATE_SECTION function is called by the new ELF backend linker
936 to handle the relocations for a section.
937
938 The relocs are always passed as Rela structures; if the section
939 actually uses Rel structures, the r_addend field will always be
940 zero.
941
942 This function is responsible for adjust the section contents as
943 necessary, and (if using Rela relocs and generating a
944 relocatable output file) adjusting the reloc addend as
945 necessary.
946
947 This function does not have to worry about setting the reloc
948 address or the reloc symbol index.
949
950 LOCAL_SYMS is a pointer to the swapped in local symbols.
951
952 LOCAL_SECTIONS is an array giving the section in the input file
953 corresponding to the st_shndx field of each local symbol.
954
955 The global hash table entry for the global symbols can be found
956 via elf_sym_hashes (input_bfd).
957
958 When generating relocatable output, this function must handle
959 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
960 going to be the section symbol corresponding to the output
961 section, which means that the addend must be adjusted
962 accordingly. */
963
964 static int
965 microblaze_elf_relocate_section (bfd *output_bfd,
966 struct bfd_link_info *info,
967 bfd *input_bfd,
968 asection *input_section,
969 bfd_byte *contents,
970 Elf_Internal_Rela *relocs,
971 Elf_Internal_Sym *local_syms,
972 asection **local_sections)
973 {
974 struct elf32_mb_link_hash_table *htab;
975 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
976 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
977 Elf_Internal_Rela *rel, *relend;
978 int endian = (bfd_little_endian (output_bfd)) ? 0 : 2;
979 /* Assume success. */
980 bool ret = true;
981 asection *sreloc;
982 bfd_vma *local_got_offsets;
983 unsigned int tls_type;
984
985 if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1])
986 microblaze_elf_howto_init ();
987
988 htab = elf32_mb_hash_table (info);
989 if (htab == NULL)
990 return false;
991
992 local_got_offsets = elf_local_got_offsets (input_bfd);
993
994 sreloc = elf_section_data (input_section)->sreloc;
995
996 rel = relocs;
997 relend = relocs + input_section->reloc_count;
998 for (; rel < relend; rel++)
999 {
1000 int r_type;
1001 reloc_howto_type *howto;
1002 unsigned long r_symndx;
1003 bfd_vma addend = rel->r_addend;
1004 bfd_vma offset = rel->r_offset;
1005 struct elf_link_hash_entry *h;
1006 Elf_Internal_Sym *sym;
1007 asection *sec;
1008 const char *sym_name;
1009 bfd_reloc_status_type r = bfd_reloc_ok;
1010 const char *errmsg = NULL;
1011 bool unresolved_reloc = false;
1012
1013 h = NULL;
1014 r_type = ELF32_R_TYPE (rel->r_info);
1015 tls_type = 0;
1016
1017 if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max)
1018 {
1019 /* xgettext:c-format */
1020 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
1021 input_bfd, (int) r_type);
1022 bfd_set_error (bfd_error_bad_value);
1023 ret = false;
1024 continue;
1025 }
1026
1027 howto = microblaze_elf_howto_table[r_type];
1028 r_symndx = ELF32_R_SYM (rel->r_info);
1029
1030 if (bfd_link_relocatable (info))
1031 {
1032 /* This is a relocatable link. We don't have to change
1033 anything, unless the reloc is against a section symbol,
1034 in which case we have to adjust according to where the
1035 section symbol winds up in the output section. */
1036 sec = NULL;
1037 if (r_symndx >= symtab_hdr->sh_info)
1038 /* External symbol. */
1039 continue;
1040
1041 /* Local symbol. */
1042 sym = local_syms + r_symndx;
1043 sym_name = "<local symbol>";
1044 /* STT_SECTION: symbol is associated with a section. */
1045 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
1046 /* Symbol isn't associated with a section. Nothing to do. */
1047 continue;
1048
1049 sec = local_sections[r_symndx];
1050 addend += sec->output_offset + sym->st_value;
1051 #ifndef USE_REL
1052 /* This can't be done for USE_REL because it doesn't mean anything
1053 and elf_link_input_bfd asserts this stays zero. */
1054 /* rel->r_addend = addend; */
1055 #endif
1056
1057 #ifndef USE_REL
1058 /* Addends are stored with relocs. We're done. */
1059 continue;
1060 #else /* USE_REL */
1061 /* If partial_inplace, we need to store any additional addend
1062 back in the section. */
1063 if (!howto->partial_inplace)
1064 continue;
1065 /* ??? Here is a nice place to call a special_function like handler. */
1066 r = _bfd_relocate_contents (howto, input_bfd, addend,
1067 contents + offset);
1068 #endif /* USE_REL */
1069 }
1070 else
1071 {
1072 bfd_vma relocation;
1073 bool resolved_to_zero;
1074
1075 /* This is a final link. */
1076 sym = NULL;
1077 sec = NULL;
1078 unresolved_reloc = false;
1079
1080 if (r_symndx < symtab_hdr->sh_info)
1081 {
1082 /* Local symbol. */
1083 sym = local_syms + r_symndx;
1084 sec = local_sections[r_symndx];
1085 if (sec == 0)
1086 continue;
1087 sym_name = "<local symbol>";
1088 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1089 /* r_addend may have changed if the reference section was
1090 a merge section. */
1091 addend = rel->r_addend;
1092 }
1093 else
1094 {
1095 /* External symbol. */
1096 bool warned ATTRIBUTE_UNUSED;
1097 bool ignored ATTRIBUTE_UNUSED;
1098
1099 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1100 r_symndx, symtab_hdr, sym_hashes,
1101 h, sec, relocation,
1102 unresolved_reloc, warned, ignored);
1103 sym_name = h->root.root.string;
1104 }
1105
1106 /* Sanity check the address. */
1107 if (offset > bfd_get_section_limit (input_bfd, input_section))
1108 {
1109 r = bfd_reloc_outofrange;
1110 goto check_reloc;
1111 }
1112
1113 resolved_to_zero = (h != NULL
1114 && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
1115
1116 switch ((int) r_type)
1117 {
1118 case (int) R_MICROBLAZE_SRO32 :
1119 {
1120 const char *name;
1121
1122 /* Only relocate if the symbol is defined. */
1123 if (sec)
1124 {
1125 name = bfd_section_name (sec);
1126
1127 if (strcmp (name, ".sdata2") == 0
1128 || strcmp (name, ".sbss2") == 0)
1129 {
1130 if (ro_small_data_pointer == 0)
1131 microblaze_elf_final_sdp (info);
1132 if (ro_small_data_pointer == 0)
1133 {
1134 ret = false;
1135 r = bfd_reloc_undefined;
1136 goto check_reloc;
1137 }
1138
1139 /* At this point `relocation' contains the object's
1140 address. */
1141 relocation -= ro_small_data_pointer;
1142 /* Now it contains the offset from _SDA2_BASE_. */
1143 r = _bfd_final_link_relocate (howto, input_bfd,
1144 input_section,
1145 contents, offset,
1146 relocation, addend);
1147 }
1148 else
1149 {
1150 _bfd_error_handler
1151 /* xgettext:c-format */
1152 (_("%pB: the target (%s) of an %s relocation"
1153 " is in the wrong section (%pA)"),
1154 input_bfd,
1155 sym_name,
1156 microblaze_elf_howto_table[(int) r_type]->name,
1157 sec);
1158 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1159 ret = false;
1160 continue;
1161 }
1162 }
1163 }
1164 break;
1165
1166 case (int) R_MICROBLAZE_SRW32 :
1167 {
1168 const char *name;
1169
1170 /* Only relocate if the symbol is defined. */
1171 if (sec)
1172 {
1173 name = bfd_section_name (sec);
1174
1175 if (strcmp (name, ".sdata") == 0
1176 || strcmp (name, ".sbss") == 0)
1177 {
1178 if (rw_small_data_pointer == 0)
1179 microblaze_elf_final_sdp (info);
1180 if (rw_small_data_pointer == 0)
1181 {
1182 ret = false;
1183 r = bfd_reloc_undefined;
1184 goto check_reloc;
1185 }
1186
1187 /* At this point `relocation' contains the object's
1188 address. */
1189 relocation -= rw_small_data_pointer;
1190 /* Now it contains the offset from _SDA_BASE_. */
1191 r = _bfd_final_link_relocate (howto, input_bfd,
1192 input_section,
1193 contents, offset,
1194 relocation, addend);
1195 }
1196 else
1197 {
1198 _bfd_error_handler
1199 /* xgettext:c-format */
1200 (_("%pB: the target (%s) of an %s relocation"
1201 " is in the wrong section (%pA)"),
1202 input_bfd,
1203 sym_name,
1204 microblaze_elf_howto_table[(int) r_type]->name,
1205 sec);
1206 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1207 ret = false;
1208 continue;
1209 }
1210 }
1211 }
1212 break;
1213
1214 case (int) R_MICROBLAZE_32_SYM_OP_SYM:
1215 break; /* Do nothing. */
1216
1217 case (int) R_MICROBLAZE_GOTPC_64:
1218 relocation = (htab->elf.sgotplt->output_section->vma
1219 + htab->elf.sgotplt->output_offset);
1220 relocation -= (input_section->output_section->vma
1221 + input_section->output_offset
1222 + offset + INST_WORD_SIZE);
1223 relocation += addend;
1224 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1225 contents + offset + endian);
1226 bfd_put_16 (input_bfd, relocation & 0xffff,
1227 contents + offset + endian + INST_WORD_SIZE);
1228 break;
1229
1230 case (int) R_MICROBLAZE_TEXTPCREL_64:
1231 relocation = input_section->output_section->vma;
1232 relocation -= (input_section->output_section->vma
1233 + input_section->output_offset
1234 + offset + INST_WORD_SIZE);
1235 relocation += addend;
1236 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1237 contents + offset + endian);
1238 bfd_put_16 (input_bfd, relocation & 0xffff,
1239 contents + offset + endian + INST_WORD_SIZE);
1240 break;
1241
1242 case (int) R_MICROBLAZE_PLT_64:
1243 {
1244 bfd_vma immediate;
1245 if (htab->elf.splt != NULL && h != NULL
1246 && h->plt.offset != (bfd_vma) -1)
1247 {
1248 relocation = (htab->elf.splt->output_section->vma
1249 + htab->elf.splt->output_offset
1250 + h->plt.offset);
1251 unresolved_reloc = false;
1252 immediate = relocation - (input_section->output_section->vma
1253 + input_section->output_offset
1254 + offset + INST_WORD_SIZE);
1255 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
1256 contents + offset + endian);
1257 bfd_put_16 (input_bfd, immediate & 0xffff,
1258 contents + offset + endian + INST_WORD_SIZE);
1259 }
1260 else
1261 {
1262 relocation -= (input_section->output_section->vma
1263 + input_section->output_offset
1264 + offset + INST_WORD_SIZE);
1265 immediate = relocation;
1266 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
1267 contents + offset + endian);
1268 bfd_put_16 (input_bfd, immediate & 0xffff,
1269 contents + offset + endian + INST_WORD_SIZE);
1270 }
1271 break;
1272 }
1273
1274 case (int) R_MICROBLAZE_TLSGD:
1275 tls_type = (TLS_TLS | TLS_GD);
1276 goto dogot;
1277 case (int) R_MICROBLAZE_TLSLD:
1278 tls_type = (TLS_TLS | TLS_LD);
1279 /* Fall through. */
1280 dogot:
1281 case (int) R_MICROBLAZE_GOT_64:
1282 {
1283 bfd_vma *offp;
1284 bfd_vma off, off2;
1285 unsigned long indx;
1286 bfd_vma static_value;
1287
1288 bool need_relocs = false;
1289 if (htab->elf.sgot == NULL)
1290 abort ();
1291
1292 indx = 0;
1293 offp = NULL;
1294
1295 /* 1. Identify GOT Offset;
1296 2. Compute Static Values
1297 3. Process Module Id, Process Offset
1298 4. Fixup Relocation with GOT offset value. */
1299
1300 /* 1. Determine GOT Offset to use : TLS_LD, global, local */
1301 if (IS_TLS_LD (tls_type))
1302 offp = &htab->tlsld_got.offset;
1303 else if (h != NULL)
1304 {
1305 if (htab->elf.sgotplt != NULL
1306 && h->got.offset != (bfd_vma) -1)
1307 offp = &h->got.offset;
1308 else
1309 abort ();
1310 }
1311 else
1312 {
1313 if (local_got_offsets == NULL)
1314 abort ();
1315 offp = &local_got_offsets[r_symndx];
1316 }
1317
1318 if (!offp)
1319 abort ();
1320
1321 off = (*offp) & ~1;
1322 off2 = off;
1323
1324 if (IS_TLS_LD(tls_type) || IS_TLS_GD(tls_type))
1325 off2 = off + 4;
1326
1327 /* Symbol index to use for relocs */
1328 if (h != NULL)
1329 {
1330 bool dyn =
1331 elf_hash_table (info)->dynamic_sections_created;
1332
1333 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
1334 bfd_link_pic (info),
1335 h)
1336 && (!bfd_link_pic (info)
1337 || !SYMBOL_REFERENCES_LOCAL (info, h)))
1338 indx = h->dynindx;
1339 }
1340
1341 /* Need to generate relocs ? */
1342 if ((bfd_link_pic (info) || indx != 0)
1343 && (h == NULL
1344 || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1345 && !resolved_to_zero)
1346 || h->root.type != bfd_link_hash_undefweak))
1347 need_relocs = true;
1348
1349 /* 2. Compute/Emit Static value of r-expression */
1350 static_value = relocation + addend;
1351
1352 /* 3. Process module-id and offset */
1353 if (! ((*offp) & 1) )
1354 {
1355 bfd_vma got_offset;
1356
1357 got_offset = (htab->elf.sgot->output_section->vma
1358 + htab->elf.sgot->output_offset
1359 + off);
1360
1361 /* Process module-id */
1362 if (IS_TLS_LD(tls_type))
1363 {
1364 if (! bfd_link_pic (info))
1365 bfd_put_32 (output_bfd, 1,
1366 htab->elf.sgot->contents + off);
1367 else
1368 microblaze_elf_output_dynamic_relocation
1369 (output_bfd,
1370 htab->elf.srelgot,
1371 htab->elf.srelgot->reloc_count++,
1372 /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32,
1373 got_offset, 0);
1374 }
1375 else if (IS_TLS_GD(tls_type))
1376 {
1377 if (! need_relocs)
1378 bfd_put_32 (output_bfd, 1,
1379 htab->elf.sgot->contents + off);
1380 else
1381 microblaze_elf_output_dynamic_relocation
1382 (output_bfd,
1383 htab->elf.srelgot,
1384 htab->elf.srelgot->reloc_count++,
1385 /* symindex= */ indx, R_MICROBLAZE_TLSDTPMOD32,
1386 got_offset, indx ? 0 : static_value);
1387 }
1388
1389 /* Process Offset */
1390 if (htab->elf.srelgot == NULL)
1391 abort ();
1392
1393 got_offset = (htab->elf.sgot->output_section->vma
1394 + htab->elf.sgot->output_offset
1395 + off2);
1396 if (IS_TLS_LD(tls_type))
1397 {
1398 /* For LD, offset should be 0 */
1399 *offp |= 1;
1400 bfd_put_32 (output_bfd, 0,
1401 htab->elf.sgot->contents + off2);
1402 }
1403 else if (IS_TLS_GD(tls_type))
1404 {
1405 *offp |= 1;
1406 static_value -= dtprel_base(info);
1407 if (need_relocs)
1408 microblaze_elf_output_dynamic_relocation
1409 (output_bfd,
1410 htab->elf.srelgot,
1411 htab->elf.srelgot->reloc_count++,
1412 /* symindex= */ indx, R_MICROBLAZE_TLSDTPREL32,
1413 got_offset, indx ? 0 : static_value);
1414 else
1415 bfd_put_32 (output_bfd, static_value,
1416 htab->elf.sgot->contents + off2);
1417 }
1418 else
1419 {
1420 bfd_put_32 (output_bfd, static_value,
1421 htab->elf.sgot->contents + off2);
1422
1423 /* Relocs for dyn symbols generated by
1424 finish_dynamic_symbols */
1425 if (bfd_link_pic (info) && h == NULL)
1426 {
1427 *offp |= 1;
1428 microblaze_elf_output_dynamic_relocation
1429 (output_bfd,
1430 htab->elf.srelgot,
1431 htab->elf.srelgot->reloc_count++,
1432 /* symindex= */ indx, R_MICROBLAZE_REL,
1433 got_offset, static_value);
1434 }
1435 }
1436 }
1437
1438 /* 4. Fixup Relocation with GOT offset value
1439 Compute relative address of GOT entry for applying
1440 the current relocation */
1441 relocation = htab->elf.sgot->output_section->vma
1442 + htab->elf.sgot->output_offset
1443 + off
1444 - htab->elf.sgotplt->output_section->vma
1445 - htab->elf.sgotplt->output_offset;
1446
1447 /* Apply Current Relocation */
1448 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1449 contents + offset + endian);
1450 bfd_put_16 (input_bfd, relocation & 0xffff,
1451 contents + offset + endian + INST_WORD_SIZE);
1452
1453 unresolved_reloc = false;
1454 break;
1455 }
1456
1457 case (int) R_MICROBLAZE_GOTOFF_64:
1458 {
1459 bfd_vma immediate;
1460 unsigned short lo, high;
1461 relocation += addend;
1462 relocation -= (htab->elf.sgotplt->output_section->vma
1463 + htab->elf.sgotplt->output_offset);
1464 /* Write this value into correct location. */
1465 immediate = relocation;
1466 lo = immediate & 0x0000ffff;
1467 high = (immediate >> 16) & 0x0000ffff;
1468 bfd_put_16 (input_bfd, high, contents + offset + endian);
1469 bfd_put_16 (input_bfd, lo,
1470 contents + offset + INST_WORD_SIZE + endian);
1471 break;
1472 }
1473
1474 case (int) R_MICROBLAZE_GOTOFF_32:
1475 {
1476 relocation += addend;
1477 relocation -= (htab->elf.sgotplt->output_section->vma
1478 + htab->elf.sgotplt->output_offset);
1479 /* Write this value into correct location. */
1480 bfd_put_32 (input_bfd, relocation, contents + offset);
1481 break;
1482 }
1483
1484 case (int) R_MICROBLAZE_TLSDTPREL64:
1485 relocation += addend;
1486 relocation -= dtprel_base(info);
1487 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1488 contents + offset + endian);
1489 bfd_put_16 (input_bfd, relocation & 0xffff,
1490 contents + offset + endian + INST_WORD_SIZE);
1491 break;
1492 case (int) R_MICROBLAZE_TEXTREL_64:
1493 case (int) R_MICROBLAZE_TEXTREL_32_LO:
1494 case (int) R_MICROBLAZE_64_PCREL :
1495 case (int) R_MICROBLAZE_64:
1496 case (int) R_MICROBLAZE_32:
1497 {
1498 /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
1499 from removed linkonce sections, or sections discarded by
1500 a linker script. */
1501 if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
1502 {
1503 relocation += addend;
1504 if (r_type == R_MICROBLAZE_32)
1505 bfd_put_32 (input_bfd, relocation, contents + offset);
1506 else
1507 {
1508 if (r_type == R_MICROBLAZE_64_PCREL)
1509 relocation -= (input_section->output_section->vma
1510 + input_section->output_offset
1511 + offset + INST_WORD_SIZE);
1512 else if (r_type == R_MICROBLAZE_TEXTREL_64
1513 || r_type == R_MICROBLAZE_TEXTREL_32_LO)
1514 relocation -= input_section->output_section->vma;
1515
1516 if (r_type == R_MICROBLAZE_TEXTREL_32_LO)
1517 bfd_put_16 (input_bfd, relocation & 0xffff,
1518 contents + offset + endian);
1519
1520 else
1521 {
1522 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1523 contents + offset + endian);
1524 bfd_put_16 (input_bfd, relocation & 0xffff,
1525 contents + offset + endian + INST_WORD_SIZE);
1526 }
1527 }
1528 break;
1529 }
1530
1531 if ((bfd_link_pic (info)
1532 && (h == NULL
1533 || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1534 && !resolved_to_zero)
1535 || h->root.type != bfd_link_hash_undefweak)
1536 && (!howto->pc_relative
1537 || (h != NULL
1538 && h->dynindx != -1
1539 && (!info->symbolic
1540 || !h->def_regular))))
1541 || (!bfd_link_pic (info)
1542 && h != NULL
1543 && h->dynindx != -1
1544 && !h->non_got_ref
1545 && ((h->def_dynamic
1546 && !h->def_regular)
1547 || h->root.type == bfd_link_hash_undefweak
1548 || h->root.type == bfd_link_hash_undefined)))
1549 {
1550 Elf_Internal_Rela outrel;
1551 bfd_byte *loc;
1552 bool skip;
1553
1554 /* When generating a shared object, these relocations
1555 are copied into the output file to be resolved at run
1556 time. */
1557
1558 BFD_ASSERT (sreloc != NULL);
1559
1560 skip = false;
1561
1562 outrel.r_offset =
1563 _bfd_elf_section_offset (output_bfd, info, input_section,
1564 rel->r_offset);
1565 if (outrel.r_offset == (bfd_vma) -1)
1566 skip = true;
1567 else if (outrel.r_offset == (bfd_vma) -2)
1568 skip = true;
1569 outrel.r_offset += (input_section->output_section->vma
1570 + input_section->output_offset);
1571
1572 if (skip)
1573 memset (&outrel, 0, sizeof outrel);
1574 /* h->dynindx may be -1 if the symbol was marked to
1575 become local. */
1576 else if (h != NULL
1577 && ((! info->symbolic && h->dynindx != -1)
1578 || !h->def_regular))
1579 {
1580 BFD_ASSERT (h->dynindx != -1);
1581 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1582 outrel.r_addend = addend;
1583 }
1584 else
1585 {
1586 if (r_type == R_MICROBLAZE_32)
1587 {
1588 outrel.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL);
1589 outrel.r_addend = relocation + addend;
1590 }
1591 else
1592 {
1593 BFD_FAIL ();
1594 _bfd_error_handler
1595 (_("%pB: probably compiled without -fPIC?"),
1596 input_bfd);
1597 bfd_set_error (bfd_error_bad_value);
1598 return false;
1599 }
1600 }
1601
1602 loc = sreloc->contents;
1603 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
1604 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1605 break;
1606 }
1607 else
1608 {
1609 relocation += addend;
1610 if (r_type == R_MICROBLAZE_32)
1611 bfd_put_32 (input_bfd, relocation, contents + offset);
1612 else
1613 {
1614 if (r_type == R_MICROBLAZE_64_PCREL)
1615 relocation -= (input_section->output_section->vma
1616 + input_section->output_offset
1617 + offset + INST_WORD_SIZE);
1618 else if (r_type == R_MICROBLAZE_TEXTREL_64
1619 || r_type == R_MICROBLAZE_TEXTREL_32_LO)
1620 relocation -= input_section->output_section->vma;
1621
1622 if (r_type == R_MICROBLAZE_TEXTREL_32_LO)
1623 {
1624 bfd_put_16 (input_bfd, relocation & 0xffff,
1625 contents + offset + endian);
1626 }
1627 else
1628 {
1629 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1630 contents + offset + endian);
1631 bfd_put_16 (input_bfd, relocation & 0xffff,
1632 contents + offset + endian
1633 + INST_WORD_SIZE);
1634 }
1635 }
1636 break;
1637 }
1638 }
1639
1640 default :
1641 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1642 contents, offset,
1643 relocation, addend);
1644 break;
1645 }
1646 }
1647
1648 check_reloc:
1649
1650 if (r != bfd_reloc_ok)
1651 {
1652 /* FIXME: This should be generic enough to go in a utility. */
1653 const char *name;
1654
1655 if (h != NULL)
1656 name = h->root.root.string;
1657 else
1658 {
1659 name = (bfd_elf_string_from_elf_section
1660 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1661 if (name == NULL || *name == '\0')
1662 name = bfd_section_name (sec);
1663 }
1664
1665 if (errmsg != NULL)
1666 goto common_error;
1667
1668 switch (r)
1669 {
1670 case bfd_reloc_overflow:
1671 (*info->callbacks->reloc_overflow)
1672 (info, (h ? &h->root : NULL), name, howto->name,
1673 (bfd_vma) 0, input_bfd, input_section, offset);
1674 break;
1675
1676 case bfd_reloc_undefined:
1677 (*info->callbacks->undefined_symbol)
1678 (info, name, input_bfd, input_section, offset, true);
1679 break;
1680
1681 case bfd_reloc_outofrange:
1682 errmsg = _("internal error: out of range error");
1683 goto common_error;
1684
1685 case bfd_reloc_notsupported:
1686 errmsg = _("internal error: unsupported relocation error");
1687 goto common_error;
1688
1689 case bfd_reloc_dangerous:
1690 errmsg = _("internal error: dangerous error");
1691 goto common_error;
1692
1693 default:
1694 errmsg = _("internal error: unknown error");
1695 /* Fall through. */
1696 common_error:
1697 (*info->callbacks->warning) (info, errmsg, name, input_bfd,
1698 input_section, offset);
1699 break;
1700 }
1701 }
1702 }
1703
1704 return ret;
1705 }
1706 \f
1707 /* Calculate fixup value for reference. */
1708
1709 static size_t
1710 calc_fixup (bfd_vma start, bfd_vma size, asection *sec)
1711 {
1712 bfd_vma end = start + size;
1713 size_t i, fixup = 0;
1714 struct _microblaze_elf_section_data *sdata;
1715
1716 if (sec == NULL || (sdata = microblaze_elf_section_data (sec)) == NULL)
1717 return 0;
1718
1719 /* Look for addr in relax table, total fixup value. */
1720 for (i = 0; i < sdata->relax_count; i++)
1721 {
1722 if (end <= sdata->relax[i].addr)
1723 break;
1724 if (end != start && start > sdata->relax[i].addr)
1725 continue;
1726 fixup += sdata->relax[i].size;
1727 }
1728 return fixup;
1729 }
1730
1731 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1732 a 32-bit instruction. */
1733 static void
1734 microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1735 {
1736 unsigned long instr = bfd_get_32 (abfd, bfd_addr);
1737 instr &= ~0x0000ffff;
1738 instr |= (val & 0x0000ffff);
1739 bfd_put_32 (abfd, instr, bfd_addr);
1740 }
1741
1742 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1743 two consecutive 32-bit instructions. */
1744 static void
1745 microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1746 {
1747 unsigned long instr_hi;
1748 unsigned long instr_lo;
1749
1750 instr_hi = bfd_get_32 (abfd, bfd_addr);
1751 instr_hi &= ~0x0000ffff;
1752 instr_hi |= ((val >> 16) & 0x0000ffff);
1753 bfd_put_32 (abfd, instr_hi, bfd_addr);
1754
1755 instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE);
1756 instr_lo &= ~0x0000ffff;
1757 instr_lo |= (val & 0x0000ffff);
1758 bfd_put_32 (abfd, instr_lo, bfd_addr + INST_WORD_SIZE);
1759 }
1760
1761 static bool
1762 microblaze_elf_relax_section (bfd *abfd,
1763 asection *sec,
1764 struct bfd_link_info *link_info,
1765 bool *again)
1766 {
1767 Elf_Internal_Shdr *symtab_hdr;
1768 Elf_Internal_Rela *internal_relocs;
1769 Elf_Internal_Rela *free_relocs = NULL;
1770 Elf_Internal_Rela *irel, *irelend;
1771 bfd_byte *contents = NULL;
1772 bfd_byte *free_contents = NULL;
1773 int rel_count;
1774 unsigned int shndx;
1775 size_t i, sym_index;
1776 asection *o;
1777 struct elf_link_hash_entry *sym_hash;
1778 Elf_Internal_Sym *isymbuf, *isymend;
1779 Elf_Internal_Sym *isym;
1780 size_t symcount;
1781 size_t offset;
1782 bfd_vma src, dest;
1783 struct _microblaze_elf_section_data *sdata;
1784
1785 /* We only do this once per section. We may be able to delete some code
1786 by running multiple passes, but it is not worth it. */
1787 *again = false;
1788
1789 /* Only do this for a text section. */
1790 if (bfd_link_relocatable (link_info)
1791 || (sec->flags & SEC_RELOC) == 0
1792 || (sec->flags & SEC_CODE) == 0
1793 || sec->reloc_count == 0
1794 || (sdata = microblaze_elf_section_data (sec)) == NULL)
1795 return true;
1796
1797 BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0));
1798
1799 /* If this is the first time we have been called for this section,
1800 initialize the cooked size. */
1801 if (sec->size == 0)
1802 sec->size = sec->rawsize;
1803
1804 /* Get symbols for this section. */
1805 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1806 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1807 symcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
1808 if (isymbuf == NULL)
1809 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount,
1810 0, NULL, NULL, NULL);
1811 BFD_ASSERT (isymbuf != NULL);
1812
1813 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
1814 if (internal_relocs == NULL)
1815 goto error_return;
1816 if (! link_info->keep_memory)
1817 free_relocs = internal_relocs;
1818
1819 sdata->relax_count = 0;
1820 sdata->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
1821 * sizeof (*sdata->relax));
1822 if (sdata->relax == NULL)
1823 goto error_return;
1824
1825 irelend = internal_relocs + sec->reloc_count;
1826 rel_count = 0;
1827 for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1828 {
1829 bfd_vma symval;
1830 if ((ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL)
1831 && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64)
1832 && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_TEXTREL_64))
1833 continue; /* Can't delete this reloc. */
1834
1835 /* Get the section contents. */
1836 if (contents == NULL)
1837 {
1838 if (elf_section_data (sec)->this_hdr.contents != NULL)
1839 contents = elf_section_data (sec)->this_hdr.contents;
1840 else
1841 {
1842 contents = (bfd_byte *) bfd_malloc (sec->size);
1843 if (contents == NULL)
1844 goto error_return;
1845 free_contents = contents;
1846
1847 if (!bfd_get_section_contents (abfd, sec, contents,
1848 (file_ptr) 0, sec->size))
1849 goto error_return;
1850 elf_section_data (sec)->this_hdr.contents = contents;
1851 }
1852 }
1853
1854 /* Get the value of the symbol referred to by the reloc. */
1855 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1856 {
1857 /* A local symbol. */
1858 asection *sym_sec;
1859
1860 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1861 if (isym->st_shndx == SHN_UNDEF)
1862 sym_sec = bfd_und_section_ptr;
1863 else if (isym->st_shndx == SHN_ABS)
1864 sym_sec = bfd_abs_section_ptr;
1865 else if (isym->st_shndx == SHN_COMMON)
1866 sym_sec = bfd_com_section_ptr;
1867 else
1868 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1869
1870 symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
1871 }
1872 else
1873 {
1874 unsigned long indx;
1875 struct elf_link_hash_entry *h;
1876
1877 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1878 h = elf_sym_hashes (abfd)[indx];
1879 BFD_ASSERT (h != NULL);
1880
1881 if (h->root.type != bfd_link_hash_defined
1882 && h->root.type != bfd_link_hash_defweak)
1883 /* This appears to be a reference to an undefined
1884 symbol. Just ignore it--it will be caught by the
1885 regular reloc processing. */
1886 continue;
1887
1888 symval = (h->root.u.def.value
1889 + h->root.u.def.section->output_section->vma
1890 + h->root.u.def.section->output_offset);
1891 }
1892
1893 /* If this is a PC-relative reloc, subtract the instr offset from
1894 the symbol value. */
1895 if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_64_PCREL)
1896 {
1897 symval = symval + irel->r_addend
1898 - (irel->r_offset
1899 + sec->output_section->vma
1900 + sec->output_offset);
1901 }
1902 else if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_TEXTREL_64)
1903 {
1904 symval = symval + irel->r_addend - (sec->output_section->vma);
1905 }
1906 else
1907 symval += irel->r_addend;
1908
1909 if ((symval & 0xffff8000) == 0
1910 || (symval & 0xffff8000) == 0xffff8000)
1911 {
1912 /* We can delete this instruction. */
1913 sdata->relax[sdata->relax_count].addr = irel->r_offset;
1914 sdata->relax[sdata->relax_count].size = INST_WORD_SIZE;
1915 sdata->relax_count++;
1916
1917 /* Rewrite relocation type. */
1918 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1919 {
1920 case R_MICROBLAZE_64_PCREL:
1921 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1922 (int) R_MICROBLAZE_32_PCREL_LO);
1923 break;
1924 case R_MICROBLAZE_64:
1925 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1926 (int) R_MICROBLAZE_32_LO);
1927 break;
1928 case R_MICROBLAZE_TEXTREL_64:
1929 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1930 (int) R_MICROBLAZE_TEXTREL_32_LO);
1931 break;
1932 default:
1933 /* Cannot happen. */
1934 BFD_ASSERT (false);
1935 }
1936 }
1937 } /* Loop through all relocations. */
1938
1939 /* Loop through the relocs again, and see if anything needs to change. */
1940 if (sdata->relax_count > 0)
1941 {
1942 shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1943 rel_count = 0;
1944 sdata->relax[sdata->relax_count].addr = sec->size;
1945
1946 for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1947 {
1948 bfd_vma nraddr;
1949
1950 /* Get the new reloc address. */
1951 nraddr = irel->r_offset - calc_fixup (irel->r_offset, 0, sec);
1952 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1953 {
1954 default:
1955 break;
1956 case R_MICROBLAZE_64_PCREL:
1957 break;
1958 case R_MICROBLAZE_TEXTREL_64:
1959 case R_MICROBLAZE_TEXTREL_32_LO:
1960 case R_MICROBLAZE_64:
1961 case R_MICROBLAZE_32_LO:
1962 /* If this reloc is against a symbol defined in this
1963 section, we must check the addend to see it will put the value in
1964 range to be adjusted, and hence must be changed. */
1965 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1966 {
1967 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1968 /* Only handle relocs against .text. */
1969 if (isym->st_shndx == shndx
1970 && ELF32_ST_TYPE (isym->st_info) == STT_SECTION)
1971 irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
1972 }
1973 break;
1974 case R_MICROBLAZE_NONE:
1975 case R_MICROBLAZE_32_NONE:
1976 {
1977 /* This was a PC-relative instruction that was
1978 completely resolved. */
1979 size_t sfix, efix;
1980 bfd_vma target_address;
1981 target_address = irel->r_addend + irel->r_offset;
1982 sfix = calc_fixup (irel->r_offset, 0, sec);
1983 efix = calc_fixup (target_address, 0, sec);
1984 irel->r_addend -= (efix - sfix);
1985 /* Should use HOWTO. */
1986 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
1987 irel->r_addend);
1988 }
1989 break;
1990 case R_MICROBLAZE_64_NONE:
1991 {
1992 /* This was a PC-relative 64-bit instruction that was
1993 completely resolved. */
1994 size_t sfix, efix;
1995 bfd_vma target_address;
1996 target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE;
1997 sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec);
1998 efix = calc_fixup (target_address, 0, sec);
1999 irel->r_addend -= (efix - sfix);
2000 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset
2001 + INST_WORD_SIZE, irel->r_addend);
2002 }
2003 break;
2004 }
2005 irel->r_offset = nraddr;
2006 } /* Change all relocs in this section. */
2007
2008 /* Look through all other sections. */
2009 for (o = abfd->sections; o != NULL; o = o->next)
2010 {
2011 Elf_Internal_Rela *irelocs;
2012 Elf_Internal_Rela *irelscan, *irelscanend;
2013 bfd_byte *ocontents;
2014
2015 if (o == sec
2016 || (o->flags & SEC_RELOC) == 0
2017 || o->reloc_count == 0)
2018 continue;
2019
2020 /* We always cache the relocs. Perhaps, if info->keep_memory is
2021 FALSE, we should free them, if we are permitted to. */
2022
2023 irelocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, true);
2024 if (irelocs == NULL)
2025 goto error_return;
2026
2027 ocontents = NULL;
2028 irelscanend = irelocs + o->reloc_count;
2029 for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
2030 {
2031 if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
2032 || (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE))
2033 {
2034 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2035
2036 /* Look at the reloc only if the value has been resolved. */
2037 if (isym->st_shndx == shndx
2038 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2039 {
2040 if (ocontents == NULL)
2041 {
2042 if (elf_section_data (o)->this_hdr.contents != NULL)
2043 ocontents = elf_section_data (o)->this_hdr.contents;
2044 else
2045 {
2046 /* We always cache the section contents.
2047 Perhaps, if info->keep_memory is FALSE, we
2048 should free them, if we are permitted to. */
2049 if (o->rawsize == 0)
2050 o->rawsize = o->size;
2051 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2052 if (ocontents == NULL)
2053 goto error_return;
2054 if (!bfd_get_section_contents (abfd, o, ocontents,
2055 (file_ptr) 0,
2056 o->rawsize))
2057 goto error_return;
2058 elf_section_data (o)->this_hdr.contents = ocontents;
2059 }
2060
2061 }
2062 irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
2063 }
2064 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
2065 {
2066 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2067
2068 /* Look at the reloc only if the value has been resolved. */
2069 if (ocontents == NULL)
2070 {
2071 if (elf_section_data (o)->this_hdr.contents != NULL)
2072 ocontents = elf_section_data (o)->this_hdr.contents;
2073 else
2074 {
2075 /* We always cache the section contents.
2076 Perhaps, if info->keep_memory is FALSE, we
2077 should free them, if we are permitted to. */
2078
2079 if (o->rawsize == 0)
2080 o->rawsize = o->size;
2081 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2082 if (ocontents == NULL)
2083 goto error_return;
2084 if (!bfd_get_section_contents (abfd, o, ocontents,
2085 (file_ptr) 0,
2086 o->rawsize))
2087 goto error_return;
2088 elf_section_data (o)->this_hdr.contents = ocontents;
2089 }
2090 }
2091 irelscan->r_addend -= calc_fixup (irelscan->r_addend
2092 + isym->st_value,
2093 0,
2094 sec);
2095 }
2096 }
2097 else if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO)
2098 || (ELF32_R_TYPE (irelscan->r_info)
2099 == (int) R_MICROBLAZE_32_LO)
2100 || (ELF32_R_TYPE (irelscan->r_info)
2101 == (int) R_MICROBLAZE_TEXTREL_32_LO))
2102 {
2103 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2104
2105 /* Look at the reloc only if the value has been resolved. */
2106 if (isym->st_shndx == shndx
2107 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2108 {
2109 bfd_vma immediate;
2110 bfd_vma target_address;
2111
2112 if (ocontents == NULL)
2113 {
2114 if (elf_section_data (o)->this_hdr.contents != NULL)
2115 ocontents = elf_section_data (o)->this_hdr.contents;
2116 else
2117 {
2118 /* We always cache the section contents.
2119 Perhaps, if info->keep_memory is FALSE, we
2120 should free them, if we are permitted to. */
2121 if (o->rawsize == 0)
2122 o->rawsize = o->size;
2123 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2124 if (ocontents == NULL)
2125 goto error_return;
2126 if (!bfd_get_section_contents (abfd, o, ocontents,
2127 (file_ptr) 0,
2128 o->rawsize))
2129 goto error_return;
2130 elf_section_data (o)->this_hdr.contents = ocontents;
2131 }
2132 }
2133
2134 unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
2135 immediate = instr & 0x0000ffff;
2136 target_address = immediate;
2137 offset = calc_fixup (target_address, 0, sec);
2138 immediate -= offset;
2139 irelscan->r_addend -= offset;
2140 microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
2141 irelscan->r_addend);
2142 }
2143 }
2144
2145 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64
2146 || (ELF32_R_TYPE (irelscan->r_info)
2147 == (int) R_MICROBLAZE_TEXTREL_64))
2148 {
2149 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2150
2151 /* Look at the reloc only if the value has been resolved. */
2152 if (isym->st_shndx == shndx
2153 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2154 {
2155 if (ocontents == NULL)
2156 {
2157 if (elf_section_data (o)->this_hdr.contents != NULL)
2158 ocontents = elf_section_data (o)->this_hdr.contents;
2159 else
2160 {
2161 /* We always cache the section contents.
2162 Perhaps, if info->keep_memory is FALSE, we
2163 should free them, if we are permitted to. */
2164
2165 if (o->rawsize == 0)
2166 o->rawsize = o->size;
2167 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2168 if (ocontents == NULL)
2169 goto error_return;
2170 if (!bfd_get_section_contents (abfd, o, ocontents,
2171 (file_ptr) 0,
2172 o->rawsize))
2173 goto error_return;
2174 elf_section_data (o)->this_hdr.contents = ocontents;
2175 }
2176 }
2177 offset = calc_fixup (irelscan->r_addend, 0, sec);
2178 irelscan->r_addend -= offset;
2179 }
2180 }
2181 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
2182 {
2183 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2184
2185 /* Look at the reloc only if the value has been resolved. */
2186 if (isym->st_shndx == shndx
2187 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2188 {
2189 bfd_vma immediate;
2190 bfd_vma target_address;
2191
2192 if (ocontents == NULL)
2193 {
2194 if (elf_section_data (o)->this_hdr.contents != NULL)
2195 ocontents = elf_section_data (o)->this_hdr.contents;
2196 else
2197 {
2198 /* We always cache the section contents.
2199 Perhaps, if info->keep_memory is FALSE, we
2200 should free them, if we are permitted to. */
2201 if (o->rawsize == 0)
2202 o->rawsize = o->size;
2203 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2204 if (ocontents == NULL)
2205 goto error_return;
2206 if (!bfd_get_section_contents (abfd, o, ocontents,
2207 (file_ptr) 0,
2208 o->rawsize))
2209 goto error_return;
2210 elf_section_data (o)->this_hdr.contents = ocontents;
2211 }
2212 }
2213 unsigned long instr_hi = bfd_get_32 (abfd, ocontents
2214 + irelscan->r_offset);
2215 unsigned long instr_lo = bfd_get_32 (abfd, ocontents
2216 + irelscan->r_offset
2217 + INST_WORD_SIZE);
2218 immediate = (instr_hi & 0x0000ffff) << 16;
2219 immediate |= (instr_lo & 0x0000ffff);
2220 target_address = immediate;
2221 offset = calc_fixup (target_address, 0, sec);
2222 immediate -= offset;
2223 irelscan->r_addend -= offset;
2224 microblaze_bfd_write_imm_value_64 (abfd, ocontents
2225 + irelscan->r_offset, immediate);
2226 }
2227 }
2228 }
2229 }
2230
2231 /* Adjust the local symbols defined in this section. */
2232 isymend = isymbuf + symtab_hdr->sh_info;
2233 for (isym = isymbuf; isym < isymend; isym++)
2234 {
2235 if (isym->st_shndx == shndx)
2236 {
2237 isym->st_value -= calc_fixup (isym->st_value, 0, sec);
2238 if (isym->st_size)
2239 isym->st_size -= calc_fixup (isym->st_value, isym->st_size, sec);
2240 }
2241 }
2242
2243 /* Now adjust the global symbols defined in this section. */
2244 isym = isymbuf + symtab_hdr->sh_info;
2245 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)) - symtab_hdr->sh_info;
2246 for (sym_index = 0; sym_index < symcount; sym_index++)
2247 {
2248 sym_hash = elf_sym_hashes (abfd)[sym_index];
2249 if ((sym_hash->root.type == bfd_link_hash_defined
2250 || sym_hash->root.type == bfd_link_hash_defweak)
2251 && sym_hash->root.u.def.section == sec)
2252 {
2253 sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value,
2254 0, sec);
2255 if (sym_hash->size)
2256 sym_hash->size -= calc_fixup (sym_hash->root.u.def.value,
2257 sym_hash->size, sec);
2258 }
2259 }
2260
2261 /* Physically move the code and change the cooked size. */
2262 dest = sdata->relax[0].addr;
2263 for (i = 0; i < sdata->relax_count; i++)
2264 {
2265 size_t len;
2266 src = sdata->relax[i].addr + sdata->relax[i].size;
2267 len = (sdata->relax[i+1].addr - sdata->relax[i].addr
2268 - sdata->relax[i].size);
2269
2270 memmove (contents + dest, contents + src, len);
2271 sec->size -= sdata->relax[i].size;
2272 dest += len;
2273 }
2274
2275 elf_section_data (sec)->relocs = internal_relocs;
2276 free_relocs = NULL;
2277
2278 elf_section_data (sec)->this_hdr.contents = contents;
2279 free_contents = NULL;
2280
2281 symtab_hdr->contents = (bfd_byte *) isymbuf;
2282 }
2283
2284 free (free_relocs);
2285 free_relocs = NULL;
2286
2287 if (free_contents != NULL)
2288 {
2289 if (!link_info->keep_memory)
2290 free (free_contents);
2291 else
2292 /* Cache the section contents for elf_link_input_bfd. */
2293 elf_section_data (sec)->this_hdr.contents = contents;
2294 free_contents = NULL;
2295 }
2296
2297 if (sdata->relax_count == 0)
2298 {
2299 *again = false;
2300 free (sdata->relax);
2301 sdata->relax = NULL;
2302 }
2303 else
2304 *again = true;
2305 return true;
2306
2307 error_return:
2308 free (free_relocs);
2309 free (free_contents);
2310 free (sdata->relax);
2311 sdata->relax = NULL;
2312 sdata->relax_count = 0;
2313 return false;
2314 }
2315
2316 /* Return the section that should be marked against GC for a given
2317 relocation. */
2318
2319 static asection *
2320 microblaze_elf_gc_mark_hook (asection *sec,
2321 struct bfd_link_info * info,
2322 Elf_Internal_Rela * rel,
2323 struct elf_link_hash_entry * h,
2324 Elf_Internal_Sym * sym)
2325 {
2326 if (h != NULL)
2327 switch (ELF32_R_TYPE (rel->r_info))
2328 {
2329 case R_MICROBLAZE_GNU_VTINHERIT:
2330 case R_MICROBLAZE_GNU_VTENTRY:
2331 return NULL;
2332 }
2333
2334 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
2335 }
2336
2337 /* PIC support. */
2338
2339 #define PLT_ENTRY_SIZE 16
2340
2341 #define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
2342 #define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
2343 #define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
2344 #define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
2345 #define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
2346
2347 static bool
2348 update_local_sym_info (bfd *abfd,
2349 Elf_Internal_Shdr *symtab_hdr,
2350 unsigned long r_symndx,
2351 unsigned int tls_type)
2352 {
2353 bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
2354 unsigned char *local_got_tls_masks;
2355
2356 if (local_got_refcounts == NULL)
2357 {
2358 bfd_size_type size = symtab_hdr->sh_info;
2359
2360 size *= (sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks));
2361 local_got_refcounts = bfd_zalloc (abfd, size);
2362 if (local_got_refcounts == NULL)
2363 return false;
2364 elf_local_got_refcounts (abfd) = local_got_refcounts;
2365 }
2366
2367 local_got_tls_masks =
2368 (unsigned char *) (local_got_refcounts + symtab_hdr->sh_info);
2369 local_got_tls_masks[r_symndx] |= tls_type;
2370 local_got_refcounts[r_symndx] += 1;
2371
2372 return true;
2373 }
2374 /* Look through the relocs for a section during the first phase. */
2375
2376 static bool
2377 microblaze_elf_check_relocs (bfd * abfd,
2378 struct bfd_link_info * info,
2379 asection * sec,
2380 const Elf_Internal_Rela * relocs)
2381 {
2382 Elf_Internal_Shdr * symtab_hdr;
2383 struct elf_link_hash_entry ** sym_hashes;
2384 const Elf_Internal_Rela * rel;
2385 const Elf_Internal_Rela * rel_end;
2386 struct elf32_mb_link_hash_table *htab;
2387 asection *sreloc = NULL;
2388
2389 if (bfd_link_relocatable (info))
2390 return true;
2391
2392 htab = elf32_mb_hash_table (info);
2393 if (htab == NULL)
2394 return false;
2395
2396 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
2397 sym_hashes = elf_sym_hashes (abfd);
2398
2399 rel_end = relocs + sec->reloc_count;
2400
2401 for (rel = relocs; rel < rel_end; rel++)
2402 {
2403 unsigned int r_type;
2404 struct elf_link_hash_entry * h;
2405 unsigned long r_symndx;
2406 unsigned char tls_type = 0;
2407
2408 r_symndx = ELF32_R_SYM (rel->r_info);
2409 r_type = ELF32_R_TYPE (rel->r_info);
2410
2411 if (r_symndx < symtab_hdr->sh_info)
2412 h = NULL;
2413 else
2414 {
2415 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
2416 while (h->root.type == bfd_link_hash_indirect
2417 || h->root.type == bfd_link_hash_warning)
2418 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2419 }
2420
2421 switch (r_type)
2422 {
2423 /* This relocation describes the C++ object vtable hierarchy.
2424 Reconstruct it for later use during GC. */
2425 case R_MICROBLAZE_GNU_VTINHERIT:
2426 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2427 return false;
2428 break;
2429
2430 /* This relocation describes which C++ vtable entries are actually
2431 used. Record for later use during GC. */
2432 case R_MICROBLAZE_GNU_VTENTRY:
2433 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
2434 return false;
2435 break;
2436
2437 /* This relocation requires .plt entry. */
2438 case R_MICROBLAZE_PLT_64:
2439 if (h != NULL)
2440 {
2441 h->needs_plt = 1;
2442 h->plt.refcount += 1;
2443 }
2444 break;
2445
2446 /* This relocation requires .got entry. */
2447 case R_MICROBLAZE_TLSGD:
2448 tls_type |= (TLS_TLS | TLS_GD);
2449 goto dogottls;
2450 case R_MICROBLAZE_TLSLD:
2451 tls_type |= (TLS_TLS | TLS_LD);
2452 /* Fall through. */
2453 dogottls:
2454 sec->has_tls_reloc = 1;
2455 /* Fall through. */
2456 case R_MICROBLAZE_GOT_64:
2457 if (htab->elf.sgot == NULL)
2458 {
2459 if (htab->elf.dynobj == NULL)
2460 htab->elf.dynobj = abfd;
2461 if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
2462 return false;
2463 }
2464 if (h != NULL)
2465 {
2466 h->got.refcount += 1;
2467 elf32_mb_hash_entry (h)->tls_mask |= tls_type;
2468 }
2469 else
2470 {
2471 if (! update_local_sym_info(abfd, symtab_hdr, r_symndx, tls_type) )
2472 return false;
2473 }
2474 break;
2475
2476 case R_MICROBLAZE_GOTOFF_64:
2477 case R_MICROBLAZE_GOTOFF_32:
2478 if (htab->elf.sgot == NULL)
2479 {
2480 if (htab->elf.dynobj == NULL)
2481 htab->elf.dynobj = abfd;
2482 if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
2483 return false;
2484 }
2485 break;
2486
2487 case R_MICROBLAZE_64:
2488 case R_MICROBLAZE_64_PCREL:
2489 case R_MICROBLAZE_32:
2490 {
2491 if (h != NULL && !bfd_link_pic (info))
2492 {
2493 /* we may need a copy reloc. */
2494 h->non_got_ref = 1;
2495
2496 /* we may also need a .plt entry. */
2497 h->plt.refcount += 1;
2498 if (ELF32_R_TYPE (rel->r_info) != R_MICROBLAZE_64_PCREL)
2499 h->pointer_equality_needed = 1;
2500 }
2501
2502
2503 /* If we are creating a shared library, and this is a reloc
2504 against a global symbol, or a non PC relative reloc
2505 against a local symbol, then we need to copy the reloc
2506 into the shared library. However, if we are linking with
2507 -Bsymbolic, we do not need to copy a reloc against a
2508 global symbol which is defined in an object we are
2509 including in the link (i.e., DEF_REGULAR is set). At
2510 this point we have not seen all the input files, so it is
2511 possible that DEF_REGULAR is not set now but will be set
2512 later (it is never cleared). In case of a weak definition,
2513 DEF_REGULAR may be cleared later by a strong definition in
2514 a shared library. We account for that possibility below by
2515 storing information in the relocs_copied field of the hash
2516 table entry. A similar situation occurs when creating
2517 shared libraries and symbol visibility changes render the
2518 symbol local.
2519
2520 If on the other hand, we are creating an executable, we
2521 may need to keep relocations for symbols satisfied by a
2522 dynamic library if we manage to avoid copy relocs for the
2523 symbol. */
2524
2525 if ((bfd_link_pic (info)
2526 && (sec->flags & SEC_ALLOC) != 0
2527 && (r_type != R_MICROBLAZE_64_PCREL
2528 || (h != NULL
2529 && (! info->symbolic
2530 || h->root.type == bfd_link_hash_defweak
2531 || !h->def_regular))))
2532 || (!bfd_link_pic (info)
2533 && (sec->flags & SEC_ALLOC) != 0
2534 && h != NULL
2535 && (h->root.type == bfd_link_hash_defweak
2536 || !h->def_regular)))
2537 {
2538 struct elf_dyn_relocs *p;
2539 struct elf_dyn_relocs **head;
2540
2541 /* When creating a shared object, we must copy these
2542 relocs into the output file. We create a reloc
2543 section in dynobj and make room for the reloc. */
2544
2545 if (sreloc == NULL)
2546 {
2547 bfd *dynobj;
2548
2549 if (htab->elf.dynobj == NULL)
2550 htab->elf.dynobj = abfd;
2551 dynobj = htab->elf.dynobj;
2552
2553 sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
2554 2, abfd, 1);
2555 if (sreloc == NULL)
2556 return false;
2557 }
2558
2559 /* If this is a global symbol, we count the number of
2560 relocations we need for this symbol. */
2561 if (h != NULL)
2562 head = &h->dyn_relocs;
2563 else
2564 {
2565 /* Track dynamic relocs needed for local syms too.
2566 We really need local syms available to do this
2567 easily. Oh well. */
2568
2569 asection *s;
2570 Elf_Internal_Sym *isym;
2571 void *vpp;
2572
2573 isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
2574 abfd, r_symndx);
2575 if (isym == NULL)
2576 return false;
2577
2578 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2579 if (s == NULL)
2580 return false;
2581
2582 vpp = &elf_section_data (s)->local_dynrel;
2583 head = (struct elf_dyn_relocs **) vpp;
2584 }
2585
2586 p = *head;
2587 if (p == NULL || p->sec != sec)
2588 {
2589 size_t amt = sizeof *p;
2590 p = ((struct elf_dyn_relocs *)
2591 bfd_alloc (htab->elf.dynobj, amt));
2592 if (p == NULL)
2593 return false;
2594 p->next = *head;
2595 *head = p;
2596 p->sec = sec;
2597 p->count = 0;
2598 p->pc_count = 0;
2599 }
2600
2601 p->count += 1;
2602 if (r_type == R_MICROBLAZE_64_PCREL)
2603 p->pc_count += 1;
2604 }
2605 }
2606 break;
2607 }
2608 }
2609
2610 return true;
2611 }
2612
2613 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2614
2615 static void
2616 microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
2617 struct elf_link_hash_entry *dir,
2618 struct elf_link_hash_entry *ind)
2619 {
2620 struct elf32_mb_link_hash_entry *edir, *eind;
2621
2622 edir = (struct elf32_mb_link_hash_entry *) dir;
2623 eind = (struct elf32_mb_link_hash_entry *) ind;
2624
2625 edir->tls_mask |= eind->tls_mask;
2626
2627 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
2628 }
2629
2630 static bool
2631 microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2632 struct elf_link_hash_entry *h)
2633 {
2634 struct elf32_mb_link_hash_table *htab;
2635 asection *s, *srel;
2636 unsigned int power_of_two;
2637
2638 htab = elf32_mb_hash_table (info);
2639 if (htab == NULL)
2640 return false;
2641
2642 /* If this is a function, put it in the procedure linkage table. We
2643 will fill in the contents of the procedure linkage table later,
2644 when we know the address of the .got section. */
2645 if (h->type == STT_FUNC
2646 || h->needs_plt)
2647 {
2648 if (h->plt.refcount <= 0
2649 || SYMBOL_CALLS_LOCAL (info, h)
2650 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
2651 && h->root.type == bfd_link_hash_undefweak))
2652 {
2653 /* This case can occur if we saw a PLT reloc in an input
2654 file, but the symbol was never referred to by a dynamic
2655 object, or if all references were garbage collected. In
2656 such a case, we don't actually need to build a procedure
2657 linkage table, and we can just do a PC32 reloc instead. */
2658 h->plt.offset = (bfd_vma) -1;
2659 h->needs_plt = 0;
2660 }
2661
2662 return true;
2663 }
2664 else
2665 /* It's possible that we incorrectly decided a .plt reloc was
2666 needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
2667 check_relocs. We can't decide accurately between function and
2668 non-function syms in check-relocs; Objects loaded later in
2669 the link may change h->type. So fix it now. */
2670 h->plt.offset = (bfd_vma) -1;
2671
2672 /* If this is a weak symbol, and there is a real definition, the
2673 processor independent code will have arranged for us to see the
2674 real definition first, and we can just use the same value. */
2675 if (h->is_weakalias)
2676 {
2677 struct elf_link_hash_entry *def = weakdef (h);
2678 BFD_ASSERT (def->root.type == bfd_link_hash_defined);
2679 h->root.u.def.section = def->root.u.def.section;
2680 h->root.u.def.value = def->root.u.def.value;
2681 return true;
2682 }
2683
2684 /* This is a reference to a symbol defined by a dynamic object which
2685 is not a function. */
2686
2687 /* If we are creating a shared library, we must presume that the
2688 only references to the symbol are via the global offset table.
2689 For such cases we need not do anything here; the relocations will
2690 be handled correctly by relocate_section. */
2691 if (bfd_link_pic (info))
2692 return true;
2693
2694 /* If there are no references to this symbol that do not use the
2695 GOT, we don't need to generate a copy reloc. */
2696 if (!h->non_got_ref)
2697 return true;
2698
2699 /* If -z nocopyreloc was given, we won't generate them either. */
2700 if (info->nocopyreloc)
2701 {
2702 h->non_got_ref = 0;
2703 return true;
2704 }
2705
2706 /* If we don't find any dynamic relocs in read-only sections, then
2707 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
2708 if (!_bfd_elf_readonly_dynrelocs (h))
2709 {
2710 h->non_got_ref = 0;
2711 return true;
2712 }
2713
2714 /* We must allocate the symbol in our .dynbss section, which will
2715 become part of the .bss section of the executable. There will be
2716 an entry for this symbol in the .dynsym section. The dynamic
2717 object will contain position independent code, so all references
2718 from the dynamic object to this symbol will go through the global
2719 offset table. The dynamic linker will use the .dynsym entry to
2720 determine the address it must put in the global offset table, so
2721 both the dynamic object and the regular object will refer to the
2722 same memory location for the variable. */
2723
2724 /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
2725 to copy the initial value out of the dynamic object and into the
2726 runtime process image. */
2727 if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
2728 {
2729 s = htab->elf.sdynrelro;
2730 srel = htab->elf.sreldynrelro;
2731 }
2732 else
2733 {
2734 s = htab->elf.sdynbss;
2735 srel = htab->elf.srelbss;
2736 }
2737 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2738 {
2739 srel->size += sizeof (Elf32_External_Rela);
2740 h->needs_copy = 1;
2741 }
2742
2743 /* We need to figure out the alignment required for this symbol. I
2744 have no idea how ELF linkers handle this. */
2745 power_of_two = bfd_log2 (h->size);
2746 if (power_of_two > 3)
2747 power_of_two = 3;
2748
2749 /* Apply the required alignment. */
2750 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
2751 if (power_of_two > s->alignment_power)
2752 {
2753 if (!bfd_set_section_alignment (s, power_of_two))
2754 return false;
2755 }
2756
2757 /* Define the symbol as being at this point in the section. */
2758 h->root.u.def.section = s;
2759 h->root.u.def.value = s->size;
2760
2761 /* Increment the section size to make room for the symbol. */
2762 s->size += h->size;
2763 return true;
2764 }
2765
2766 /* Allocate space in .plt, .got and associated reloc sections for
2767 dynamic relocs. */
2768
2769 static bool
2770 allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
2771 {
2772 struct bfd_link_info *info;
2773 struct elf32_mb_link_hash_table *htab;
2774 struct elf32_mb_link_hash_entry *eh;
2775 struct elf_dyn_relocs *p;
2776
2777 if (h->root.type == bfd_link_hash_indirect)
2778 return true;
2779
2780 info = (struct bfd_link_info *) dat;
2781 htab = elf32_mb_hash_table (info);
2782 if (htab == NULL)
2783 return false;
2784
2785 if (htab->elf.dynamic_sections_created
2786 && h->plt.refcount > 0)
2787 {
2788 /* Make sure this symbol is output as a dynamic symbol.
2789 Undefined weak syms won't yet be marked as dynamic. */
2790 if (h->dynindx == -1
2791 && !h->forced_local)
2792 {
2793 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2794 return false;
2795 }
2796
2797 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
2798 {
2799 asection *s = htab->elf.splt;
2800
2801 /* The first entry in .plt is reserved. */
2802 if (s->size == 0)
2803 s->size = PLT_ENTRY_SIZE;
2804
2805 h->plt.offset = s->size;
2806
2807 /* If this symbol is not defined in a regular file, and we are
2808 not generating a shared library, then set the symbol to this
2809 location in the .plt. This is required to make function
2810 pointers compare as equal between the normal executable and
2811 the shared library. */
2812 if (! bfd_link_pic (info)
2813 && !h->def_regular)
2814 {
2815 h->root.u.def.section = s;
2816 h->root.u.def.value = h->plt.offset;
2817 }
2818
2819 /* Make room for this entry. */
2820 s->size += PLT_ENTRY_SIZE;
2821
2822 /* We also need to make an entry in the .got.plt section, which
2823 will be placed in the .got section by the linker script. */
2824 htab->elf.sgotplt->size += 4;
2825
2826 /* We also need to make an entry in the .rel.plt section. */
2827 htab->elf.srelplt->size += sizeof (Elf32_External_Rela);
2828 }
2829 else
2830 {
2831 h->plt.offset = (bfd_vma) -1;
2832 h->needs_plt = 0;
2833 }
2834 }
2835 else
2836 {
2837 h->plt.offset = (bfd_vma) -1;
2838 h->needs_plt = 0;
2839 }
2840
2841 eh = (struct elf32_mb_link_hash_entry *) h;
2842 if (h->got.refcount > 0)
2843 {
2844 unsigned int need;
2845 asection *s;
2846
2847 /* Make sure this symbol is output as a dynamic symbol.
2848 Undefined weak syms won't yet be marked as dynamic. */
2849 if (h->dynindx == -1
2850 && !h->forced_local)
2851 {
2852 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2853 return false;
2854 }
2855
2856 need = 0;
2857 if ((eh->tls_mask & TLS_TLS) != 0)
2858 {
2859 /* Handle TLS Symbol */
2860 if ((eh->tls_mask & TLS_LD) != 0)
2861 {
2862 if (!eh->elf.def_dynamic)
2863 /* We'll just use htab->tlsld_got.offset. This should
2864 always be the case. It's a little odd if we have
2865 a local dynamic reloc against a non-local symbol. */
2866 htab->tlsld_got.refcount += 1;
2867 else
2868 need += 8;
2869 }
2870 if ((eh->tls_mask & TLS_GD) != 0)
2871 need += 8;
2872 }
2873 else
2874 {
2875 /* Regular (non-TLS) symbol */
2876 need += 4;
2877 }
2878 if (need == 0)
2879 {
2880 h->got.offset = (bfd_vma) -1;
2881 }
2882 else
2883 {
2884 s = htab->elf.sgot;
2885 h->got.offset = s->size;
2886 s->size += need;
2887 htab->elf.srelgot->size += need * (sizeof (Elf32_External_Rela) / 4);
2888 }
2889 }
2890 else
2891 h->got.offset = (bfd_vma) -1;
2892
2893 if (h->dyn_relocs == NULL)
2894 return true;
2895
2896 /* In the shared -Bsymbolic case, discard space allocated for
2897 dynamic pc-relative relocs against symbols which turn out to be
2898 defined in regular objects. For the normal shared case, discard
2899 space for pc-relative relocs that have become local due to symbol
2900 visibility changes. */
2901
2902 if (bfd_link_pic (info))
2903 {
2904 if (h->def_regular
2905 && (h->forced_local
2906 || info->symbolic))
2907 {
2908 struct elf_dyn_relocs **pp;
2909
2910 for (pp = &h->dyn_relocs; (p = *pp) != NULL; )
2911 {
2912 p->count -= p->pc_count;
2913 p->pc_count = 0;
2914 if (p->count == 0)
2915 *pp = p->next;
2916 else
2917 pp = &p->next;
2918 }
2919 }
2920 else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
2921 h->dyn_relocs = NULL;
2922 }
2923 else
2924 {
2925 /* For the non-shared case, discard space for relocs against
2926 symbols which turn out to need copy relocs or are not
2927 dynamic. */
2928
2929 if (!h->non_got_ref
2930 && ((h->def_dynamic
2931 && !h->def_regular)
2932 || (htab->elf.dynamic_sections_created
2933 && (h->root.type == bfd_link_hash_undefweak
2934 || h->root.type == bfd_link_hash_undefined))))
2935 {
2936 /* Make sure this symbol is output as a dynamic symbol.
2937 Undefined weak syms won't yet be marked as dynamic. */
2938 if (h->dynindx == -1
2939 && !h->forced_local)
2940 {
2941 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2942 return false;
2943 }
2944
2945 /* If that succeeded, we know we'll be keeping all the
2946 relocs. */
2947 if (h->dynindx != -1)
2948 goto keep;
2949 }
2950
2951 h->dyn_relocs = NULL;
2952
2953 keep: ;
2954 }
2955
2956 /* Finally, allocate space. */
2957 for (p = h->dyn_relocs; p != NULL; p = p->next)
2958 {
2959 asection *sreloc = elf_section_data (p->sec)->sreloc;
2960 sreloc->size += p->count * sizeof (Elf32_External_Rela);
2961 }
2962
2963 return true;
2964 }
2965
2966 /* Set the sizes of the dynamic sections. */
2967
2968 static bool
2969 microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2970 struct bfd_link_info *info)
2971 {
2972 struct elf32_mb_link_hash_table *htab;
2973 bfd *dynobj;
2974 asection *s;
2975 bfd *ibfd;
2976
2977 htab = elf32_mb_hash_table (info);
2978 if (htab == NULL)
2979 return false;
2980
2981 dynobj = htab->elf.dynobj;
2982 BFD_ASSERT (dynobj != NULL);
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_size_dynamic_sections microblaze_elf_size_dynamic_sections
3499 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
3500
3501 #include "elf32-target.h"