1 /* Xilinx MicroBlaze-specific support for 32-bit ELF
3 Copyright (C) 2009-2016 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
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.
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.
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. */
30 #include "elf/microblaze.h"
33 #define USE_RELA /* Only USE_REL is actually significant, but this is
34 here are a reminder... */
35 #define INST_WORD_SIZE 4
37 static int ro_small_data_pointer = 0;
38 static int rw_small_data_pointer = 0;
40 static reloc_howto_type * microblaze_elf_howto_table [(int) R_MICROBLAZE_max];
42 static reloc_howto_type microblaze_elf_howto_raw[] =
44 /* This reloc does nothing. */
45 HOWTO (R_MICROBLAZE_NONE, /* Type. */
47 3, /* Size (0 = byte, 1 = short, 2 = long). */
49 FALSE, /* PC_relative. */
51 complain_overflow_dont, /* Complain on overflow. */
52 NULL, /* Special Function. */
53 "R_MICROBLAZE_NONE", /* Name. */
54 FALSE, /* Partial Inplace. */
57 FALSE), /* PC relative offset? */
59 /* A standard 32 bit relocation. */
60 HOWTO (R_MICROBLAZE_32, /* Type. */
62 2, /* Size (0 = byte, 1 = short, 2 = long). */
64 FALSE, /* PC_relative. */
66 complain_overflow_bitfield, /* Complain on overflow. */
67 bfd_elf_generic_reloc,/* Special Function. */
68 "R_MICROBLAZE_32", /* Name. */
69 FALSE, /* Partial Inplace. */
71 0xffffffff, /* Dest Mask. */
72 FALSE), /* PC relative offset? */
74 /* A standard PCREL 32 bit relocation. */
75 HOWTO (R_MICROBLAZE_32_PCREL,/* Type. */
77 2, /* Size (0 = byte, 1 = short, 2 = long). */
79 TRUE, /* PC_relative. */
81 complain_overflow_bitfield, /* Complain on overflow. */
82 bfd_elf_generic_reloc,/* Special Function. */
83 "R_MICROBLAZE_32_PCREL", /* Name. */
84 TRUE, /* Partial Inplace. */
86 0xffffffff, /* Dest Mask. */
87 TRUE), /* PC relative offset? */
89 /* A 64 bit PCREL relocation. Table-entry not really used. */
90 HOWTO (R_MICROBLAZE_64_PCREL,/* Type. */
92 2, /* Size (0 = byte, 1 = short, 2 = long). */
94 TRUE, /* PC_relative. */
96 complain_overflow_dont, /* Complain on overflow. */
97 bfd_elf_generic_reloc,/* Special Function. */
98 "R_MICROBLAZE_64_PCREL", /* Name. */
99 FALSE, /* Partial Inplace. */
100 0, /* Source Mask. */
101 0x0000ffff, /* Dest Mask. */
102 TRUE), /* PC relative offset? */
104 /* The low half of a PCREL 32 bit relocation. */
105 HOWTO (R_MICROBLAZE_32_PCREL_LO, /* Type. */
107 2, /* Size (0 = byte, 1 = short, 2 = long). */
109 TRUE, /* PC_relative. */
111 complain_overflow_signed, /* Complain on overflow. */
112 bfd_elf_generic_reloc, /* Special Function. */
113 "R_MICROBLAZE_32_PCREL_LO", /* Name. */
114 FALSE, /* Partial Inplace. */
115 0, /* Source Mask. */
116 0x0000ffff, /* Dest Mask. */
117 TRUE), /* PC relative offset? */
119 /* A 64 bit relocation. Table entry not really used. */
120 HOWTO (R_MICROBLAZE_64, /* Type. */
122 2, /* Size (0 = byte, 1 = short, 2 = long). */
124 FALSE, /* PC_relative. */
126 complain_overflow_dont, /* Complain on overflow. */
127 bfd_elf_generic_reloc,/* Special Function. */
128 "R_MICROBLAZE_64", /* Name. */
129 FALSE, /* Partial Inplace. */
130 0, /* Source Mask. */
131 0x0000ffff, /* Dest Mask. */
132 FALSE), /* PC relative offset? */
134 /* The low half of a 32 bit relocation. */
135 HOWTO (R_MICROBLAZE_32_LO, /* Type. */
137 2, /* Size (0 = byte, 1 = short, 2 = long). */
139 FALSE, /* PC_relative. */
141 complain_overflow_signed, /* Complain on overflow. */
142 bfd_elf_generic_reloc,/* Special Function. */
143 "R_MICROBLAZE_32_LO", /* Name. */
144 FALSE, /* Partial Inplace. */
145 0, /* Source Mask. */
146 0x0000ffff, /* Dest Mask. */
147 FALSE), /* PC relative offset? */
149 /* Read-only small data section relocation. */
150 HOWTO (R_MICROBLAZE_SRO32, /* Type. */
152 2, /* Size (0 = byte, 1 = short, 2 = long). */
154 FALSE, /* PC_relative. */
156 complain_overflow_bitfield, /* Complain on overflow. */
157 bfd_elf_generic_reloc,/* Special Function. */
158 "R_MICROBLAZE_SRO32", /* Name. */
159 FALSE, /* Partial Inplace. */
160 0, /* Source Mask. */
161 0x0000ffff, /* Dest Mask. */
162 FALSE), /* PC relative offset? */
164 /* Read-write small data area relocation. */
165 HOWTO (R_MICROBLAZE_SRW32, /* Type. */
167 2, /* Size (0 = byte, 1 = short, 2 = long). */
169 FALSE, /* PC_relative. */
171 complain_overflow_bitfield, /* Complain on overflow. */
172 bfd_elf_generic_reloc,/* Special Function. */
173 "R_MICROBLAZE_SRW32", /* Name. */
174 FALSE, /* Partial Inplace. */
175 0, /* Source Mask. */
176 0x0000ffff, /* Dest Mask. */
177 FALSE), /* PC relative offset? */
179 /* This reloc does nothing. Used for relaxation. */
180 HOWTO (R_MICROBLAZE_64_NONE, /* Type. */
182 3, /* Size (0 = byte, 1 = short, 2 = long). */
184 TRUE, /* PC_relative. */
186 complain_overflow_dont, /* Complain on overflow. */
187 NULL, /* Special Function. */
188 "R_MICROBLAZE_64_NONE",/* Name. */
189 FALSE, /* Partial Inplace. */
190 0, /* Source Mask. */
192 FALSE), /* PC relative offset? */
194 /* Symbol Op Symbol relocation. */
195 HOWTO (R_MICROBLAZE_32_SYM_OP_SYM, /* Type. */
197 2, /* Size (0 = byte, 1 = short, 2 = long). */
199 FALSE, /* PC_relative. */
201 complain_overflow_bitfield, /* Complain on overflow. */
202 bfd_elf_generic_reloc,/* Special Function. */
203 "R_MICROBLAZE_32_SYM_OP_SYM", /* Name. */
204 FALSE, /* Partial Inplace. */
205 0, /* Source Mask. */
206 0xffffffff, /* Dest Mask. */
207 FALSE), /* PC relative offset? */
209 /* GNU extension to record C++ vtable hierarchy. */
210 HOWTO (R_MICROBLAZE_GNU_VTINHERIT, /* Type. */
212 2, /* Size (0 = byte, 1 = short, 2 = long). */
214 FALSE, /* PC_relative. */
216 complain_overflow_dont,/* Complain on overflow. */
217 NULL, /* Special Function. */
218 "R_MICROBLAZE_GNU_VTINHERIT", /* Name. */
219 FALSE, /* Partial Inplace. */
220 0, /* Source Mask. */
222 FALSE), /* PC relative offset? */
224 /* GNU extension to record C++ vtable member usage. */
225 HOWTO (R_MICROBLAZE_GNU_VTENTRY, /* Type. */
227 2, /* Size (0 = byte, 1 = short, 2 = long). */
229 FALSE, /* PC_relative. */
231 complain_overflow_dont,/* Complain on overflow. */
232 _bfd_elf_rel_vtable_reloc_fn, /* Special Function. */
233 "R_MICROBLAZE_GNU_VTENTRY", /* Name. */
234 FALSE, /* Partial Inplace. */
235 0, /* Source Mask. */
237 FALSE), /* PC relative offset? */
239 /* A 64 bit GOTPC relocation. Table-entry not really used. */
240 HOWTO (R_MICROBLAZE_GOTPC_64, /* Type. */
242 2, /* Size (0 = byte, 1 = short, 2 = long). */
244 TRUE, /* PC_relative. */
246 complain_overflow_dont, /* Complain on overflow. */
247 bfd_elf_generic_reloc, /* Special Function. */
248 "R_MICROBLAZE_GOTPC_64", /* Name. */
249 FALSE, /* Partial Inplace. */
250 0, /* Source Mask. */
251 0x0000ffff, /* Dest Mask. */
252 TRUE), /* PC relative offset? */
254 /* A 64 bit GOT relocation. Table-entry not really used. */
255 HOWTO (R_MICROBLAZE_GOT_64, /* Type. */
257 2, /* Size (0 = byte, 1 = short, 2 = long). */
259 FALSE, /* PC_relative. */
261 complain_overflow_dont, /* Complain on overflow. */
262 bfd_elf_generic_reloc,/* Special Function. */
263 "R_MICROBLAZE_GOT_64",/* Name. */
264 FALSE, /* Partial Inplace. */
265 0, /* Source Mask. */
266 0x0000ffff, /* Dest Mask. */
267 FALSE), /* PC relative offset? */
269 /* A 64 bit PLT relocation. Table-entry not really used. */
270 HOWTO (R_MICROBLAZE_PLT_64, /* Type. */
272 2, /* Size (0 = byte, 1 = short, 2 = long). */
274 TRUE, /* PC_relative. */
276 complain_overflow_dont, /* Complain on overflow. */
277 bfd_elf_generic_reloc,/* Special Function. */
278 "R_MICROBLAZE_PLT_64",/* Name. */
279 FALSE, /* Partial Inplace. */
280 0, /* Source Mask. */
281 0x0000ffff, /* Dest Mask. */
282 TRUE), /* PC relative offset? */
284 /* Table-entry not really used. */
285 HOWTO (R_MICROBLAZE_REL, /* Type. */
287 2, /* Size (0 = byte, 1 = short, 2 = long). */
289 TRUE, /* PC_relative. */
291 complain_overflow_dont, /* Complain on overflow. */
292 bfd_elf_generic_reloc,/* Special Function. */
293 "R_MICROBLAZE_REL", /* Name. */
294 FALSE, /* Partial Inplace. */
295 0, /* Source Mask. */
296 0x0000ffff, /* Dest Mask. */
297 TRUE), /* PC relative offset? */
299 /* Table-entry not really used. */
300 HOWTO (R_MICROBLAZE_JUMP_SLOT,/* Type. */
302 2, /* Size (0 = byte, 1 = short, 2 = long). */
304 TRUE, /* PC_relative. */
306 complain_overflow_dont, /* Complain on overflow. */
307 bfd_elf_generic_reloc,/* Special Function. */
308 "R_MICROBLAZE_JUMP_SLOT", /* Name. */
309 FALSE, /* Partial Inplace. */
310 0, /* Source Mask. */
311 0x0000ffff, /* Dest Mask. */
312 TRUE), /* PC relative offset? */
314 /* Table-entry not really used. */
315 HOWTO (R_MICROBLAZE_GLOB_DAT,/* Type. */
317 2, /* Size (0 = byte, 1 = short, 2 = long). */
319 TRUE, /* PC_relative. */
321 complain_overflow_dont, /* Complain on overflow. */
322 bfd_elf_generic_reloc,/* Special Function. */
323 "R_MICROBLAZE_GLOB_DAT", /* Name. */
324 FALSE, /* Partial Inplace. */
325 0, /* Source Mask. */
326 0x0000ffff, /* Dest Mask. */
327 TRUE), /* PC relative offset? */
329 /* A 64 bit GOT relative relocation. Table-entry not really used. */
330 HOWTO (R_MICROBLAZE_GOTOFF_64, /* Type. */
332 2, /* Size (0 = byte, 1 = short, 2 = long). */
334 FALSE, /* PC_relative. */
336 complain_overflow_dont, /* Complain on overflow. */
337 bfd_elf_generic_reloc,/* Special Function. */
338 "R_MICROBLAZE_GOTOFF_64", /* Name. */
339 FALSE, /* Partial Inplace. */
340 0, /* Source Mask. */
341 0x0000ffff, /* Dest Mask. */
342 FALSE), /* PC relative offset? */
344 /* A 32 bit GOT relative relocation. Table-entry not really used. */
345 HOWTO (R_MICROBLAZE_GOTOFF_32, /* Type. */
347 2, /* Size (0 = byte, 1 = short, 2 = long). */
349 FALSE, /* PC_relative. */
351 complain_overflow_dont, /* Complain on overflow. */
352 bfd_elf_generic_reloc, /* Special Function. */
353 "R_MICROBLAZE_GOTOFF_32", /* Name. */
354 FALSE, /* Partial Inplace. */
355 0, /* Source Mask. */
356 0x0000ffff, /* Dest Mask. */
357 FALSE), /* PC relative offset? */
359 /* COPY relocation. Table-entry not really used. */
360 HOWTO (R_MICROBLAZE_COPY, /* Type. */
362 2, /* Size (0 = byte, 1 = short, 2 = long). */
364 FALSE, /* PC_relative. */
366 complain_overflow_dont, /* Complain on overflow. */
367 bfd_elf_generic_reloc,/* Special Function. */
368 "R_MICROBLAZE_COPY", /* Name. */
369 FALSE, /* Partial Inplace. */
370 0, /* Source Mask. */
371 0x0000ffff, /* Dest Mask. */
372 FALSE), /* PC relative offset? */
374 /* Marker relocs for TLS. */
375 HOWTO (R_MICROBLAZE_TLS,
377 2, /* size (0 = byte, 1 = short, 2 = long) */
379 FALSE, /* pc_relative */
381 complain_overflow_dont, /* complain_on_overflow */
382 bfd_elf_generic_reloc, /* special_function */
383 "R_MICROBLAZE_TLS", /* name */
384 FALSE, /* partial_inplace */
386 0x0000ffff, /* dst_mask */
387 FALSE), /* pcrel_offset */
389 HOWTO (R_MICROBLAZE_TLSGD,
391 2, /* size (0 = byte, 1 = short, 2 = long) */
393 FALSE, /* pc_relative */
395 complain_overflow_dont, /* complain_on_overflow */
396 bfd_elf_generic_reloc, /* special_function */
397 "R_MICROBLAZE_TLSGD", /* name */
398 FALSE, /* partial_inplace */
400 0x0000ffff, /* dst_mask */
401 FALSE), /* pcrel_offset */
403 HOWTO (R_MICROBLAZE_TLSLD,
405 2, /* size (0 = byte, 1 = short, 2 = long) */
407 FALSE, /* pc_relative */
409 complain_overflow_dont, /* complain_on_overflow */
410 bfd_elf_generic_reloc, /* special_function */
411 "R_MICROBLAZE_TLSLD", /* name */
412 FALSE, /* partial_inplace */
414 0x0000ffff, /* dst_mask */
415 FALSE), /* pcrel_offset */
417 /* Computes the load module index of the load module that contains the
418 definition of its TLS sym. */
419 HOWTO (R_MICROBLAZE_TLSDTPMOD32,
421 2, /* size (0 = byte, 1 = short, 2 = long) */
423 FALSE, /* pc_relative */
425 complain_overflow_dont, /* complain_on_overflow */
426 bfd_elf_generic_reloc, /* special_function */
427 "R_MICROBLAZE_TLSDTPMOD32", /* name */
428 FALSE, /* partial_inplace */
430 0x0000ffff, /* dst_mask */
431 FALSE), /* pcrel_offset */
433 /* Computes a dtv-relative displacement, the difference between the value
434 of sym+add and the base address of the thread-local storage block that
435 contains the definition of sym, minus 0x8000. Used for initializing GOT */
436 HOWTO (R_MICROBLAZE_TLSDTPREL32,
438 2, /* size (0 = byte, 1 = short, 2 = long) */
440 FALSE, /* pc_relative */
442 complain_overflow_dont, /* complain_on_overflow */
443 bfd_elf_generic_reloc, /* special_function */
444 "R_MICROBLAZE_TLSDTPREL32", /* name */
445 FALSE, /* partial_inplace */
447 0x0000ffff, /* dst_mask */
448 FALSE), /* pcrel_offset */
450 /* Computes a dtv-relative displacement, the difference between the value
451 of sym+add and the base address of the thread-local storage block that
452 contains the definition of sym, minus 0x8000. */
453 HOWTO (R_MICROBLAZE_TLSDTPREL64,
455 2, /* size (0 = byte, 1 = short, 2 = long) */
457 FALSE, /* pc_relative */
459 complain_overflow_dont, /* complain_on_overflow */
460 bfd_elf_generic_reloc, /* special_function */
461 "R_MICROBLAZE_TLSDTPREL64", /* name */
462 FALSE, /* partial_inplace */
464 0x0000ffff, /* dst_mask */
465 FALSE), /* pcrel_offset */
467 /* Computes a tp-relative displacement, the difference between the value of
468 sym+add and the value of the thread pointer (r13). */
469 HOWTO (R_MICROBLAZE_TLSGOTTPREL32,
471 2, /* size (0 = byte, 1 = short, 2 = long) */
473 FALSE, /* pc_relative */
475 complain_overflow_dont, /* complain_on_overflow */
476 bfd_elf_generic_reloc, /* special_function */
477 "R_MICROBLAZE_TLSGOTTPREL32", /* name */
478 FALSE, /* partial_inplace */
480 0x0000ffff, /* dst_mask */
481 FALSE), /* pcrel_offset */
483 /* Computes a tp-relative displacement, the difference between the value of
484 sym+add and the value of the thread pointer (r13). */
485 HOWTO (R_MICROBLAZE_TLSTPREL32,
487 2, /* size (0 = byte, 1 = short, 2 = long) */
489 FALSE, /* pc_relative */
491 complain_overflow_dont, /* complain_on_overflow */
492 bfd_elf_generic_reloc, /* special_function */
493 "R_MICROBLAZE_TLSTPREL32", /* name */
494 FALSE, /* partial_inplace */
496 0x0000ffff, /* dst_mask */
497 FALSE), /* pcrel_offset */
502 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
505 /* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */
508 microblaze_elf_howto_init (void)
512 for (i = NUM_ELEM (microblaze_elf_howto_raw); i--;)
516 type = microblaze_elf_howto_raw[i].type;
518 BFD_ASSERT (type < NUM_ELEM (microblaze_elf_howto_table));
520 microblaze_elf_howto_table [type] = & microblaze_elf_howto_raw [i];
524 static reloc_howto_type *
525 microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
526 bfd_reloc_code_real_type code)
528 enum elf_microblaze_reloc_type microblaze_reloc = R_MICROBLAZE_NONE;
533 microblaze_reloc = R_MICROBLAZE_NONE;
535 case BFD_RELOC_MICROBLAZE_64_NONE:
536 microblaze_reloc = R_MICROBLAZE_64_NONE;
539 microblaze_reloc = R_MICROBLAZE_32;
541 /* RVA is treated the same as 32 */
543 microblaze_reloc = R_MICROBLAZE_32;
545 case BFD_RELOC_32_PCREL:
546 microblaze_reloc = R_MICROBLAZE_32_PCREL;
548 case BFD_RELOC_64_PCREL:
549 microblaze_reloc = R_MICROBLAZE_64_PCREL;
551 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
552 microblaze_reloc = R_MICROBLAZE_32_PCREL_LO;
555 microblaze_reloc = R_MICROBLAZE_64;
557 case BFD_RELOC_MICROBLAZE_32_LO:
558 microblaze_reloc = R_MICROBLAZE_32_LO;
560 case BFD_RELOC_MICROBLAZE_32_ROSDA:
561 microblaze_reloc = R_MICROBLAZE_SRO32;
563 case BFD_RELOC_MICROBLAZE_32_RWSDA:
564 microblaze_reloc = R_MICROBLAZE_SRW32;
566 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
567 microblaze_reloc = R_MICROBLAZE_32_SYM_OP_SYM;
569 case BFD_RELOC_VTABLE_INHERIT:
570 microblaze_reloc = R_MICROBLAZE_GNU_VTINHERIT;
572 case BFD_RELOC_VTABLE_ENTRY:
573 microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
575 case BFD_RELOC_MICROBLAZE_64_GOTPC:
576 microblaze_reloc = R_MICROBLAZE_GOTPC_64;
578 case BFD_RELOC_MICROBLAZE_64_GOT:
579 microblaze_reloc = R_MICROBLAZE_GOT_64;
581 case BFD_RELOC_MICROBLAZE_64_PLT:
582 microblaze_reloc = R_MICROBLAZE_PLT_64;
584 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
585 microblaze_reloc = R_MICROBLAZE_GOTOFF_64;
587 case BFD_RELOC_MICROBLAZE_32_GOTOFF:
588 microblaze_reloc = R_MICROBLAZE_GOTOFF_32;
590 case BFD_RELOC_MICROBLAZE_64_TLSGD:
591 microblaze_reloc = R_MICROBLAZE_TLSGD;
593 case BFD_RELOC_MICROBLAZE_64_TLSLD:
594 microblaze_reloc = R_MICROBLAZE_TLSLD;
596 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
597 microblaze_reloc = R_MICROBLAZE_TLSDTPREL32;
599 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
600 microblaze_reloc = R_MICROBLAZE_TLSDTPREL64;
602 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
603 microblaze_reloc = R_MICROBLAZE_TLSDTPMOD32;
605 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
606 microblaze_reloc = R_MICROBLAZE_TLSGOTTPREL32;
608 case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
609 microblaze_reloc = R_MICROBLAZE_TLSTPREL32;
611 case BFD_RELOC_MICROBLAZE_COPY:
612 microblaze_reloc = R_MICROBLAZE_COPY;
615 return (reloc_howto_type *) NULL;
618 if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
619 /* Initialize howto table if needed. */
620 microblaze_elf_howto_init ();
622 return microblaze_elf_howto_table [(int) microblaze_reloc];
625 static reloc_howto_type *
626 microblaze_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
631 for (i = 0; i < NUM_ELEM (microblaze_elf_howto_raw); i++)
632 if (microblaze_elf_howto_raw[i].name != NULL
633 && strcasecmp (microblaze_elf_howto_raw[i].name, r_name) == 0)
634 return µblaze_elf_howto_raw[i];
639 /* Set the howto pointer for a RCE ELF reloc. */
642 microblaze_elf_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
644 Elf_Internal_Rela * dst)
648 if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
649 /* Initialize howto table if needed. */
650 microblaze_elf_howto_init ();
652 r_type = ELF32_R_TYPE (dst->r_info);
653 if (r_type >= R_MICROBLAZE_max)
655 _bfd_error_handler (_("%B: unrecognised MicroBlaze reloc number: %d"),
657 bfd_set_error (bfd_error_bad_value);
658 r_type = R_MICROBLAZE_NONE;
661 cache_ptr->howto = microblaze_elf_howto_table [r_type];
664 /* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
667 microblaze_elf_is_local_label_name (bfd *abfd, const char *name)
669 if (name[0] == 'L' && name[1] == '.')
672 if (name[0] == '$' && name[1] == 'L')
675 /* With gcc, the labels go back to starting with '.', so we accept
676 the generic ELF local label syntax as well. */
677 return _bfd_elf_is_local_label_name (abfd, name);
680 /* The microblaze linker (like many others) needs to keep track of
681 the number of relocs that it decides to copy as dynamic relocs in
682 check_relocs for each symbol. This is so that it can later discard
683 them if they are found to be unnecessary. We store the information
684 in a field extending the regular ELF linker hash table. */
686 struct elf32_mb_dyn_relocs
688 struct elf32_mb_dyn_relocs *next;
690 /* The input section of the reloc. */
693 /* Total number of relocs copied for the input section. */
696 /* Number of pc-relative relocs copied for the input section. */
697 bfd_size_type pc_count;
700 /* ELF linker hash entry. */
702 struct elf32_mb_link_hash_entry
704 struct elf_link_hash_entry elf;
706 /* Track dynamic relocs copied for this symbol. */
707 struct elf32_mb_dyn_relocs *dyn_relocs;
709 /* TLS Reference Types for the symbol; Updated by check_relocs */
710 #define TLS_GD 1 /* GD reloc. */
711 #define TLS_LD 2 /* LD reloc. */
712 #define TLS_TPREL 4 /* TPREL reloc, => IE. */
713 #define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
714 #define TLS_TLS 16 /* Any TLS reloc. */
715 unsigned char tls_mask;
719 #define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD))
720 #define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD))
721 #define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL))
722 #define IS_TLS_NONE(x) (x == 0)
724 #define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent))
726 /* ELF linker hash table. */
728 struct elf32_mb_link_hash_table
730 struct elf_link_hash_table elf;
732 /* Short-cuts to get to dynamic linker sections. */
741 /* Small local sym to section mapping cache. */
742 struct sym_cache sym_sec;
744 /* TLS Local Dynamic GOT Entry */
746 bfd_signed_vma refcount;
751 /* Nonzero if this section has TLS related relocations. */
752 #define has_tls_reloc sec_flg0
754 /* Get the ELF linker hash table from a link_info structure. */
756 #define elf32_mb_hash_table(p) \
757 (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
758 == MICROBLAZE_ELF_DATA ? ((struct elf32_mb_link_hash_table *) ((p)->hash)) : NULL)
760 /* Create an entry in a microblaze ELF linker hash table. */
762 static struct bfd_hash_entry *
763 link_hash_newfunc (struct bfd_hash_entry *entry,
764 struct bfd_hash_table *table,
767 /* Allocate the structure if it has not already been allocated by a
771 entry = bfd_hash_allocate (table,
772 sizeof (struct elf32_mb_link_hash_entry));
777 /* Call the allocation method of the superclass. */
778 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
781 struct elf32_mb_link_hash_entry *eh;
783 eh = (struct elf32_mb_link_hash_entry *) entry;
784 eh->dyn_relocs = NULL;
791 /* Create a mb ELF linker hash table. */
793 static struct bfd_link_hash_table *
794 microblaze_elf_link_hash_table_create (bfd *abfd)
796 struct elf32_mb_link_hash_table *ret;
797 bfd_size_type amt = sizeof (struct elf32_mb_link_hash_table);
799 ret = (struct elf32_mb_link_hash_table *) bfd_zmalloc (amt);
803 if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
804 sizeof (struct elf32_mb_link_hash_entry),
805 MICROBLAZE_ELF_DATA))
811 return &ret->elf.root;
814 /* Set the values of the small data pointers. */
817 microblaze_elf_final_sdp (struct bfd_link_info *info)
819 struct bfd_link_hash_entry *h;
821 h = bfd_link_hash_lookup (info->hash, RO_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE);
822 if (h != (struct bfd_link_hash_entry *) NULL
823 && h->type == bfd_link_hash_defined)
824 ro_small_data_pointer = (h->u.def.value
825 + h->u.def.section->output_section->vma
826 + h->u.def.section->output_offset);
828 h = bfd_link_hash_lookup (info->hash, RW_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE);
829 if (h != (struct bfd_link_hash_entry *) NULL
830 && h->type == bfd_link_hash_defined)
831 rw_small_data_pointer = (h->u.def.value
832 + h->u.def.section->output_section->vma
833 + h->u.def.section->output_offset);
837 dtprel_base (struct bfd_link_info *info)
839 /* If tls_sec is NULL, we should have signalled an error already. */
840 if (elf_hash_table (info)->tls_sec == NULL)
842 return elf_hash_table (info)->tls_sec->vma;
845 /* The size of the thread control block. */
848 /* Output a simple dynamic relocation into SRELOC. */
851 microblaze_elf_output_dynamic_relocation (bfd *output_bfd,
853 unsigned long reloc_index,
860 Elf_Internal_Rela rel;
862 rel.r_info = ELF32_R_INFO (indx, r_type);
863 rel.r_offset = offset;
864 rel.r_addend = addend;
866 bfd_elf32_swap_reloca_out (output_bfd, &rel,
867 (sreloc->contents + reloc_index * sizeof (Elf32_External_Rela)));
870 /* This code is taken from elf32-m32r.c
871 There is some attempt to make this function usable for many architectures,
872 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
873 if only to serve as a learning tool.
875 The RELOCATE_SECTION function is called by the new ELF backend linker
876 to handle the relocations for a section.
878 The relocs are always passed as Rela structures; if the section
879 actually uses Rel structures, the r_addend field will always be
882 This function is responsible for adjust the section contents as
883 necessary, and (if using Rela relocs and generating a
884 relocatable output file) adjusting the reloc addend as
887 This function does not have to worry about setting the reloc
888 address or the reloc symbol index.
890 LOCAL_SYMS is a pointer to the swapped in local symbols.
892 LOCAL_SECTIONS is an array giving the section in the input file
893 corresponding to the st_shndx field of each local symbol.
895 The global hash table entry for the global symbols can be found
896 via elf_sym_hashes (input_bfd).
898 When generating relocatable output, this function must handle
899 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
900 going to be the section symbol corresponding to the output
901 section, which means that the addend must be adjusted
905 microblaze_elf_relocate_section (bfd *output_bfd,
906 struct bfd_link_info *info,
908 asection *input_section,
910 Elf_Internal_Rela *relocs,
911 Elf_Internal_Sym *local_syms,
912 asection **local_sections)
914 struct elf32_mb_link_hash_table *htab;
915 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
916 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
917 Elf_Internal_Rela *rel, *relend;
918 int endian = (bfd_little_endian (output_bfd)) ? 0 : 2;
919 /* Assume success. */
920 bfd_boolean ret = TRUE;
922 bfd_vma *local_got_offsets;
923 unsigned int tls_type;
925 if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1])
926 microblaze_elf_howto_init ();
928 htab = elf32_mb_hash_table (info);
932 local_got_offsets = elf_local_got_offsets (input_bfd);
934 sreloc = elf_section_data (input_section)->sreloc;
937 relend = relocs + input_section->reloc_count;
938 for (; rel < relend; rel++)
941 reloc_howto_type *howto;
942 unsigned long r_symndx;
943 bfd_vma addend = rel->r_addend;
944 bfd_vma offset = rel->r_offset;
945 struct elf_link_hash_entry *h;
946 Elf_Internal_Sym *sym;
948 const char *sym_name;
949 bfd_reloc_status_type r = bfd_reloc_ok;
950 const char *errmsg = NULL;
951 bfd_boolean unresolved_reloc = FALSE;
954 r_type = ELF32_R_TYPE (rel->r_info);
957 if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max)
959 _bfd_error_handler (_("%s: unknown relocation type %d"),
960 bfd_get_filename (input_bfd), (int) r_type);
961 bfd_set_error (bfd_error_bad_value);
966 howto = microblaze_elf_howto_table[r_type];
967 r_symndx = ELF32_R_SYM (rel->r_info);
969 if (bfd_link_relocatable (info))
971 /* This is a relocatable link. We don't have to change
972 anything, unless the reloc is against a section symbol,
973 in which case we have to adjust according to where the
974 section symbol winds up in the output section. */
976 if (r_symndx >= symtab_hdr->sh_info)
977 /* External symbol. */
981 sym = local_syms + r_symndx;
982 sym_name = "<local symbol>";
983 /* STT_SECTION: symbol is associated with a section. */
984 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
985 /* Symbol isn't associated with a section. Nothing to do. */
988 sec = local_sections[r_symndx];
989 addend += sec->output_offset + sym->st_value;
991 /* This can't be done for USE_REL because it doesn't mean anything
992 and elf_link_input_bfd asserts this stays zero. */
993 /* rel->r_addend = addend; */
997 /* Addends are stored with relocs. We're done. */
1000 /* If partial_inplace, we need to store any additional addend
1001 back in the section. */
1002 if (!howto->partial_inplace)
1004 /* ??? Here is a nice place to call a special_function like handler. */
1005 r = _bfd_relocate_contents (howto, input_bfd, addend,
1007 #endif /* USE_REL */
1013 /* This is a final link. */
1016 unresolved_reloc = FALSE;
1018 if (r_symndx < symtab_hdr->sh_info)
1021 sym = local_syms + r_symndx;
1022 sec = local_sections[r_symndx];
1025 sym_name = "<local symbol>";
1026 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1027 /* r_addend may have changed if the reference section was
1029 addend = rel->r_addend;
1033 /* External symbol. */
1034 bfd_boolean warned ATTRIBUTE_UNUSED;
1035 bfd_boolean ignored ATTRIBUTE_UNUSED;
1037 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1038 r_symndx, symtab_hdr, sym_hashes,
1040 unresolved_reloc, warned, ignored);
1041 sym_name = h->root.root.string;
1044 /* Sanity check the address. */
1045 if (offset > bfd_get_section_limit (input_bfd, input_section))
1047 r = bfd_reloc_outofrange;
1051 switch ((int) r_type)
1053 case (int) R_MICROBLAZE_SRO32 :
1057 /* Only relocate if the symbol is defined. */
1060 name = bfd_get_section_name (sec->owner, sec);
1062 if (strcmp (name, ".sdata2") == 0
1063 || strcmp (name, ".sbss2") == 0)
1065 if (ro_small_data_pointer == 0)
1066 microblaze_elf_final_sdp (info);
1067 if (ro_small_data_pointer == 0)
1070 r = bfd_reloc_undefined;
1074 /* At this point `relocation' contains the object's
1076 relocation -= ro_small_data_pointer;
1077 /* Now it contains the offset from _SDA2_BASE_. */
1078 r = _bfd_final_link_relocate (howto, input_bfd,
1081 relocation, addend);
1086 (_("%s: The target (%s) of an %s relocation "
1087 "is in the wrong section (%s)"),
1088 bfd_get_filename (input_bfd),
1090 microblaze_elf_howto_table[(int) r_type]->name,
1091 bfd_get_section_name (sec->owner, sec));
1092 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1100 case (int) R_MICROBLAZE_SRW32 :
1104 /* Only relocate if the symbol is defined. */
1107 name = bfd_get_section_name (sec->owner, sec);
1109 if (strcmp (name, ".sdata") == 0
1110 || strcmp (name, ".sbss") == 0)
1112 if (rw_small_data_pointer == 0)
1113 microblaze_elf_final_sdp (info);
1114 if (rw_small_data_pointer == 0)
1117 r = bfd_reloc_undefined;
1121 /* At this point `relocation' contains the object's
1123 relocation -= rw_small_data_pointer;
1124 /* Now it contains the offset from _SDA_BASE_. */
1125 r = _bfd_final_link_relocate (howto, input_bfd,
1128 relocation, addend);
1133 (_("%s: The target (%s) of an %s relocation "
1134 "is in the wrong section (%s)"),
1135 bfd_get_filename (input_bfd),
1137 microblaze_elf_howto_table[(int) r_type]->name,
1138 bfd_get_section_name (sec->owner, sec));
1139 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1147 case (int) R_MICROBLAZE_32_SYM_OP_SYM:
1148 break; /* Do nothing. */
1150 case (int) R_MICROBLAZE_GOTPC_64:
1151 relocation = htab->sgotplt->output_section->vma
1152 + htab->sgotplt->output_offset;
1153 relocation -= (input_section->output_section->vma
1154 + input_section->output_offset
1155 + offset + INST_WORD_SIZE);
1156 relocation += addend;
1157 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1158 contents + offset + endian);
1159 bfd_put_16 (input_bfd, relocation & 0xffff,
1160 contents + offset + endian + INST_WORD_SIZE);
1163 case (int) R_MICROBLAZE_PLT_64:
1166 if (htab->splt != NULL && h != NULL
1167 && h->plt.offset != (bfd_vma) -1)
1169 relocation = (htab->splt->output_section->vma
1170 + htab->splt->output_offset
1172 unresolved_reloc = FALSE;
1173 immediate = relocation - (input_section->output_section->vma
1174 + input_section->output_offset
1175 + offset + INST_WORD_SIZE);
1176 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
1177 contents + offset + endian);
1178 bfd_put_16 (input_bfd, immediate & 0xffff,
1179 contents + offset + endian + INST_WORD_SIZE);
1183 relocation -= (input_section->output_section->vma
1184 + input_section->output_offset
1185 + offset + INST_WORD_SIZE);
1186 immediate = relocation;
1187 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
1188 contents + offset + endian);
1189 bfd_put_16 (input_bfd, immediate & 0xffff,
1190 contents + offset + endian + INST_WORD_SIZE);
1195 case (int) R_MICROBLAZE_TLSGD:
1196 tls_type = (TLS_TLS | TLS_GD);
1198 case (int) R_MICROBLAZE_TLSLD:
1199 tls_type = (TLS_TLS | TLS_LD);
1202 case (int) R_MICROBLAZE_GOT_64:
1207 bfd_vma static_value;
1209 bfd_boolean need_relocs = FALSE;
1210 if (htab->sgot == NULL)
1216 /* 1. Identify GOT Offset;
1217 2. Compute Static Values
1218 3. Process Module Id, Process Offset
1219 4. Fixup Relocation with GOT offset value. */
1221 /* 1. Determine GOT Offset to use : TLS_LD, global, local */
1222 if (IS_TLS_LD (tls_type))
1223 offp = &htab->tlsld_got.offset;
1226 if (htab->sgotplt != NULL && h->got.offset != (bfd_vma) -1)
1227 offp = &h->got.offset;
1233 if (local_got_offsets == NULL)
1235 offp = &local_got_offsets[r_symndx];
1244 if (IS_TLS_LD(tls_type) || IS_TLS_GD(tls_type))
1247 /* Symbol index to use for relocs */
1251 elf_hash_table (info)->dynamic_sections_created;
1253 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
1254 bfd_link_pic (info),
1256 && (!bfd_link_pic (info)
1257 || !SYMBOL_REFERENCES_LOCAL (info, h)))
1261 /* Need to generate relocs ? */
1262 if ((bfd_link_pic (info) || indx != 0)
1264 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1265 || h->root.type != bfd_link_hash_undefweak))
1268 /* 2. Compute/Emit Static value of r-expression */
1269 static_value = relocation + addend;
1271 /* 3. Process module-id and offset */
1272 if (! ((*offp) & 1) )
1276 got_offset = (htab->sgot->output_section->vma
1277 + htab->sgot->output_offset
1280 /* Process module-id */
1281 if (IS_TLS_LD(tls_type))
1283 if (! bfd_link_pic (info))
1285 bfd_put_32 (output_bfd, 1, htab->sgot->contents + off);
1289 microblaze_elf_output_dynamic_relocation (output_bfd,
1290 htab->srelgot, htab->srelgot->reloc_count++,
1291 /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32,
1295 else if (IS_TLS_GD(tls_type))
1299 bfd_put_32 (output_bfd, 1, htab->sgot->contents + off);
1303 microblaze_elf_output_dynamic_relocation (output_bfd,
1305 htab->srelgot->reloc_count++,
1306 /* symindex= */ indx, R_MICROBLAZE_TLSDTPMOD32,
1307 got_offset, indx ? 0 : static_value);
1311 /* Process Offset */
1312 if (htab->srelgot == NULL)
1315 got_offset = (htab->sgot->output_section->vma
1316 + htab->sgot->output_offset
1318 if (IS_TLS_LD(tls_type))
1320 /* For LD, offset should be 0 */
1322 bfd_put_32 (output_bfd, 0, htab->sgot->contents + off2);
1324 else if (IS_TLS_GD(tls_type))
1327 static_value -= dtprel_base(info);
1330 microblaze_elf_output_dynamic_relocation (output_bfd,
1331 htab->srelgot, htab->srelgot->reloc_count++,
1332 /* symindex= */ indx, R_MICROBLAZE_TLSDTPREL32,
1333 got_offset, indx ? 0 : static_value);
1337 bfd_put_32 (output_bfd, static_value,
1338 htab->sgot->contents + off2);
1343 bfd_put_32 (output_bfd, static_value,
1344 htab->sgot->contents + off2);
1346 /* Relocs for dyn symbols generated by
1347 finish_dynamic_symbols */
1348 if (bfd_link_pic (info) && h == NULL)
1351 microblaze_elf_output_dynamic_relocation (output_bfd,
1352 htab->srelgot, htab->srelgot->reloc_count++,
1353 /* symindex= */ indx, R_MICROBLAZE_REL,
1354 got_offset, static_value);
1359 /* 4. Fixup Relocation with GOT offset value
1360 Compute relative address of GOT entry for applying
1361 the current relocation */
1362 relocation = htab->sgot->output_section->vma
1363 + htab->sgot->output_offset
1365 - htab->sgotplt->output_section->vma
1366 - htab->sgotplt->output_offset;
1368 /* Apply Current Relocation */
1369 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1370 contents + offset + endian);
1371 bfd_put_16 (input_bfd, relocation & 0xffff,
1372 contents + offset + endian + INST_WORD_SIZE);
1374 unresolved_reloc = FALSE;
1378 case (int) R_MICROBLAZE_GOTOFF_64:
1381 unsigned short lo, high;
1382 relocation += addend;
1383 relocation -= htab->sgotplt->output_section->vma
1384 + htab->sgotplt->output_offset;
1385 /* Write this value into correct location. */
1386 immediate = relocation;
1387 lo = immediate & 0x0000ffff;
1388 high = (immediate >> 16) & 0x0000ffff;
1389 bfd_put_16 (input_bfd, high, contents + offset + endian);
1390 bfd_put_16 (input_bfd, lo, contents + offset + INST_WORD_SIZE + endian);
1394 case (int) R_MICROBLAZE_GOTOFF_32:
1396 relocation += addend;
1397 relocation -= htab->sgotplt->output_section->vma
1398 + htab->sgotplt->output_offset;
1399 /* Write this value into correct location. */
1400 bfd_put_32 (input_bfd, relocation, contents + offset);
1404 case (int) R_MICROBLAZE_TLSDTPREL64:
1405 relocation += addend;
1406 relocation -= dtprel_base(info);
1407 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1408 contents + offset + 2);
1409 bfd_put_16 (input_bfd, relocation & 0xffff,
1410 contents + offset + 2 + INST_WORD_SIZE);
1412 case (int) R_MICROBLAZE_64_PCREL :
1413 case (int) R_MICROBLAZE_64:
1414 case (int) R_MICROBLAZE_32:
1416 /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
1417 from removed linkonce sections, or sections discarded by
1419 if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
1421 relocation += addend;
1422 if (r_type == R_MICROBLAZE_32)
1423 bfd_put_32 (input_bfd, relocation, contents + offset);
1426 if (r_type == R_MICROBLAZE_64_PCREL)
1427 relocation -= (input_section->output_section->vma
1428 + input_section->output_offset
1429 + offset + INST_WORD_SIZE);
1430 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1431 contents + offset + endian);
1432 bfd_put_16 (input_bfd, relocation & 0xffff,
1433 contents + offset + endian + INST_WORD_SIZE);
1438 if ((bfd_link_pic (info)
1440 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1441 || h->root.type != bfd_link_hash_undefweak)
1442 && (!howto->pc_relative
1446 || !h->def_regular))))
1447 || (!bfd_link_pic (info)
1453 || h->root.type == bfd_link_hash_undefweak
1454 || h->root.type == bfd_link_hash_undefined)))
1456 Elf_Internal_Rela outrel;
1460 /* When generating a shared object, these relocations
1461 are copied into the output file to be resolved at run
1464 BFD_ASSERT (sreloc != NULL);
1469 _bfd_elf_section_offset (output_bfd, info, input_section,
1471 if (outrel.r_offset == (bfd_vma) -1)
1473 else if (outrel.r_offset == (bfd_vma) -2)
1475 outrel.r_offset += (input_section->output_section->vma
1476 + input_section->output_offset);
1479 memset (&outrel, 0, sizeof outrel);
1480 /* h->dynindx may be -1 if the symbol was marked to
1483 && ((! info->symbolic && h->dynindx != -1)
1484 || !h->def_regular))
1486 BFD_ASSERT (h->dynindx != -1);
1487 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1488 outrel.r_addend = addend;
1492 if (r_type == R_MICROBLAZE_32)
1494 outrel.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL);
1495 outrel.r_addend = relocation + addend;
1501 (_("%B: probably compiled without -fPIC?"),
1503 bfd_set_error (bfd_error_bad_value);
1508 loc = sreloc->contents;
1509 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
1510 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1515 relocation += addend;
1516 if (r_type == R_MICROBLAZE_32)
1517 bfd_put_32 (input_bfd, relocation, contents + offset);
1520 if (r_type == R_MICROBLAZE_64_PCREL)
1521 relocation -= (input_section->output_section->vma
1522 + input_section->output_offset
1523 + offset + INST_WORD_SIZE);
1524 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1525 contents + offset + endian);
1526 bfd_put_16 (input_bfd, relocation & 0xffff,
1527 contents + offset + endian + INST_WORD_SIZE);
1534 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1536 relocation, addend);
1543 if (r != bfd_reloc_ok)
1545 /* FIXME: This should be generic enough to go in a utility. */
1549 name = h->root.root.string;
1552 name = (bfd_elf_string_from_elf_section
1553 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1554 if (name == NULL || *name == '\0')
1555 name = bfd_section_name (input_bfd, sec);
1563 case bfd_reloc_overflow:
1564 (*info->callbacks->reloc_overflow)
1565 (info, (h ? &h->root : NULL), name, howto->name,
1566 (bfd_vma) 0, input_bfd, input_section, offset);
1569 case bfd_reloc_undefined:
1570 (*info->callbacks->undefined_symbol)
1571 (info, name, input_bfd, input_section, offset, TRUE);
1574 case bfd_reloc_outofrange:
1575 errmsg = _("internal error: out of range error");
1578 case bfd_reloc_notsupported:
1579 errmsg = _("internal error: unsupported relocation error");
1582 case bfd_reloc_dangerous:
1583 errmsg = _("internal error: dangerous error");
1587 errmsg = _("internal error: unknown error");
1590 (*info->callbacks->warning) (info, errmsg, name, input_bfd,
1591 input_section, offset);
1600 /* Merge backend specific data from an object file to the output
1601 object file when linking.
1603 Note: We only use this hook to catch endian mismatches. */
1605 microblaze_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
1607 /* Check if we have the same endianess. */
1608 if (! _bfd_generic_verify_endian_match (ibfd, obfd))
1615 /* Calculate fixup value for reference. */
1618 calc_fixup (bfd_vma start, bfd_vma size, asection *sec)
1620 bfd_vma end = start + size;
1623 if (sec == NULL || sec->relax == NULL)
1626 /* Look for addr in relax table, total fixup value. */
1627 for (i = 0; i < sec->relax_count; i++)
1629 if (end <= sec->relax[i].addr)
1631 if ((end != start) && (start > sec->relax[i].addr))
1633 fixup += sec->relax[i].size;
1638 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1639 a 32-bit instruction. */
1641 microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1643 unsigned long instr = bfd_get_32 (abfd, bfd_addr);
1644 instr &= ~0x0000ffff;
1645 instr |= (val & 0x0000ffff);
1646 bfd_put_32 (abfd, instr, bfd_addr);
1649 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1650 two consecutive 32-bit instructions. */
1652 microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1654 unsigned long instr_hi;
1655 unsigned long instr_lo;
1657 instr_hi = bfd_get_32 (abfd, bfd_addr);
1658 instr_hi &= ~0x0000ffff;
1659 instr_hi |= ((val >> 16) & 0x0000ffff);
1660 bfd_put_32 (abfd, instr_hi, bfd_addr);
1662 instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE);
1663 instr_lo &= ~0x0000ffff;
1664 instr_lo |= (val & 0x0000ffff);
1665 bfd_put_32 (abfd, instr_lo, bfd_addr + INST_WORD_SIZE);
1669 microblaze_elf_relax_section (bfd *abfd,
1671 struct bfd_link_info *link_info,
1674 Elf_Internal_Shdr *symtab_hdr;
1675 Elf_Internal_Rela *internal_relocs;
1676 Elf_Internal_Rela *free_relocs = NULL;
1677 Elf_Internal_Rela *irel, *irelend;
1678 bfd_byte *contents = NULL;
1679 bfd_byte *free_contents = NULL;
1684 struct elf_link_hash_entry *sym_hash;
1685 Elf_Internal_Sym *isymbuf, *isymend;
1686 Elf_Internal_Sym *isym;
1691 /* We only do this once per section. We may be able to delete some code
1692 by running multiple passes, but it is not worth it. */
1695 /* Only do this for a text section. */
1696 if (bfd_link_relocatable (link_info)
1697 || (sec->flags & SEC_RELOC) == 0
1698 || (sec->reloc_count == 0)
1699 || (sec->flags & SEC_CODE) == 0)
1702 BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0));
1704 /* If this is the first time we have been called for this section,
1705 initialize the cooked size. */
1707 sec->size = sec->rawsize;
1709 /* Get symbols for this section. */
1710 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1711 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1712 symcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
1713 if (isymbuf == NULL)
1714 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount,
1715 0, NULL, NULL, NULL);
1716 BFD_ASSERT (isymbuf != NULL);
1718 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
1719 if (internal_relocs == NULL)
1721 if (! link_info->keep_memory)
1722 free_relocs = internal_relocs;
1724 sec->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
1725 * sizeof (struct relax_table));
1726 if (sec->relax == NULL)
1728 sec->relax_count = 0;
1730 irelend = internal_relocs + sec->reloc_count;
1732 for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1735 if ((ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL)
1736 && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64 ))
1737 continue; /* Can't delete this reloc. */
1739 /* Get the section contents. */
1740 if (contents == NULL)
1742 if (elf_section_data (sec)->this_hdr.contents != NULL)
1743 contents = elf_section_data (sec)->this_hdr.contents;
1746 contents = (bfd_byte *) bfd_malloc (sec->size);
1747 if (contents == NULL)
1749 free_contents = contents;
1751 if (!bfd_get_section_contents (abfd, sec, contents,
1752 (file_ptr) 0, sec->size))
1754 elf_section_data (sec)->this_hdr.contents = contents;
1758 /* Get the value of the symbol referred to by the reloc. */
1759 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1761 /* A local symbol. */
1764 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1765 if (isym->st_shndx == SHN_UNDEF)
1766 sym_sec = bfd_und_section_ptr;
1767 else if (isym->st_shndx == SHN_ABS)
1768 sym_sec = bfd_abs_section_ptr;
1769 else if (isym->st_shndx == SHN_COMMON)
1770 sym_sec = bfd_com_section_ptr;
1772 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1774 symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
1779 struct elf_link_hash_entry *h;
1781 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1782 h = elf_sym_hashes (abfd)[indx];
1783 BFD_ASSERT (h != NULL);
1785 if (h->root.type != bfd_link_hash_defined
1786 && h->root.type != bfd_link_hash_defweak)
1787 /* This appears to be a reference to an undefined
1788 symbol. Just ignore it--it will be caught by the
1789 regular reloc processing. */
1792 symval = (h->root.u.def.value
1793 + h->root.u.def.section->output_section->vma
1794 + h->root.u.def.section->output_offset);
1797 /* If this is a PC-relative reloc, subtract the instr offset from
1798 the symbol value. */
1799 if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_64_PCREL)
1801 symval = symval + irel->r_addend
1803 + sec->output_section->vma
1804 + sec->output_offset);
1807 symval += irel->r_addend;
1809 if ((symval & 0xffff8000) == 0
1810 || (symval & 0xffff8000) == 0xffff8000)
1812 /* We can delete this instruction. */
1813 sec->relax[sec->relax_count].addr = irel->r_offset;
1814 sec->relax[sec->relax_count].size = INST_WORD_SIZE;
1817 /* Rewrite relocation type. */
1818 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1820 case R_MICROBLAZE_64_PCREL:
1821 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1822 (int) R_MICROBLAZE_32_PCREL_LO);
1824 case R_MICROBLAZE_64:
1825 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1826 (int) R_MICROBLAZE_32_LO);
1829 /* Cannot happen. */
1833 } /* Loop through all relocations. */
1835 /* Loop through the relocs again, and see if anything needs to change. */
1836 if (sec->relax_count > 0)
1838 shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1840 sec->relax[sec->relax_count].addr = sec->size;
1842 for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1846 /* Get the new reloc address. */
1847 nraddr = irel->r_offset - calc_fixup (irel->r_offset, 0, sec);
1848 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1852 case R_MICROBLAZE_64_PCREL:
1854 case R_MICROBLAZE_64:
1855 case R_MICROBLAZE_32_LO:
1856 /* If this reloc is against a symbol defined in this
1857 section, we must check the addend to see it will put the value in
1858 range to be adjusted, and hence must be changed. */
1859 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1861 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1862 /* Only handle relocs against .text. */
1863 if (isym->st_shndx == shndx
1864 && ELF32_ST_TYPE (isym->st_info) == STT_SECTION)
1865 irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
1868 case R_MICROBLAZE_NONE:
1870 /* This was a PC-relative instruction that was
1871 completely resolved. */
1873 bfd_vma target_address;
1874 target_address = irel->r_addend + irel->r_offset;
1875 sfix = calc_fixup (irel->r_offset, 0, sec);
1876 efix = calc_fixup (target_address, 0, sec);
1877 irel->r_addend -= (efix - sfix);
1878 /* Should use HOWTO. */
1879 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
1883 case R_MICROBLAZE_64_NONE:
1885 /* This was a PC-relative 64-bit instruction that was
1886 completely resolved. */
1888 bfd_vma target_address;
1889 target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE;
1890 sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec);
1891 efix = calc_fixup (target_address, 0, sec);
1892 irel->r_addend -= (efix - sfix);
1893 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset
1894 + INST_WORD_SIZE, irel->r_addend);
1898 irel->r_offset = nraddr;
1899 } /* Change all relocs in this section. */
1901 /* Look through all other sections. */
1902 for (o = abfd->sections; o != NULL; o = o->next)
1904 Elf_Internal_Rela *irelocs;
1905 Elf_Internal_Rela *irelscan, *irelscanend;
1906 bfd_byte *ocontents;
1909 || (o->flags & SEC_RELOC) == 0
1910 || o->reloc_count == 0)
1913 /* We always cache the relocs. Perhaps, if info->keep_memory is
1914 FALSE, we should free them, if we are permitted to. */
1916 irelocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, TRUE);
1917 if (irelocs == NULL)
1921 irelscanend = irelocs + o->reloc_count;
1922 for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
1924 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
1926 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1928 /* Look at the reloc only if the value has been resolved. */
1929 if (isym->st_shndx == shndx
1930 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
1932 if (ocontents == NULL)
1934 if (elf_section_data (o)->this_hdr.contents != NULL)
1935 ocontents = elf_section_data (o)->this_hdr.contents;
1938 /* We always cache the section contents.
1939 Perhaps, if info->keep_memory is FALSE, we
1940 should free them, if we are permitted to. */
1941 if (o->rawsize == 0)
1942 o->rawsize = o->size;
1943 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
1944 if (ocontents == NULL)
1946 if (!bfd_get_section_contents (abfd, o, ocontents,
1950 elf_section_data (o)->this_hdr.contents = ocontents;
1954 irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
1956 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
1958 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1960 /* Look at the reloc only if the value has been resolved. */
1961 if (ocontents == NULL)
1963 if (elf_section_data (o)->this_hdr.contents != NULL)
1964 ocontents = elf_section_data (o)->this_hdr.contents;
1967 /* We always cache the section contents.
1968 Perhaps, if info->keep_memory is FALSE, we
1969 should free them, if we are permitted to. */
1971 if (o->rawsize == 0)
1972 o->rawsize = o->size;
1973 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
1974 if (ocontents == NULL)
1976 if (!bfd_get_section_contents (abfd, o, ocontents,
1980 elf_section_data (o)->this_hdr.contents = ocontents;
1983 irelscan->r_addend -= calc_fixup (irel->r_addend
1989 else if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO)
1990 || (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_LO))
1992 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1994 /* Look at the reloc only if the value has been resolved. */
1995 if (isym->st_shndx == shndx
1996 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
1999 bfd_vma target_address;
2001 if (ocontents == NULL)
2003 if (elf_section_data (o)->this_hdr.contents != NULL)
2004 ocontents = elf_section_data (o)->this_hdr.contents;
2007 /* We always cache the section contents.
2008 Perhaps, if info->keep_memory is FALSE, we
2009 should free them, if we are permitted to. */
2010 if (o->rawsize == 0)
2011 o->rawsize = o->size;
2012 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2013 if (ocontents == NULL)
2015 if (!bfd_get_section_contents (abfd, o, ocontents,
2019 elf_section_data (o)->this_hdr.contents = ocontents;
2023 unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
2024 immediate = instr & 0x0000ffff;
2025 target_address = immediate;
2026 offset = calc_fixup (target_address, 0, sec);
2027 immediate -= offset;
2028 irelscan->r_addend -= offset;
2029 microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
2030 irelscan->r_addend);
2034 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64)
2036 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2038 /* Look at the reloc only if the value has been resolved. */
2039 if (isym->st_shndx == shndx
2040 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2044 if (ocontents == NULL)
2046 if (elf_section_data (o)->this_hdr.contents != NULL)
2047 ocontents = elf_section_data (o)->this_hdr.contents;
2050 /* We always cache the section contents.
2051 Perhaps, if info->keep_memory is FALSE, we
2052 should free them, if we are permitted to. */
2054 if (o->rawsize == 0)
2055 o->rawsize = o->size;
2056 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2057 if (ocontents == NULL)
2059 if (!bfd_get_section_contents (abfd, o, ocontents,
2063 elf_section_data (o)->this_hdr.contents = ocontents;
2066 unsigned long instr_hi = bfd_get_32 (abfd, ocontents
2067 + irelscan->r_offset);
2068 unsigned long instr_lo = bfd_get_32 (abfd, ocontents
2069 + irelscan->r_offset
2071 immediate = (instr_hi & 0x0000ffff) << 16;
2072 immediate |= (instr_lo & 0x0000ffff);
2073 offset = calc_fixup (irelscan->r_addend, 0, sec);
2074 immediate -= offset;
2075 irelscan->r_addend -= offset;
2078 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
2080 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2082 /* Look at the reloc only if the value has been resolved. */
2083 if (isym->st_shndx == shndx
2084 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2087 bfd_vma target_address;
2089 if (ocontents == NULL)
2091 if (elf_section_data (o)->this_hdr.contents != NULL)
2092 ocontents = elf_section_data (o)->this_hdr.contents;
2095 /* We always cache the section contents.
2096 Perhaps, if info->keep_memory is FALSE, we
2097 should free them, if we are permitted to. */
2098 if (o->rawsize == 0)
2099 o->rawsize = o->size;
2100 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2101 if (ocontents == NULL)
2103 if (!bfd_get_section_contents (abfd, o, ocontents,
2107 elf_section_data (o)->this_hdr.contents = ocontents;
2110 unsigned long instr_hi = bfd_get_32 (abfd, ocontents
2111 + irelscan->r_offset);
2112 unsigned long instr_lo = bfd_get_32 (abfd, ocontents
2113 + irelscan->r_offset
2115 immediate = (instr_hi & 0x0000ffff) << 16;
2116 immediate |= (instr_lo & 0x0000ffff);
2117 target_address = immediate;
2118 offset = calc_fixup (target_address, 0, sec);
2119 immediate -= offset;
2120 irelscan->r_addend -= offset;
2121 microblaze_bfd_write_imm_value_64 (abfd, ocontents
2122 + irelscan->r_offset, immediate);
2128 /* Adjust the local symbols defined in this section. */
2129 isymend = isymbuf + symtab_hdr->sh_info;
2130 for (isym = isymbuf; isym < isymend; isym++)
2132 if (isym->st_shndx == shndx)
2134 isym->st_value -= calc_fixup (isym->st_value, 0, sec);
2136 isym->st_size -= calc_fixup (isym->st_value, isym->st_size, sec);
2140 /* Now adjust the global symbols defined in this section. */
2141 isym = isymbuf + symtab_hdr->sh_info;
2142 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)) - symtab_hdr->sh_info;
2143 for (sym_index = 0; sym_index < symcount; sym_index++)
2145 sym_hash = elf_sym_hashes (abfd)[sym_index];
2146 if ((sym_hash->root.type == bfd_link_hash_defined
2147 || sym_hash->root.type == bfd_link_hash_defweak)
2148 && sym_hash->root.u.def.section == sec)
2150 sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value,
2153 sym_hash->size -= calc_fixup (sym_hash->root.u.def.value,
2154 sym_hash->size, sec);
2158 /* Physically move the code and change the cooked size. */
2159 dest = sec->relax[0].addr;
2160 for (i = 0; i < sec->relax_count; i++)
2163 src = sec->relax[i].addr + sec->relax[i].size;
2164 len = sec->relax[i+1].addr - sec->relax[i].addr - sec->relax[i].size;
2166 memmove (contents + dest, contents + src, len);
2167 sec->size -= sec->relax[i].size;
2171 elf_section_data (sec)->relocs = internal_relocs;
2174 elf_section_data (sec)->this_hdr.contents = contents;
2175 free_contents = NULL;
2177 symtab_hdr->contents = (bfd_byte *) isymbuf;
2180 if (free_relocs != NULL)
2186 if (free_contents != NULL)
2188 if (!link_info->keep_memory)
2189 free (free_contents);
2191 /* Cache the section contents for elf_link_input_bfd. */
2192 elf_section_data (sec)->this_hdr.contents = contents;
2193 free_contents = NULL;
2196 if (sec->relax_count == 0)
2207 if (free_relocs != NULL)
2209 if (free_contents != NULL)
2210 free (free_contents);
2211 if (sec->relax != NULL)
2215 sec->relax_count = 0;
2220 /* Return the section that should be marked against GC for a given
2224 microblaze_elf_gc_mark_hook (asection *sec,
2225 struct bfd_link_info * info,
2226 Elf_Internal_Rela * rel,
2227 struct elf_link_hash_entry * h,
2228 Elf_Internal_Sym * sym)
2231 switch (ELF32_R_TYPE (rel->r_info))
2233 case R_MICROBLAZE_GNU_VTINHERIT:
2234 case R_MICROBLAZE_GNU_VTENTRY:
2238 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
2241 /* Update the got entry reference counts for the section being removed. */
2244 microblaze_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
2245 struct bfd_link_info * info ATTRIBUTE_UNUSED,
2246 asection * sec ATTRIBUTE_UNUSED,
2247 const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
2254 #define PLT_ENTRY_SIZE 16
2256 #define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
2257 #define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
2258 #define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
2259 #define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
2260 #define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
2262 /* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
2263 shortcuts to them in our hash table. */
2266 create_got_section (bfd *dynobj, struct bfd_link_info *info)
2268 struct elf32_mb_link_hash_table *htab;
2270 if (! _bfd_elf_create_got_section (dynobj, info))
2272 htab = elf32_mb_hash_table (info);
2276 htab->sgot = bfd_get_linker_section (dynobj, ".got");
2277 htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
2278 if (!htab->sgot || !htab->sgotplt)
2281 if ((htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got")) == NULL)
2282 htab->srelgot = bfd_make_section_anyway (dynobj, ".rela.got");
2283 if (htab->srelgot == NULL
2284 || ! bfd_set_section_flags (dynobj, htab->srelgot, SEC_ALLOC
2288 | SEC_LINKER_CREATED
2290 || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
2296 update_local_sym_info (bfd *abfd,
2297 Elf_Internal_Shdr *symtab_hdr,
2298 unsigned long r_symndx,
2299 unsigned int tls_type)
2301 bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
2302 unsigned char *local_got_tls_masks;
2304 if (local_got_refcounts == NULL)
2306 bfd_size_type size = symtab_hdr->sh_info;
2308 size *= (sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks));
2309 local_got_refcounts = bfd_zalloc (abfd, size);
2310 if (local_got_refcounts == NULL)
2312 elf_local_got_refcounts (abfd) = local_got_refcounts;
2315 local_got_tls_masks =
2316 (unsigned char *) (local_got_refcounts + symtab_hdr->sh_info);
2317 local_got_tls_masks[r_symndx] |= tls_type;
2318 local_got_refcounts[r_symndx] += 1;
2322 /* Look through the relocs for a section during the first phase. */
2325 microblaze_elf_check_relocs (bfd * abfd,
2326 struct bfd_link_info * info,
2328 const Elf_Internal_Rela * relocs)
2330 Elf_Internal_Shdr * symtab_hdr;
2331 struct elf_link_hash_entry ** sym_hashes;
2332 struct elf_link_hash_entry ** sym_hashes_end;
2333 const Elf_Internal_Rela * rel;
2334 const Elf_Internal_Rela * rel_end;
2335 struct elf32_mb_link_hash_table *htab;
2336 asection *sreloc = NULL;
2338 if (bfd_link_relocatable (info))
2341 htab = elf32_mb_hash_table (info);
2345 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
2346 sym_hashes = elf_sym_hashes (abfd);
2347 sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
2348 if (!elf_bad_symtab (abfd))
2349 sym_hashes_end -= symtab_hdr->sh_info;
2351 rel_end = relocs + sec->reloc_count;
2353 for (rel = relocs; rel < rel_end; rel++)
2355 unsigned int r_type;
2356 struct elf_link_hash_entry * h;
2357 unsigned long r_symndx;
2358 unsigned char tls_type = 0;
2360 r_symndx = ELF32_R_SYM (rel->r_info);
2361 r_type = ELF32_R_TYPE (rel->r_info);
2363 if (r_symndx < symtab_hdr->sh_info)
2367 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
2369 /* PR15323, ref flags aren't set for references in the same
2371 h->root.non_ir_ref = 1;
2376 /* This relocation describes the C++ object vtable hierarchy.
2377 Reconstruct it for later use during GC. */
2378 case R_MICROBLAZE_GNU_VTINHERIT:
2379 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2383 /* This relocation describes which C++ vtable entries are actually
2384 used. Record for later use during GC. */
2385 case R_MICROBLAZE_GNU_VTENTRY:
2386 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
2390 /* This relocation requires .plt entry. */
2391 case R_MICROBLAZE_PLT_64:
2395 h->plt.refcount += 1;
2399 /* This relocation requires .got entry. */
2400 case R_MICROBLAZE_TLSGD:
2401 tls_type |= (TLS_TLS | TLS_GD);
2403 case R_MICROBLAZE_TLSLD:
2404 tls_type |= (TLS_TLS | TLS_LD);
2407 sec->has_tls_reloc = 1;
2409 case R_MICROBLAZE_GOT_64:
2410 if (htab->sgot == NULL)
2412 if (htab->elf.dynobj == NULL)
2413 htab->elf.dynobj = abfd;
2414 if (!create_got_section (htab->elf.dynobj, info))
2419 h->got.refcount += 1;
2420 elf32_mb_hash_entry (h)->tls_mask |= tls_type;
2424 if (! update_local_sym_info(abfd, symtab_hdr, r_symndx, tls_type) )
2429 case R_MICROBLAZE_64:
2430 case R_MICROBLAZE_64_PCREL:
2431 case R_MICROBLAZE_32:
2433 if (h != NULL && !bfd_link_pic (info))
2435 /* we may need a copy reloc. */
2438 /* we may also need a .plt entry. */
2439 h->plt.refcount += 1;
2440 if (ELF32_R_TYPE (rel->r_info) != R_MICROBLAZE_64_PCREL)
2441 h->pointer_equality_needed = 1;
2445 /* If we are creating a shared library, and this is a reloc
2446 against a global symbol, or a non PC relative reloc
2447 against a local symbol, then we need to copy the reloc
2448 into the shared library. However, if we are linking with
2449 -Bsymbolic, we do not need to copy a reloc against a
2450 global symbol which is defined in an object we are
2451 including in the link (i.e., DEF_REGULAR is set). At
2452 this point we have not seen all the input files, so it is
2453 possible that DEF_REGULAR is not set now but will be set
2454 later (it is never cleared). In case of a weak definition,
2455 DEF_REGULAR may be cleared later by a strong definition in
2456 a shared library. We account for that possibility below by
2457 storing information in the relocs_copied field of the hash
2458 table entry. A similar situation occurs when creating
2459 shared libraries and symbol visibility changes render the
2462 If on the other hand, we are creating an executable, we
2463 may need to keep relocations for symbols satisfied by a
2464 dynamic library if we manage to avoid copy relocs for the
2467 if ((bfd_link_pic (info)
2468 && (sec->flags & SEC_ALLOC) != 0
2469 && (r_type != R_MICROBLAZE_64_PCREL
2471 && (! info->symbolic
2472 || h->root.type == bfd_link_hash_defweak
2473 || !h->def_regular))))
2474 || (!bfd_link_pic (info)
2475 && (sec->flags & SEC_ALLOC) != 0
2477 && (h->root.type == bfd_link_hash_defweak
2478 || !h->def_regular)))
2480 struct elf32_mb_dyn_relocs *p;
2481 struct elf32_mb_dyn_relocs **head;
2483 /* When creating a shared object, we must copy these
2484 relocs into the output file. We create a reloc
2485 section in dynobj and make room for the reloc. */
2491 if (htab->elf.dynobj == NULL)
2492 htab->elf.dynobj = abfd;
2493 dynobj = htab->elf.dynobj;
2495 sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
2501 /* If this is a global symbol, we count the number of
2502 relocations we need for this symbol. */
2504 head = &((struct elf32_mb_link_hash_entry *) h)->dyn_relocs;
2507 /* Track dynamic relocs needed for local syms too.
2508 We really need local syms available to do this
2512 Elf_Internal_Sym *isym;
2515 isym = bfd_sym_from_r_symndx (&htab->sym_sec,
2520 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2524 vpp = &elf_section_data (s)->local_dynrel;
2525 head = (struct elf32_mb_dyn_relocs **) vpp;
2529 if (p == NULL || p->sec != sec)
2531 bfd_size_type amt = sizeof *p;
2532 p = ((struct elf32_mb_dyn_relocs *)
2533 bfd_alloc (htab->elf.dynobj, amt));
2544 if (r_type == R_MICROBLAZE_64_PCREL)
2556 microblaze_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
2558 struct elf32_mb_link_hash_table *htab;
2560 htab = elf32_mb_hash_table (info);
2564 if (!htab->sgot && !create_got_section (dynobj, info))
2567 if (!_bfd_elf_create_dynamic_sections (dynobj, info))
2570 htab->splt = bfd_get_linker_section (dynobj, ".plt");
2571 htab->srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
2572 htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
2573 if (!bfd_link_pic (info))
2574 htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
2576 if (!htab->splt || !htab->srelplt || !htab->sdynbss
2577 || (!bfd_link_pic (info) && !htab->srelbss))
2583 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2586 microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
2587 struct elf_link_hash_entry *dir,
2588 struct elf_link_hash_entry *ind)
2590 struct elf32_mb_link_hash_entry *edir, *eind;
2592 edir = (struct elf32_mb_link_hash_entry *) dir;
2593 eind = (struct elf32_mb_link_hash_entry *) ind;
2595 if (eind->dyn_relocs != NULL)
2597 if (edir->dyn_relocs != NULL)
2599 struct elf32_mb_dyn_relocs **pp;
2600 struct elf32_mb_dyn_relocs *p;
2602 if (ind->root.type == bfd_link_hash_indirect)
2605 /* Add reloc counts against the weak sym to the strong sym
2606 list. Merge any entries against the same section. */
2607 for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
2609 struct elf32_mb_dyn_relocs *q;
2611 for (q = edir->dyn_relocs; q != NULL; q = q->next)
2612 if (q->sec == p->sec)
2614 q->pc_count += p->pc_count;
2615 q->count += p->count;
2622 *pp = edir->dyn_relocs;
2625 edir->dyn_relocs = eind->dyn_relocs;
2626 eind->dyn_relocs = NULL;
2629 edir->tls_mask |= eind->tls_mask;
2631 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
2635 microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2636 struct elf_link_hash_entry *h)
2638 struct elf32_mb_link_hash_table *htab;
2639 struct elf32_mb_link_hash_entry * eh;
2640 struct elf32_mb_dyn_relocs *p;
2641 asection *sdynbss, *s;
2642 unsigned int power_of_two;
2645 htab = elf32_mb_hash_table (info);
2649 /* If this is a function, put it in the procedure linkage table. We
2650 will fill in the contents of the procedure linkage table later,
2651 when we know the address of the .got section. */
2652 if (h->type == STT_FUNC
2655 if (h->plt.refcount <= 0
2656 || SYMBOL_CALLS_LOCAL (info, h)
2657 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
2658 && h->root.type == bfd_link_hash_undefweak))
2660 /* This case can occur if we saw a PLT reloc in an input
2661 file, but the symbol was never referred to by a dynamic
2662 object, or if all references were garbage collected. In
2663 such a case, we don't actually need to build a procedure
2664 linkage table, and we can just do a PC32 reloc instead. */
2665 h->plt.offset = (bfd_vma) -1;
2672 /* It's possible that we incorrectly decided a .plt reloc was
2673 needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
2674 check_relocs. We can't decide accurately between function and
2675 non-function syms in check-relocs; Objects loaded later in
2676 the link may change h->type. So fix it now. */
2677 h->plt.offset = (bfd_vma) -1;
2679 /* If this is a weak symbol, and there is a real definition, the
2680 processor independent code will have arranged for us to see the
2681 real definition first, and we can just use the same value. */
2682 if (h->u.weakdef != NULL)
2684 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2685 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2686 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2687 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2691 /* This is a reference to a symbol defined by a dynamic object which
2692 is not a function. */
2694 /* If we are creating a shared library, we must presume that the
2695 only references to the symbol are via the global offset table.
2696 For such cases we need not do anything here; the relocations will
2697 be handled correctly by relocate_section. */
2698 if (bfd_link_pic (info))
2701 /* If there are no references to this symbol that do not use the
2702 GOT, we don't need to generate a copy reloc. */
2703 if (!h->non_got_ref)
2706 /* If -z nocopyreloc was given, we won't generate them either. */
2707 if (info->nocopyreloc)
2713 eh = (struct elf32_mb_link_hash_entry *) h;
2714 for (p = eh->dyn_relocs; p != NULL; p = p->next)
2716 s = p->sec->output_section;
2717 if (s != NULL && (s->flags & SEC_READONLY) != 0)
2721 /* If we didn't find any dynamic relocs in read-only sections, then
2722 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
2729 /* We must allocate the symbol in our .dynbss section, which will
2730 become part of the .bss section of the executable. There will be
2731 an entry for this symbol in the .dynsym section. The dynamic
2732 object will contain position independent code, so all references
2733 from the dynamic object to this symbol will go through the global
2734 offset table. The dynamic linker will use the .dynsym entry to
2735 determine the address it must put in the global offset table, so
2736 both the dynamic object and the regular object will refer to the
2737 same memory location for the variable. */
2739 /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
2740 to copy the initial value out of the dynamic object and into the
2741 runtime process image. */
2742 dynobj = elf_hash_table (info)->dynobj;
2743 BFD_ASSERT (dynobj != NULL);
2744 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2746 htab->srelbss->size += sizeof (Elf32_External_Rela);
2750 /* We need to figure out the alignment required for this symbol. I
2751 have no idea how ELF linkers handle this. */
2752 power_of_two = bfd_log2 (h->size);
2753 if (power_of_two > 3)
2756 sdynbss = htab->sdynbss;
2757 /* Apply the required alignment. */
2758 sdynbss->size = BFD_ALIGN (sdynbss->size, (bfd_size_type) (1 << power_of_two));
2759 if (power_of_two > bfd_get_section_alignment (dynobj, sdynbss))
2761 if (! bfd_set_section_alignment (dynobj, sdynbss, power_of_two))
2765 /* Define the symbol as being at this point in the section. */
2766 h->root.u.def.section = sdynbss;
2767 h->root.u.def.value = sdynbss->size;
2769 /* Increment the section size to make room for the symbol. */
2770 sdynbss->size += h->size;
2774 /* Allocate space in .plt, .got and associated reloc sections for
2778 allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
2780 struct bfd_link_info *info;
2781 struct elf32_mb_link_hash_table *htab;
2782 struct elf32_mb_link_hash_entry *eh;
2783 struct elf32_mb_dyn_relocs *p;
2785 if (h->root.type == bfd_link_hash_indirect)
2788 info = (struct bfd_link_info *) dat;
2789 htab = elf32_mb_hash_table (info);
2793 if (htab->elf.dynamic_sections_created
2794 && h->plt.refcount > 0)
2796 /* Make sure this symbol is output as a dynamic symbol.
2797 Undefined weak syms won't yet be marked as dynamic. */
2798 if (h->dynindx == -1
2799 && !h->forced_local)
2801 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2805 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
2807 asection *s = htab->splt;
2809 /* The first entry in .plt is reserved. */
2811 s->size = PLT_ENTRY_SIZE;
2813 h->plt.offset = s->size;
2815 /* If this symbol is not defined in a regular file, and we are
2816 not generating a shared library, then set the symbol to this
2817 location in the .plt. This is required to make function
2818 pointers compare as equal between the normal executable and
2819 the shared library. */
2820 if (! bfd_link_pic (info)
2823 h->root.u.def.section = s;
2824 h->root.u.def.value = h->plt.offset;
2827 /* Make room for this entry. */
2828 s->size += PLT_ENTRY_SIZE;
2830 /* We also need to make an entry in the .got.plt section, which
2831 will be placed in the .got section by the linker script. */
2832 htab->sgotplt->size += 4;
2834 /* We also need to make an entry in the .rel.plt section. */
2835 htab->srelplt->size += sizeof (Elf32_External_Rela);
2839 h->plt.offset = (bfd_vma) -1;
2845 h->plt.offset = (bfd_vma) -1;
2849 eh = (struct elf32_mb_link_hash_entry *) h;
2850 if (h->got.refcount > 0)
2855 /* Make sure this symbol is output as a dynamic symbol.
2856 Undefined weak syms won't yet be marked as dynamic. */
2857 if (h->dynindx == -1
2858 && !h->forced_local)
2860 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2865 if ((eh->tls_mask & TLS_TLS) != 0)
2867 /* Handle TLS Symbol */
2868 if ((eh->tls_mask & TLS_LD) != 0)
2870 if (!eh->elf.def_dynamic)
2871 /* We'll just use htab->tlsld_got.offset. This should
2872 always be the case. It's a little odd if we have
2873 a local dynamic reloc against a non-local symbol. */
2874 htab->tlsld_got.refcount += 1;
2878 if ((eh->tls_mask & TLS_GD) != 0)
2883 /* Regular (non-TLS) symbol */
2888 h->got.offset = (bfd_vma) -1;
2893 h->got.offset = s->size;
2895 htab->srelgot->size += need * (sizeof (Elf32_External_Rela) / 4);
2899 h->got.offset = (bfd_vma) -1;
2901 if (eh->dyn_relocs == NULL)
2904 /* In the shared -Bsymbolic case, discard space allocated for
2905 dynamic pc-relative relocs against symbols which turn out to be
2906 defined in regular objects. For the normal shared case, discard
2907 space for pc-relative relocs that have become local due to symbol
2908 visibility changes. */
2910 if (bfd_link_pic (info))
2916 struct elf32_mb_dyn_relocs **pp;
2918 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
2920 p->count -= p->pc_count;
2931 /* For the non-shared case, discard space for relocs against
2932 symbols which turn out to need copy relocs or are not
2938 || (htab->elf.dynamic_sections_created
2939 && (h->root.type == bfd_link_hash_undefweak
2940 || h->root.type == bfd_link_hash_undefined))))
2942 /* Make sure this symbol is output as a dynamic symbol.
2943 Undefined weak syms won't yet be marked as dynamic. */
2944 if (h->dynindx == -1
2945 && !h->forced_local)
2947 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2951 /* If that succeeded, we know we'll be keeping all the
2953 if (h->dynindx != -1)
2957 eh->dyn_relocs = NULL;
2962 /* Finally, allocate space. */
2963 for (p = eh->dyn_relocs; p != NULL; p = p->next)
2965 asection *sreloc = elf_section_data (p->sec)->sreloc;
2966 sreloc->size += p->count * sizeof (Elf32_External_Rela);
2972 /* Set the sizes of the dynamic sections. */
2975 microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2976 struct bfd_link_info *info)
2978 struct elf32_mb_link_hash_table *htab;
2983 htab = elf32_mb_hash_table (info);
2987 dynobj = htab->elf.dynobj;
2988 BFD_ASSERT (dynobj != NULL);
2990 /* Set up .got offsets for local syms, and space for local dynamic
2992 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
2994 bfd_signed_vma *local_got;
2995 bfd_signed_vma *end_local_got;
2996 bfd_size_type locsymcount;
2997 Elf_Internal_Shdr *symtab_hdr;
2998 unsigned char *lgot_masks;
3001 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
3004 for (s = ibfd->sections; s != NULL; s = s->next)
3006 struct elf32_mb_dyn_relocs *p;
3008 for (p = ((struct elf32_mb_dyn_relocs *)
3009 elf_section_data (s)->local_dynrel);
3013 if (!bfd_is_abs_section (p->sec)
3014 && bfd_is_abs_section (p->sec->output_section))
3016 /* Input section has been discarded, either because
3017 it is a copy of a linkonce section or due to
3018 linker script /DISCARD/, so we'll be discarding
3021 else if (p->count != 0)
3023 srel = elf_section_data (p->sec)->sreloc;
3024 srel->size += p->count * sizeof (Elf32_External_Rela);
3025 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
3026 info->flags |= DF_TEXTREL;
3031 local_got = elf_local_got_refcounts (ibfd);
3035 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
3036 locsymcount = symtab_hdr->sh_info;
3037 end_local_got = local_got + locsymcount;
3038 lgot_masks = (unsigned char *) end_local_got;
3040 srel = htab->srelgot;
3042 for (; local_got < end_local_got; ++local_got, ++lgot_masks)
3046 unsigned int need = 0;
3047 if ((*lgot_masks & TLS_TLS) != 0)
3049 if ((*lgot_masks & TLS_GD) != 0)
3051 if ((*lgot_masks & TLS_LD) != 0)
3052 htab->tlsld_got.refcount += 1;
3059 *local_got = (bfd_vma) -1;
3063 *local_got = s->size;
3065 if (bfd_link_pic (info))
3066 srel->size += need * (sizeof (Elf32_External_Rela) / 4);
3070 *local_got = (bfd_vma) -1;
3074 /* Allocate global sym .plt and .got entries, and space for global
3075 sym dynamic relocs. */
3076 elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
3078 if (htab->tlsld_got.refcount > 0)
3080 htab->tlsld_got.offset = htab->sgot->size;
3081 htab->sgot->size += 8;
3082 if (bfd_link_pic (info))
3083 htab->srelgot->size += sizeof (Elf32_External_Rela);
3086 htab->tlsld_got.offset = (bfd_vma) -1;
3088 if (elf_hash_table (info)->dynamic_sections_created)
3090 /* Make space for the trailing nop in .plt. */
3091 if (htab->splt->size > 0)
3092 htab->splt->size += 4;
3095 /* The check_relocs and adjust_dynamic_symbol entry points have
3096 determined the sizes of the various dynamic sections. Allocate
3098 for (s = dynobj->sections; s != NULL; s = s->next)
3101 bfd_boolean strip = FALSE;
3103 if ((s->flags & SEC_LINKER_CREATED) == 0)
3106 /* It's OK to base decisions on the section name, because none
3107 of the dynobj section names depend upon the input files. */
3108 name = bfd_get_section_name (dynobj, s);
3110 if (strncmp (name, ".rela", 5) == 0)
3114 /* If we don't need this section, strip it from the
3115 output file. This is to handle .rela.bss and
3116 .rela.plt. We must create it in
3117 create_dynamic_sections, because it must be created
3118 before the linker maps input sections to output
3119 sections. The linker does that before
3120 adjust_dynamic_symbol is called, and it is that
3121 function which decides whether anything needs to go
3122 into these sections. */
3127 /* We use the reloc_count field as a counter if we need
3128 to copy relocs into the output file. */
3132 else if (s != htab->splt && s != htab->sgot && s != htab->sgotplt)
3134 /* It's not one of our sections, so don't allocate space. */
3140 s->flags |= SEC_EXCLUDE;
3144 /* Allocate memory for the section contents. */
3145 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
3146 Unused entries should be reclaimed before the section's contents
3147 are written out, but at the moment this does not happen. Thus in
3148 order to prevent writing out garbage, we initialise the section's
3149 contents to zero. */
3150 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
3151 if (s->contents == NULL && s->size != 0)
3155 if (elf_hash_table (info)->dynamic_sections_created)
3157 /* Add some entries to the .dynamic section. We fill in the
3158 values later, in microblaze_elf_finish_dynamic_sections, but we
3159 must add the entries now so that we get the correct size for
3160 the .dynamic section. The DT_DEBUG entry is filled in by the
3161 dynamic linker and used by the debugger. */
3162 #define add_dynamic_entry(TAG, VAL) \
3163 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3165 if (bfd_link_executable (info))
3167 if (!add_dynamic_entry (DT_DEBUG, 0))
3171 if (!add_dynamic_entry (DT_RELA, 0)
3172 || !add_dynamic_entry (DT_RELASZ, 0)
3173 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
3176 if (htab->splt->size != 0)
3178 if (!add_dynamic_entry (DT_PLTGOT, 0)
3179 || !add_dynamic_entry (DT_PLTRELSZ, 0)
3180 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
3181 || !add_dynamic_entry (DT_JMPREL, 0)
3182 || !add_dynamic_entry (DT_BIND_NOW, 1))
3186 if (info->flags & DF_TEXTREL)
3188 if (!add_dynamic_entry (DT_TEXTREL, 0))
3192 #undef add_dynamic_entry
3196 /* Finish up dynamic symbol handling. We set the contents of various
3197 dynamic sections here. */
3200 microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
3201 struct bfd_link_info *info,
3202 struct elf_link_hash_entry *h,
3203 Elf_Internal_Sym *sym)
3205 struct elf32_mb_link_hash_table *htab;
3206 struct elf32_mb_link_hash_entry *eh = elf32_mb_hash_entry(h);
3208 htab = elf32_mb_hash_table (info);
3212 if (h->plt.offset != (bfd_vma) -1)
3217 Elf_Internal_Rela rela;
3223 /* This symbol has an entry in the procedure linkage table. Set
3225 BFD_ASSERT (h->dynindx != -1);
3228 srela = htab->srelplt;
3229 sgotplt = htab->sgotplt;
3230 BFD_ASSERT (splt != NULL && srela != NULL && sgotplt != NULL);
3232 plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* first entry reserved. */
3233 got_offset = (plt_index + 3) * 4; /* 3 reserved ??? */
3234 got_addr = got_offset;
3236 /* For non-PIC objects we need absolute address of the GOT entry. */
3237 if (!bfd_link_pic (info))
3238 got_addr += htab->sgotplt->output_section->vma + sgotplt->output_offset;
3240 /* Fill in the entry in the procedure linkage table. */
3241 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_0 + ((got_addr >> 16) & 0xffff),
3242 splt->contents + h->plt.offset);
3243 if (bfd_link_pic (info))
3244 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1 + (got_addr & 0xffff),
3245 splt->contents + h->plt.offset + 4);
3247 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1_NOPIC + (got_addr & 0xffff),
3248 splt->contents + h->plt.offset + 4);
3249 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_2,
3250 splt->contents + h->plt.offset + 8);
3251 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_3,
3252 splt->contents + h->plt.offset + 12);
3254 /* Any additions to the .got section??? */
3255 /* bfd_put_32 (output_bfd,
3256 splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
3257 sgotplt->contents + got_offset); */
3259 /* Fill in the entry in the .rela.plt section. */
3260 rela.r_offset = (sgotplt->output_section->vma
3261 + sgotplt->output_offset
3263 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_JUMP_SLOT);
3265 loc = srela->contents;
3266 loc += plt_index * sizeof (Elf32_External_Rela);
3267 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
3269 if (!h->def_regular)
3271 /* Mark the symbol as undefined, rather than as defined in
3272 the .plt section. Zero the value. */
3273 sym->st_shndx = SHN_UNDEF;
3278 /* h->got.refcount to be checked ? */
3279 if (h->got.offset != (bfd_vma) -1 &&
3280 ! ((h->got.offset & 1) ||
3281 IS_TLS_LD(eh->tls_mask) || IS_TLS_GD(eh->tls_mask)))
3287 /* This symbol has an entry in the global offset table. Set it
3291 srela = htab->srelgot;
3292 BFD_ASSERT (sgot != NULL && srela != NULL);
3294 offset = (sgot->output_section->vma + sgot->output_offset
3295 + (h->got.offset &~ (bfd_vma) 1));
3297 /* If this is a -Bsymbolic link, and the symbol is defined
3298 locally, we just want to emit a RELATIVE reloc. Likewise if
3299 the symbol was forced to be local because of a version file.
3300 The entry in the global offset table will already have been
3301 initialized in the relocate_section function. */
3302 if (bfd_link_pic (info)
3303 && ((info->symbolic && h->def_regular)
3304 || h->dynindx == -1))
3306 asection *sec = h->root.u.def.section;
3307 microblaze_elf_output_dynamic_relocation (output_bfd,
3308 srela, srela->reloc_count++,
3310 R_MICROBLAZE_REL, offset,
3312 + sec->output_section->vma
3313 + sec->output_offset);
3317 microblaze_elf_output_dynamic_relocation (output_bfd,
3318 srela, srela->reloc_count++,
3320 R_MICROBLAZE_GLOB_DAT,
3324 bfd_put_32 (output_bfd, (bfd_vma) 0,
3325 sgot->contents + (h->got.offset &~ (bfd_vma) 1));
3331 Elf_Internal_Rela rela;
3334 /* This symbols needs a copy reloc. Set it up. */
3336 BFD_ASSERT (h->dynindx != -1);
3338 s = bfd_get_linker_section (htab->elf.dynobj, ".rela.bss");
3339 BFD_ASSERT (s != NULL);
3341 rela.r_offset = (h->root.u.def.value
3342 + h->root.u.def.section->output_section->vma
3343 + h->root.u.def.section->output_offset);
3344 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_COPY);
3346 loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
3347 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
3350 /* Mark some specially defined symbols as absolute. */
3351 if (h == htab->elf.hdynamic
3352 || h == htab->elf.hgot
3353 || h == htab->elf.hplt)
3354 sym->st_shndx = SHN_ABS;
3360 /* Finish up the dynamic sections. */
3363 microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
3364 struct bfd_link_info *info)
3367 asection *sdyn, *sgot;
3368 struct elf32_mb_link_hash_table *htab;
3370 htab = elf32_mb_hash_table (info);
3374 dynobj = htab->elf.dynobj;
3376 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
3378 if (htab->elf.dynamic_sections_created)
3381 Elf32_External_Dyn *dyncon, *dynconend;
3383 splt = bfd_get_linker_section (dynobj, ".plt");
3384 BFD_ASSERT (splt != NULL && sdyn != NULL);
3386 dyncon = (Elf32_External_Dyn *) sdyn->contents;
3387 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
3388 for (; dyncon < dynconend; dyncon++)
3390 Elf_Internal_Dyn dyn;
3394 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
3398 case DT_PLTGOT: name = ".got.plt"; size = FALSE; break;
3399 case DT_PLTRELSZ: name = ".rela.plt"; size = TRUE; break;
3400 case DT_JMPREL: name = ".rela.plt"; size = FALSE; break;
3401 case DT_RELA: name = ".rela.dyn"; size = FALSE; break;
3402 case DT_RELASZ: name = ".rela.dyn"; size = TRUE; break;
3403 default: name = NULL; size = FALSE; break;
3410 s = bfd_get_linker_section (dynobj, name);
3416 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
3418 dyn.d_un.d_val = s->size;
3420 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
3424 /* Clear the first entry in the procedure linkage table,
3425 and put a nop in the last four bytes. */
3428 memset (splt->contents, 0, PLT_ENTRY_SIZE);
3429 bfd_put_32 (output_bfd, (bfd_vma) 0x80000000 /* nop. */,
3430 splt->contents + splt->size - 4);
3433 elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
3436 /* Set the first entry in the global offset table to the address of
3437 the dynamic section. */
3438 sgot = bfd_get_linker_section (dynobj, ".got.plt");
3439 if (sgot && sgot->size > 0)
3442 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
3444 bfd_put_32 (output_bfd,
3445 sdyn->output_section->vma + sdyn->output_offset,
3447 elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
3450 if (htab->sgot && htab->sgot->size > 0)
3451 elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 4;
3456 /* Hook called by the linker routine which adds symbols from an object
3457 file. We use it to put .comm items in .sbss, and not .bss. */
3460 microblaze_elf_add_symbol_hook (bfd *abfd,
3461 struct bfd_link_info *info,
3462 Elf_Internal_Sym *sym,
3463 const char **namep ATTRIBUTE_UNUSED,
3464 flagword *flagsp ATTRIBUTE_UNUSED,
3468 if (sym->st_shndx == SHN_COMMON
3469 && !bfd_link_relocatable (info)
3470 && sym->st_size <= elf_gp_size (abfd))
3472 /* Common symbols less than or equal to -G nn bytes are automatically
3474 *secp = bfd_make_section_old_way (abfd, ".sbss");
3476 || ! bfd_set_section_flags (abfd, *secp, SEC_IS_COMMON))
3479 *valp = sym->st_size;
3485 #define TARGET_LITTLE_SYM microblaze_elf32_le_vec
3486 #define TARGET_LITTLE_NAME "elf32-microblazeel"
3488 #define TARGET_BIG_SYM microblaze_elf32_vec
3489 #define TARGET_BIG_NAME "elf32-microblaze"
3491 #define ELF_ARCH bfd_arch_microblaze
3492 #define ELF_TARGET_ID MICROBLAZE_ELF_DATA
3493 #define ELF_MACHINE_CODE EM_MICROBLAZE
3494 #define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
3495 #define ELF_MAXPAGESIZE 0x1000
3496 #define elf_info_to_howto microblaze_elf_info_to_howto
3497 #define elf_info_to_howto_rel NULL
3499 #define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
3500 #define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name
3501 #define elf_backend_relocate_section microblaze_elf_relocate_section
3502 #define bfd_elf32_bfd_relax_section microblaze_elf_relax_section
3503 #define bfd_elf32_bfd_merge_private_bfd_data microblaze_elf_merge_private_bfd_data
3504 #define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
3506 #define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
3507 #define elf_backend_gc_sweep_hook microblaze_elf_gc_sweep_hook
3508 #define elf_backend_check_relocs microblaze_elf_check_relocs
3509 #define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
3510 #define bfd_elf32_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
3511 #define elf_backend_can_gc_sections 1
3512 #define elf_backend_can_refcount 1
3513 #define elf_backend_want_got_plt 1
3514 #define elf_backend_plt_readonly 1
3515 #define elf_backend_got_header_size 12
3516 #define elf_backend_rela_normal 1
3518 #define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
3519 #define elf_backend_create_dynamic_sections microblaze_elf_create_dynamic_sections
3520 #define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
3521 #define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
3522 #define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
3523 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
3525 #include "elf32-target.h"