1 /* Xilinx MicroBlaze-specific support for 32-bit ELF
3 Copyright (C) 2009-2022 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. */
28 #include "elf/microblaze.h"
31 #define USE_RELA /* Only USE_REL is actually significant, but this is
32 here are a reminder... */
33 #define INST_WORD_SIZE 4
35 static int ro_small_data_pointer
= 0;
36 static int rw_small_data_pointer
= 0;
38 static reloc_howto_type
* microblaze_elf_howto_table
[(int) R_MICROBLAZE_max
];
40 static reloc_howto_type microblaze_elf_howto_raw
[] =
42 /* This reloc does nothing. */
43 HOWTO (R_MICROBLAZE_NONE
, /* Type. */
47 false, /* PC_relative. */
49 complain_overflow_dont
, /* Complain on overflow. */
50 NULL
, /* Special Function. */
51 "R_MICROBLAZE_NONE", /* Name. */
52 false, /* Partial Inplace. */
55 false), /* PC relative offset? */
57 /* A standard 32 bit relocation. */
58 HOWTO (R_MICROBLAZE_32
, /* Type. */
62 false, /* PC_relative. */
64 complain_overflow_bitfield
, /* Complain on overflow. */
65 bfd_elf_generic_reloc
,/* Special Function. */
66 "R_MICROBLAZE_32", /* Name. */
67 false, /* Partial Inplace. */
69 0xffffffff, /* Dest Mask. */
70 false), /* PC relative offset? */
72 /* A standard PCREL 32 bit relocation. */
73 HOWTO (R_MICROBLAZE_32_PCREL
,/* Type. */
77 true, /* PC_relative. */
79 complain_overflow_bitfield
, /* Complain on overflow. */
80 bfd_elf_generic_reloc
,/* Special Function. */
81 "R_MICROBLAZE_32_PCREL", /* Name. */
82 true, /* Partial Inplace. */
84 0xffffffff, /* Dest Mask. */
85 true), /* PC relative offset? */
87 /* A 64 bit PCREL relocation. Table-entry not really used. */
88 HOWTO (R_MICROBLAZE_64_PCREL
,/* Type. */
92 true, /* PC_relative. */
94 complain_overflow_dont
, /* Complain on overflow. */
95 bfd_elf_generic_reloc
,/* Special Function. */
96 "R_MICROBLAZE_64_PCREL", /* Name. */
97 false, /* Partial Inplace. */
99 0x0000ffff, /* Dest Mask. */
100 true), /* PC relative offset? */
102 /* The low half of a PCREL 32 bit relocation. */
103 HOWTO (R_MICROBLAZE_32_PCREL_LO
, /* Type. */
107 true, /* PC_relative. */
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? */
117 /* A 64 bit relocation. Table entry not really used. */
118 HOWTO (R_MICROBLAZE_64
, /* Type. */
122 false, /* PC_relative. */
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? */
132 /* The low half of a 32 bit relocation. */
133 HOWTO (R_MICROBLAZE_32_LO
, /* Type. */
137 false, /* PC_relative. */
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? */
147 /* Read-only small data section relocation. */
148 HOWTO (R_MICROBLAZE_SRO32
, /* Type. */
152 false, /* PC_relative. */
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? */
162 /* Read-write small data area relocation. */
163 HOWTO (R_MICROBLAZE_SRW32
, /* Type. */
167 false, /* PC_relative. */
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? */
177 /* This reloc does nothing. Used for relaxation. */
178 HOWTO (R_MICROBLAZE_64_NONE
, /* Type. */
182 true, /* PC_relative. */
184 complain_overflow_dont
, /* Complain on overflow. */
185 NULL
, /* Special Function. */
186 "R_MICROBLAZE_64_NONE",/* Name. */
187 false, /* Partial Inplace. */
188 0, /* Source Mask. */
190 false), /* PC relative offset? */
192 /* Symbol Op Symbol relocation. */
193 HOWTO (R_MICROBLAZE_32_SYM_OP_SYM
, /* Type. */
197 false, /* PC_relative. */
199 complain_overflow_bitfield
, /* Complain on overflow. */
200 bfd_elf_generic_reloc
,/* Special Function. */
201 "R_MICROBLAZE_32_SYM_OP_SYM", /* Name. */
202 false, /* Partial Inplace. */
203 0, /* Source Mask. */
204 0xffffffff, /* Dest Mask. */
205 false), /* PC relative offset? */
207 /* GNU extension to record C++ vtable hierarchy. */
208 HOWTO (R_MICROBLAZE_GNU_VTINHERIT
, /* Type. */
212 false, /* PC_relative. */
214 complain_overflow_dont
,/* Complain on overflow. */
215 NULL
, /* Special Function. */
216 "R_MICROBLAZE_GNU_VTINHERIT", /* Name. */
217 false, /* Partial Inplace. */
218 0, /* Source Mask. */
220 false), /* PC relative offset? */
222 /* GNU extension to record C++ vtable member usage. */
223 HOWTO (R_MICROBLAZE_GNU_VTENTRY
, /* Type. */
227 false, /* PC_relative. */
229 complain_overflow_dont
,/* Complain on overflow. */
230 _bfd_elf_rel_vtable_reloc_fn
, /* Special Function. */
231 "R_MICROBLAZE_GNU_VTENTRY", /* Name. */
232 false, /* Partial Inplace. */
233 0, /* Source Mask. */
235 false), /* PC relative offset? */
237 /* A 64 bit GOTPC relocation. Table-entry not really used. */
238 HOWTO (R_MICROBLAZE_GOTPC_64
, /* Type. */
242 true, /* PC_relative. */
244 complain_overflow_dont
, /* Complain on overflow. */
245 bfd_elf_generic_reloc
, /* Special Function. */
246 "R_MICROBLAZE_GOTPC_64", /* Name. */
247 false, /* Partial Inplace. */
248 0, /* Source Mask. */
249 0x0000ffff, /* Dest Mask. */
250 true), /* PC relative offset? */
252 /* A 64 bit TEXTPCREL relocation. Table-entry not really used. */
253 HOWTO (R_MICROBLAZE_TEXTPCREL_64
, /* Type. */
257 true, /* PC_relative. */
259 complain_overflow_dont
, /* Complain on overflow. */
260 bfd_elf_generic_reloc
, /* Special Function. */
261 "R_MICROBLAZE_TEXTPCREL_64", /* Name. */
262 false, /* Partial Inplace. */
263 0, /* Source Mask. */
264 0x0000ffff, /* Dest Mask. */
265 true), /* PC relative offset? */
267 /* A 64 bit GOT relocation. Table-entry not really used. */
268 HOWTO (R_MICROBLAZE_GOT_64
, /* Type. */
272 false, /* PC_relative. */
274 complain_overflow_dont
, /* Complain on overflow. */
275 bfd_elf_generic_reloc
,/* Special Function. */
276 "R_MICROBLAZE_GOT_64",/* Name. */
277 false, /* Partial Inplace. */
278 0, /* Source Mask. */
279 0x0000ffff, /* Dest Mask. */
280 false), /* PC relative offset? */
282 /* A 64 bit TEXTREL relocation. Table-entry not really used. */
283 HOWTO (R_MICROBLAZE_TEXTREL_64
, /* Type. */
287 false, /* PC_relative. */
289 complain_overflow_dont
, /* Complain on overflow. */
290 bfd_elf_generic_reloc
,/* Special Function. */
291 "R_MICROBLAZE_TEXTREL_64",/* Name. */
292 false, /* Partial Inplace. */
293 0, /* Source Mask. */
294 0x0000ffff, /* Dest Mask. */
295 false), /* PC relative offset? */
297 /* A 64 bit PLT relocation. Table-entry not really used. */
298 HOWTO (R_MICROBLAZE_PLT_64
, /* Type. */
302 true, /* PC_relative. */
304 complain_overflow_dont
, /* Complain on overflow. */
305 bfd_elf_generic_reloc
,/* Special Function. */
306 "R_MICROBLAZE_PLT_64",/* Name. */
307 false, /* Partial Inplace. */
308 0, /* Source Mask. */
309 0x0000ffff, /* Dest Mask. */
310 true), /* PC relative offset? */
312 /* Table-entry not really used. */
313 HOWTO (R_MICROBLAZE_REL
, /* Type. */
317 true, /* PC_relative. */
319 complain_overflow_dont
, /* Complain on overflow. */
320 bfd_elf_generic_reloc
,/* Special Function. */
321 "R_MICROBLAZE_REL", /* Name. */
322 false, /* Partial Inplace. */
323 0, /* Source Mask. */
324 0x0000ffff, /* Dest Mask. */
325 true), /* PC relative offset? */
327 /* Table-entry not really used. */
328 HOWTO (R_MICROBLAZE_JUMP_SLOT
,/* Type. */
332 true, /* PC_relative. */
334 complain_overflow_dont
, /* Complain on overflow. */
335 bfd_elf_generic_reloc
,/* Special Function. */
336 "R_MICROBLAZE_JUMP_SLOT", /* Name. */
337 false, /* Partial Inplace. */
338 0, /* Source Mask. */
339 0x0000ffff, /* Dest Mask. */
340 true), /* PC relative offset? */
342 /* Table-entry not really used. */
343 HOWTO (R_MICROBLAZE_GLOB_DAT
,/* Type. */
347 true, /* PC_relative. */
349 complain_overflow_dont
, /* Complain on overflow. */
350 bfd_elf_generic_reloc
,/* Special Function. */
351 "R_MICROBLAZE_GLOB_DAT", /* Name. */
352 false, /* Partial Inplace. */
353 0, /* Source Mask. */
354 0x0000ffff, /* Dest Mask. */
355 true), /* PC relative offset? */
357 /* A 64 bit GOT relative relocation. Table-entry not really used. */
358 HOWTO (R_MICROBLAZE_GOTOFF_64
, /* Type. */
362 false, /* PC_relative. */
364 complain_overflow_dont
, /* Complain on overflow. */
365 bfd_elf_generic_reloc
,/* Special Function. */
366 "R_MICROBLAZE_GOTOFF_64", /* Name. */
367 false, /* Partial Inplace. */
368 0, /* Source Mask. */
369 0x0000ffff, /* Dest Mask. */
370 false), /* PC relative offset? */
372 /* A 32 bit GOT relative relocation. Table-entry not really used. */
373 HOWTO (R_MICROBLAZE_GOTOFF_32
, /* Type. */
377 false, /* PC_relative. */
379 complain_overflow_dont
, /* Complain on overflow. */
380 bfd_elf_generic_reloc
, /* Special Function. */
381 "R_MICROBLAZE_GOTOFF_32", /* Name. */
382 false, /* Partial Inplace. */
383 0, /* Source Mask. */
384 0x0000ffff, /* Dest Mask. */
385 false), /* PC relative offset? */
387 /* COPY relocation. Table-entry not really used. */
388 HOWTO (R_MICROBLAZE_COPY
, /* Type. */
392 false, /* PC_relative. */
394 complain_overflow_dont
, /* Complain on overflow. */
395 bfd_elf_generic_reloc
,/* Special Function. */
396 "R_MICROBLAZE_COPY", /* Name. */
397 false, /* Partial Inplace. */
398 0, /* Source Mask. */
399 0x0000ffff, /* Dest Mask. */
400 false), /* PC relative offset? */
402 /* Marker relocs for TLS. */
403 HOWTO (R_MICROBLAZE_TLS
,
407 false, /* pc_relative */
409 complain_overflow_dont
, /* complain_on_overflow */
410 bfd_elf_generic_reloc
, /* special_function */
411 "R_MICROBLAZE_TLS", /* name */
412 false, /* partial_inplace */
414 0x0000ffff, /* dst_mask */
415 false), /* pcrel_offset */
417 HOWTO (R_MICROBLAZE_TLSGD
,
421 false, /* pc_relative */
423 complain_overflow_dont
, /* complain_on_overflow */
424 bfd_elf_generic_reloc
, /* special_function */
425 "R_MICROBLAZE_TLSGD", /* name */
426 false, /* partial_inplace */
428 0x0000ffff, /* dst_mask */
429 false), /* pcrel_offset */
431 HOWTO (R_MICROBLAZE_TLSLD
,
435 false, /* pc_relative */
437 complain_overflow_dont
, /* complain_on_overflow */
438 bfd_elf_generic_reloc
, /* special_function */
439 "R_MICROBLAZE_TLSLD", /* name */
440 false, /* partial_inplace */
442 0x0000ffff, /* dst_mask */
443 false), /* pcrel_offset */
445 /* Computes the load module index of the load module that contains the
446 definition of its TLS sym. */
447 HOWTO (R_MICROBLAZE_TLSDTPMOD32
,
451 false, /* pc_relative */
453 complain_overflow_dont
, /* complain_on_overflow */
454 bfd_elf_generic_reloc
, /* special_function */
455 "R_MICROBLAZE_TLSDTPMOD32", /* name */
456 false, /* partial_inplace */
458 0x0000ffff, /* dst_mask */
459 false), /* pcrel_offset */
461 /* Computes a dtv-relative displacement, the difference between the value
462 of sym+add and the base address of the thread-local storage block that
463 contains the definition of sym, minus 0x8000. Used for initializing GOT */
464 HOWTO (R_MICROBLAZE_TLSDTPREL32
,
468 false, /* pc_relative */
470 complain_overflow_dont
, /* complain_on_overflow */
471 bfd_elf_generic_reloc
, /* special_function */
472 "R_MICROBLAZE_TLSDTPREL32", /* name */
473 false, /* partial_inplace */
475 0x0000ffff, /* dst_mask */
476 false), /* pcrel_offset */
478 /* Computes a dtv-relative displacement, the difference between the value
479 of sym+add and the base address of the thread-local storage block that
480 contains the definition of sym, minus 0x8000. */
481 HOWTO (R_MICROBLAZE_TLSDTPREL64
,
485 false, /* pc_relative */
487 complain_overflow_dont
, /* complain_on_overflow */
488 bfd_elf_generic_reloc
, /* special_function */
489 "R_MICROBLAZE_TLSDTPREL64", /* name */
490 false, /* partial_inplace */
492 0x0000ffff, /* dst_mask */
493 false), /* pcrel_offset */
495 /* Computes a tp-relative displacement, the difference between the value of
496 sym+add and the value of the thread pointer (r13). */
497 HOWTO (R_MICROBLAZE_TLSGOTTPREL32
,
501 false, /* pc_relative */
503 complain_overflow_dont
, /* complain_on_overflow */
504 bfd_elf_generic_reloc
, /* special_function */
505 "R_MICROBLAZE_TLSGOTTPREL32", /* name */
506 false, /* partial_inplace */
508 0x0000ffff, /* dst_mask */
509 false), /* pcrel_offset */
511 /* Computes a tp-relative displacement, the difference between the value of
512 sym+add and the value of the thread pointer (r13). */
513 HOWTO (R_MICROBLAZE_TLSTPREL32
,
517 false, /* pc_relative */
519 complain_overflow_dont
, /* complain_on_overflow */
520 bfd_elf_generic_reloc
, /* special_function */
521 "R_MICROBLAZE_TLSTPREL32", /* name */
522 false, /* partial_inplace */
524 0x0000ffff, /* dst_mask */
525 false), /* pcrel_offset */
530 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
533 /* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */
536 microblaze_elf_howto_init (void)
540 for (i
= NUM_ELEM (microblaze_elf_howto_raw
); i
--;)
544 type
= microblaze_elf_howto_raw
[i
].type
;
546 BFD_ASSERT (type
< NUM_ELEM (microblaze_elf_howto_table
));
548 microblaze_elf_howto_table
[type
] = & microblaze_elf_howto_raw
[i
];
552 static reloc_howto_type
*
553 microblaze_elf_reloc_type_lookup (bfd
* abfd ATTRIBUTE_UNUSED
,
554 bfd_reloc_code_real_type code
)
556 enum elf_microblaze_reloc_type microblaze_reloc
= R_MICROBLAZE_NONE
;
561 microblaze_reloc
= R_MICROBLAZE_NONE
;
563 case BFD_RELOC_MICROBLAZE_64_NONE
:
564 microblaze_reloc
= R_MICROBLAZE_64_NONE
;
567 microblaze_reloc
= R_MICROBLAZE_32
;
569 /* RVA is treated the same as 32 */
571 microblaze_reloc
= R_MICROBLAZE_32
;
573 case BFD_RELOC_32_PCREL
:
574 microblaze_reloc
= R_MICROBLAZE_32_PCREL
;
576 case BFD_RELOC_64_PCREL
:
577 microblaze_reloc
= R_MICROBLAZE_64_PCREL
;
579 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
580 microblaze_reloc
= R_MICROBLAZE_32_PCREL_LO
;
583 microblaze_reloc
= R_MICROBLAZE_64
;
585 case BFD_RELOC_MICROBLAZE_32_LO
:
586 microblaze_reloc
= R_MICROBLAZE_32_LO
;
588 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
589 microblaze_reloc
= R_MICROBLAZE_SRO32
;
591 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
592 microblaze_reloc
= R_MICROBLAZE_SRW32
;
594 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
595 microblaze_reloc
= R_MICROBLAZE_32_SYM_OP_SYM
;
597 case BFD_RELOC_VTABLE_INHERIT
:
598 microblaze_reloc
= R_MICROBLAZE_GNU_VTINHERIT
;
600 case BFD_RELOC_VTABLE_ENTRY
:
601 microblaze_reloc
= R_MICROBLAZE_GNU_VTENTRY
;
603 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
604 microblaze_reloc
= R_MICROBLAZE_GOTPC_64
;
606 case BFD_RELOC_MICROBLAZE_64_GOT
:
607 microblaze_reloc
= R_MICROBLAZE_GOT_64
;
609 case BFD_RELOC_MICROBLAZE_64_TEXTPCREL
:
610 microblaze_reloc
= R_MICROBLAZE_TEXTPCREL_64
;
612 case BFD_RELOC_MICROBLAZE_64_TEXTREL
:
613 microblaze_reloc
= R_MICROBLAZE_TEXTREL_64
;
615 case BFD_RELOC_MICROBLAZE_64_PLT
:
616 microblaze_reloc
= R_MICROBLAZE_PLT_64
;
618 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
619 microblaze_reloc
= R_MICROBLAZE_GOTOFF_64
;
621 case BFD_RELOC_MICROBLAZE_32_GOTOFF
:
622 microblaze_reloc
= R_MICROBLAZE_GOTOFF_32
;
624 case BFD_RELOC_MICROBLAZE_64_TLSGD
:
625 microblaze_reloc
= R_MICROBLAZE_TLSGD
;
627 case BFD_RELOC_MICROBLAZE_64_TLSLD
:
628 microblaze_reloc
= R_MICROBLAZE_TLSLD
;
630 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL
:
631 microblaze_reloc
= R_MICROBLAZE_TLSDTPREL32
;
633 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL
:
634 microblaze_reloc
= R_MICROBLAZE_TLSDTPREL64
;
636 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
:
637 microblaze_reloc
= R_MICROBLAZE_TLSDTPMOD32
;
639 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
:
640 microblaze_reloc
= R_MICROBLAZE_TLSGOTTPREL32
;
642 case BFD_RELOC_MICROBLAZE_64_TLSTPREL
:
643 microblaze_reloc
= R_MICROBLAZE_TLSTPREL32
;
645 case BFD_RELOC_MICROBLAZE_COPY
:
646 microblaze_reloc
= R_MICROBLAZE_COPY
;
649 return (reloc_howto_type
*) NULL
;
652 if (!microblaze_elf_howto_table
[R_MICROBLAZE_32
])
653 /* Initialize howto table if needed. */
654 microblaze_elf_howto_init ();
656 return microblaze_elf_howto_table
[(int) microblaze_reloc
];
659 static reloc_howto_type
*
660 microblaze_elf_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
665 for (i
= 0; i
< NUM_ELEM (microblaze_elf_howto_raw
); i
++)
666 if (microblaze_elf_howto_raw
[i
].name
!= NULL
667 && strcasecmp (microblaze_elf_howto_raw
[i
].name
, r_name
) == 0)
668 return µblaze_elf_howto_raw
[i
];
673 /* Set the howto pointer for a RCE ELF reloc. */
676 microblaze_elf_info_to_howto (bfd
* abfd
,
678 Elf_Internal_Rela
* dst
)
682 if (!microblaze_elf_howto_table
[R_MICROBLAZE_32
])
683 /* Initialize howto table if needed. */
684 microblaze_elf_howto_init ();
686 r_type
= ELF32_R_TYPE (dst
->r_info
);
687 if (r_type
>= R_MICROBLAZE_max
)
689 /* xgettext:c-format */
690 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
692 bfd_set_error (bfd_error_bad_value
);
696 cache_ptr
->howto
= microblaze_elf_howto_table
[r_type
];
700 /* Relax table contains information about instructions which can
701 be removed by relaxation -- replacing a long address with a
705 /* Address where bytes may be deleted. */
708 /* Number of bytes to be deleted. */
712 struct _microblaze_elf_section_data
714 struct bfd_elf_section_data elf
;
715 /* Count of used relaxation table entries. */
717 /* Relaxation table. */
718 struct relax_table
*relax
;
721 #define microblaze_elf_section_data(sec) \
722 ((struct _microblaze_elf_section_data *) elf_section_data (sec))
725 microblaze_elf_new_section_hook (bfd
*abfd
, asection
*sec
)
727 if (!sec
->used_by_bfd
)
729 struct _microblaze_elf_section_data
*sdata
;
730 size_t amt
= sizeof (*sdata
);
732 sdata
= bfd_zalloc (abfd
, amt
);
735 sec
->used_by_bfd
= sdata
;
738 return _bfd_elf_new_section_hook (abfd
, sec
);
741 /* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
744 microblaze_elf_is_local_label_name (bfd
*abfd
, const char *name
)
746 if (name
[0] == 'L' && name
[1] == '.')
749 if (name
[0] == '$' && name
[1] == 'L')
752 /* With gcc, the labels go back to starting with '.', so we accept
753 the generic ELF local label syntax as well. */
754 return _bfd_elf_is_local_label_name (abfd
, name
);
757 /* ELF linker hash entry. */
759 struct elf32_mb_link_hash_entry
761 struct elf_link_hash_entry elf
;
763 /* TLS Reference Types for the symbol; Updated by check_relocs */
764 #define TLS_GD 1 /* GD reloc. */
765 #define TLS_LD 2 /* LD reloc. */
766 #define TLS_TPREL 4 /* TPREL reloc, => IE. */
767 #define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
768 #define TLS_TLS 16 /* Any TLS reloc. */
769 unsigned char tls_mask
;
773 #define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD))
774 #define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD))
775 #define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL))
776 #define IS_TLS_NONE(x) (x == 0)
778 #define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent))
780 /* ELF linker hash table. */
782 struct elf32_mb_link_hash_table
784 struct elf_link_hash_table elf
;
786 /* TLS Local Dynamic GOT Entry */
788 bfd_signed_vma refcount
;
793 /* Nonzero if this section has TLS related relocations. */
794 #define has_tls_reloc sec_flg0
796 /* Get the ELF linker hash table from a link_info structure. */
798 #define elf32_mb_hash_table(p) \
799 ((is_elf_hash_table ((p)->hash) \
800 && elf_hash_table_id (elf_hash_table (p)) == MICROBLAZE_ELF_DATA) \
801 ? (struct elf32_mb_link_hash_table *) (p)->hash : NULL)
803 /* Create an entry in a microblaze ELF linker hash table. */
805 static struct bfd_hash_entry
*
806 link_hash_newfunc (struct bfd_hash_entry
*entry
,
807 struct bfd_hash_table
*table
,
810 /* Allocate the structure if it has not already been allocated by a
814 entry
= bfd_hash_allocate (table
,
815 sizeof (struct elf32_mb_link_hash_entry
));
820 /* Call the allocation method of the superclass. */
821 entry
= _bfd_elf_link_hash_newfunc (entry
, table
, string
);
824 struct elf32_mb_link_hash_entry
*eh
;
826 eh
= (struct elf32_mb_link_hash_entry
*) entry
;
833 /* Create a mb ELF linker hash table. */
835 static struct bfd_link_hash_table
*
836 microblaze_elf_link_hash_table_create (bfd
*abfd
)
838 struct elf32_mb_link_hash_table
*ret
;
839 size_t amt
= sizeof (struct elf32_mb_link_hash_table
);
841 ret
= (struct elf32_mb_link_hash_table
*) bfd_zmalloc (amt
);
845 if (!_bfd_elf_link_hash_table_init (&ret
->elf
, abfd
, link_hash_newfunc
,
846 sizeof (struct elf32_mb_link_hash_entry
),
847 MICROBLAZE_ELF_DATA
))
853 return &ret
->elf
.root
;
856 /* Set the values of the small data pointers. */
859 microblaze_elf_final_sdp (struct bfd_link_info
*info
)
861 struct bfd_link_hash_entry
*h
;
863 h
= bfd_link_hash_lookup (info
->hash
, RO_SDA_ANCHOR_NAME
, false, false, true);
864 if (h
!= (struct bfd_link_hash_entry
*) NULL
865 && h
->type
== bfd_link_hash_defined
)
866 ro_small_data_pointer
= (h
->u
.def
.value
867 + h
->u
.def
.section
->output_section
->vma
868 + h
->u
.def
.section
->output_offset
);
870 h
= bfd_link_hash_lookup (info
->hash
, RW_SDA_ANCHOR_NAME
, false, false, true);
871 if (h
!= (struct bfd_link_hash_entry
*) NULL
872 && h
->type
== bfd_link_hash_defined
)
873 rw_small_data_pointer
= (h
->u
.def
.value
874 + h
->u
.def
.section
->output_section
->vma
875 + h
->u
.def
.section
->output_offset
);
879 dtprel_base (struct bfd_link_info
*info
)
881 /* If tls_sec is NULL, we should have signalled an error already. */
882 if (elf_hash_table (info
)->tls_sec
== NULL
)
884 return elf_hash_table (info
)->tls_sec
->vma
;
887 /* The size of the thread control block. */
890 /* Output a simple dynamic relocation into SRELOC. */
893 microblaze_elf_output_dynamic_relocation (bfd
*output_bfd
,
895 unsigned long reloc_index
,
902 Elf_Internal_Rela rel
;
904 rel
.r_info
= ELF32_R_INFO (indx
, r_type
);
905 rel
.r_offset
= offset
;
906 rel
.r_addend
= addend
;
908 bfd_elf32_swap_reloca_out (output_bfd
, &rel
,
909 (sreloc
->contents
+ reloc_index
* sizeof (Elf32_External_Rela
)));
912 /* This code is taken from elf32-m32r.c
913 There is some attempt to make this function usable for many architectures,
914 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
915 if only to serve as a learning tool.
917 The RELOCATE_SECTION function is called by the new ELF backend linker
918 to handle the relocations for a section.
920 The relocs are always passed as Rela structures; if the section
921 actually uses Rel structures, the r_addend field will always be
924 This function is responsible for adjust the section contents as
925 necessary, and (if using Rela relocs and generating a
926 relocatable output file) adjusting the reloc addend as
929 This function does not have to worry about setting the reloc
930 address or the reloc symbol index.
932 LOCAL_SYMS is a pointer to the swapped in local symbols.
934 LOCAL_SECTIONS is an array giving the section in the input file
935 corresponding to the st_shndx field of each local symbol.
937 The global hash table entry for the global symbols can be found
938 via elf_sym_hashes (input_bfd).
940 When generating relocatable output, this function must handle
941 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
942 going to be the section symbol corresponding to the output
943 section, which means that the addend must be adjusted
947 microblaze_elf_relocate_section (bfd
*output_bfd
,
948 struct bfd_link_info
*info
,
950 asection
*input_section
,
952 Elf_Internal_Rela
*relocs
,
953 Elf_Internal_Sym
*local_syms
,
954 asection
**local_sections
)
956 struct elf32_mb_link_hash_table
*htab
;
957 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
958 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
959 Elf_Internal_Rela
*rel
, *relend
;
960 int endian
= (bfd_little_endian (output_bfd
)) ? 0 : 2;
961 /* Assume success. */
964 bfd_vma
*local_got_offsets
;
965 unsigned int tls_type
;
967 if (!microblaze_elf_howto_table
[R_MICROBLAZE_max
-1])
968 microblaze_elf_howto_init ();
970 htab
= elf32_mb_hash_table (info
);
974 local_got_offsets
= elf_local_got_offsets (input_bfd
);
976 sreloc
= elf_section_data (input_section
)->sreloc
;
979 relend
= relocs
+ input_section
->reloc_count
;
980 for (; rel
< relend
; rel
++)
983 reloc_howto_type
*howto
;
984 unsigned long r_symndx
;
985 bfd_vma addend
= rel
->r_addend
;
986 bfd_vma offset
= rel
->r_offset
;
987 struct elf_link_hash_entry
*h
;
988 Elf_Internal_Sym
*sym
;
990 const char *sym_name
;
991 bfd_reloc_status_type r
= bfd_reloc_ok
;
992 const char *errmsg
= NULL
;
993 bool unresolved_reloc
= false;
996 r_type
= ELF32_R_TYPE (rel
->r_info
);
999 if (r_type
< 0 || r_type
>= (int) R_MICROBLAZE_max
)
1001 /* xgettext:c-format */
1002 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
1003 input_bfd
, (int) r_type
);
1004 bfd_set_error (bfd_error_bad_value
);
1009 howto
= microblaze_elf_howto_table
[r_type
];
1010 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1012 if (bfd_link_relocatable (info
))
1014 /* This is a relocatable link. We don't have to change
1015 anything, unless the reloc is against a section symbol,
1016 in which case we have to adjust according to where the
1017 section symbol winds up in the output section. */
1019 if (r_symndx
>= symtab_hdr
->sh_info
)
1020 /* External symbol. */
1024 sym
= local_syms
+ r_symndx
;
1025 sym_name
= "<local symbol>";
1026 /* STT_SECTION: symbol is associated with a section. */
1027 if (ELF_ST_TYPE (sym
->st_info
) != STT_SECTION
)
1028 /* Symbol isn't associated with a section. Nothing to do. */
1031 sec
= local_sections
[r_symndx
];
1032 addend
+= sec
->output_offset
+ sym
->st_value
;
1034 /* This can't be done for USE_REL because it doesn't mean anything
1035 and elf_link_input_bfd asserts this stays zero. */
1036 /* rel->r_addend = addend; */
1040 /* Addends are stored with relocs. We're done. */
1043 /* If partial_inplace, we need to store any additional addend
1044 back in the section. */
1045 if (!howto
->partial_inplace
)
1047 /* ??? Here is a nice place to call a special_function like handler. */
1048 r
= _bfd_relocate_contents (howto
, input_bfd
, addend
,
1050 #endif /* USE_REL */
1055 bool resolved_to_zero
;
1057 /* This is a final link. */
1060 unresolved_reloc
= false;
1062 if (r_symndx
< symtab_hdr
->sh_info
)
1065 sym
= local_syms
+ r_symndx
;
1066 sec
= local_sections
[r_symndx
];
1069 sym_name
= "<local symbol>";
1070 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
1071 /* r_addend may have changed if the reference section was
1073 addend
= rel
->r_addend
;
1077 /* External symbol. */
1078 bool warned ATTRIBUTE_UNUSED
;
1079 bool ignored ATTRIBUTE_UNUSED
;
1081 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
1082 r_symndx
, symtab_hdr
, sym_hashes
,
1084 unresolved_reloc
, warned
, ignored
);
1085 sym_name
= h
->root
.root
.string
;
1088 /* Sanity check the address. */
1089 if (offset
> bfd_get_section_limit (input_bfd
, input_section
))
1091 r
= bfd_reloc_outofrange
;
1095 resolved_to_zero
= (h
!= NULL
1096 && UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
));
1098 switch ((int) r_type
)
1100 case (int) R_MICROBLAZE_SRO32
:
1104 /* Only relocate if the symbol is defined. */
1107 name
= bfd_section_name (sec
);
1109 if (strcmp (name
, ".sdata2") == 0
1110 || strcmp (name
, ".sbss2") == 0)
1112 if (ro_small_data_pointer
== 0)
1113 microblaze_elf_final_sdp (info
);
1114 if (ro_small_data_pointer
== 0)
1117 r
= bfd_reloc_undefined
;
1121 /* At this point `relocation' contains the object's
1123 relocation
-= ro_small_data_pointer
;
1124 /* Now it contains the offset from _SDA2_BASE_. */
1125 r
= _bfd_final_link_relocate (howto
, input_bfd
,
1128 relocation
, addend
);
1133 /* xgettext:c-format */
1134 (_("%pB: the target (%s) of an %s relocation"
1135 " is in the wrong section (%pA)"),
1138 microblaze_elf_howto_table
[(int) r_type
]->name
,
1140 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1148 case (int) R_MICROBLAZE_SRW32
:
1152 /* Only relocate if the symbol is defined. */
1155 name
= bfd_section_name (sec
);
1157 if (strcmp (name
, ".sdata") == 0
1158 || strcmp (name
, ".sbss") == 0)
1160 if (rw_small_data_pointer
== 0)
1161 microblaze_elf_final_sdp (info
);
1162 if (rw_small_data_pointer
== 0)
1165 r
= bfd_reloc_undefined
;
1169 /* At this point `relocation' contains the object's
1171 relocation
-= rw_small_data_pointer
;
1172 /* Now it contains the offset from _SDA_BASE_. */
1173 r
= _bfd_final_link_relocate (howto
, input_bfd
,
1176 relocation
, addend
);
1181 /* xgettext:c-format */
1182 (_("%pB: the target (%s) of an %s relocation"
1183 " is in the wrong section (%pA)"),
1186 microblaze_elf_howto_table
[(int) r_type
]->name
,
1188 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1196 case (int) R_MICROBLAZE_32_SYM_OP_SYM
:
1197 break; /* Do nothing. */
1199 case (int) R_MICROBLAZE_GOTPC_64
:
1200 relocation
= (htab
->elf
.sgotplt
->output_section
->vma
1201 + htab
->elf
.sgotplt
->output_offset
);
1202 relocation
-= (input_section
->output_section
->vma
1203 + input_section
->output_offset
1204 + offset
+ INST_WORD_SIZE
);
1205 relocation
+= addend
;
1206 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1207 contents
+ offset
+ endian
);
1208 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1209 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1212 case (int) R_MICROBLAZE_TEXTPCREL_64
:
1213 relocation
= input_section
->output_section
->vma
;
1214 relocation
-= (input_section
->output_section
->vma
1215 + input_section
->output_offset
1216 + offset
+ INST_WORD_SIZE
);
1217 relocation
+= addend
;
1218 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1219 contents
+ offset
+ endian
);
1220 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1221 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1224 case (int) R_MICROBLAZE_PLT_64
:
1227 if (htab
->elf
.splt
!= NULL
&& h
!= NULL
1228 && h
->plt
.offset
!= (bfd_vma
) -1)
1230 relocation
= (htab
->elf
.splt
->output_section
->vma
1231 + htab
->elf
.splt
->output_offset
1233 unresolved_reloc
= false;
1234 immediate
= relocation
- (input_section
->output_section
->vma
1235 + input_section
->output_offset
1236 + offset
+ INST_WORD_SIZE
);
1237 bfd_put_16 (input_bfd
, (immediate
>> 16) & 0xffff,
1238 contents
+ offset
+ endian
);
1239 bfd_put_16 (input_bfd
, immediate
& 0xffff,
1240 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1244 relocation
-= (input_section
->output_section
->vma
1245 + input_section
->output_offset
1246 + offset
+ INST_WORD_SIZE
);
1247 immediate
= relocation
;
1248 bfd_put_16 (input_bfd
, (immediate
>> 16) & 0xffff,
1249 contents
+ offset
+ endian
);
1250 bfd_put_16 (input_bfd
, immediate
& 0xffff,
1251 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1256 case (int) R_MICROBLAZE_TLSGD
:
1257 tls_type
= (TLS_TLS
| TLS_GD
);
1259 case (int) R_MICROBLAZE_TLSLD
:
1260 tls_type
= (TLS_TLS
| TLS_LD
);
1263 case (int) R_MICROBLAZE_GOT_64
:
1268 bfd_vma static_value
;
1270 bool need_relocs
= false;
1271 if (htab
->elf
.sgot
== NULL
)
1277 /* 1. Identify GOT Offset;
1278 2. Compute Static Values
1279 3. Process Module Id, Process Offset
1280 4. Fixup Relocation with GOT offset value. */
1282 /* 1. Determine GOT Offset to use : TLS_LD, global, local */
1283 if (IS_TLS_LD (tls_type
))
1284 offp
= &htab
->tlsld_got
.offset
;
1287 if (htab
->elf
.sgotplt
!= NULL
1288 && h
->got
.offset
!= (bfd_vma
) -1)
1289 offp
= &h
->got
.offset
;
1295 if (local_got_offsets
== NULL
)
1297 offp
= &local_got_offsets
[r_symndx
];
1306 if (IS_TLS_LD(tls_type
) || IS_TLS_GD(tls_type
))
1309 /* Symbol index to use for relocs */
1313 elf_hash_table (info
)->dynamic_sections_created
;
1315 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
,
1316 bfd_link_pic (info
),
1318 && (!bfd_link_pic (info
)
1319 || !SYMBOL_REFERENCES_LOCAL (info
, h
)))
1323 /* Need to generate relocs ? */
1324 if ((bfd_link_pic (info
) || indx
!= 0)
1326 || (ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
1327 && !resolved_to_zero
)
1328 || h
->root
.type
!= bfd_link_hash_undefweak
))
1331 /* 2. Compute/Emit Static value of r-expression */
1332 static_value
= relocation
+ addend
;
1334 /* 3. Process module-id and offset */
1335 if (! ((*offp
) & 1) )
1339 got_offset
= (htab
->elf
.sgot
->output_section
->vma
1340 + htab
->elf
.sgot
->output_offset
1343 /* Process module-id */
1344 if (IS_TLS_LD(tls_type
))
1346 if (! bfd_link_pic (info
))
1347 bfd_put_32 (output_bfd
, 1,
1348 htab
->elf
.sgot
->contents
+ off
);
1350 microblaze_elf_output_dynamic_relocation
1353 htab
->elf
.srelgot
->reloc_count
++,
1354 /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32
,
1357 else if (IS_TLS_GD(tls_type
))
1360 bfd_put_32 (output_bfd
, 1,
1361 htab
->elf
.sgot
->contents
+ off
);
1363 microblaze_elf_output_dynamic_relocation
1366 htab
->elf
.srelgot
->reloc_count
++,
1367 /* symindex= */ indx
, R_MICROBLAZE_TLSDTPMOD32
,
1368 got_offset
, indx
? 0 : static_value
);
1371 /* Process Offset */
1372 if (htab
->elf
.srelgot
== NULL
)
1375 got_offset
= (htab
->elf
.sgot
->output_section
->vma
1376 + htab
->elf
.sgot
->output_offset
1378 if (IS_TLS_LD(tls_type
))
1380 /* For LD, offset should be 0 */
1382 bfd_put_32 (output_bfd
, 0,
1383 htab
->elf
.sgot
->contents
+ off2
);
1385 else if (IS_TLS_GD(tls_type
))
1388 static_value
-= dtprel_base(info
);
1390 microblaze_elf_output_dynamic_relocation
1393 htab
->elf
.srelgot
->reloc_count
++,
1394 /* symindex= */ indx
, R_MICROBLAZE_TLSDTPREL32
,
1395 got_offset
, indx
? 0 : static_value
);
1397 bfd_put_32 (output_bfd
, static_value
,
1398 htab
->elf
.sgot
->contents
+ off2
);
1402 bfd_put_32 (output_bfd
, static_value
,
1403 htab
->elf
.sgot
->contents
+ off2
);
1405 /* Relocs for dyn symbols generated by
1406 finish_dynamic_symbols */
1407 if (bfd_link_pic (info
) && h
== NULL
)
1410 microblaze_elf_output_dynamic_relocation
1413 htab
->elf
.srelgot
->reloc_count
++,
1414 /* symindex= */ indx
, R_MICROBLAZE_REL
,
1415 got_offset
, static_value
);
1420 /* 4. Fixup Relocation with GOT offset value
1421 Compute relative address of GOT entry for applying
1422 the current relocation */
1423 relocation
= htab
->elf
.sgot
->output_section
->vma
1424 + htab
->elf
.sgot
->output_offset
1426 - htab
->elf
.sgotplt
->output_section
->vma
1427 - htab
->elf
.sgotplt
->output_offset
;
1429 /* Apply Current Relocation */
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
);
1435 unresolved_reloc
= false;
1439 case (int) R_MICROBLAZE_GOTOFF_64
:
1442 unsigned short lo
, high
;
1443 relocation
+= addend
;
1444 relocation
-= (htab
->elf
.sgotplt
->output_section
->vma
1445 + htab
->elf
.sgotplt
->output_offset
);
1446 /* Write this value into correct location. */
1447 immediate
= relocation
;
1448 lo
= immediate
& 0x0000ffff;
1449 high
= (immediate
>> 16) & 0x0000ffff;
1450 bfd_put_16 (input_bfd
, high
, contents
+ offset
+ endian
);
1451 bfd_put_16 (input_bfd
, lo
,
1452 contents
+ offset
+ INST_WORD_SIZE
+ endian
);
1456 case (int) R_MICROBLAZE_GOTOFF_32
:
1458 relocation
+= addend
;
1459 relocation
-= (htab
->elf
.sgotplt
->output_section
->vma
1460 + htab
->elf
.sgotplt
->output_offset
);
1461 /* Write this value into correct location. */
1462 bfd_put_32 (input_bfd
, relocation
, contents
+ offset
);
1466 case (int) R_MICROBLAZE_TLSDTPREL64
:
1467 relocation
+= addend
;
1468 relocation
-= dtprel_base(info
);
1469 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1470 contents
+ offset
+ 2);
1471 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1472 contents
+ offset
+ 2 + INST_WORD_SIZE
);
1474 case (int) R_MICROBLAZE_TEXTREL_64
:
1475 case (int) R_MICROBLAZE_TEXTREL_32_LO
:
1476 case (int) R_MICROBLAZE_64_PCREL
:
1477 case (int) R_MICROBLAZE_64
:
1478 case (int) R_MICROBLAZE_32
:
1480 /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
1481 from removed linkonce sections, or sections discarded by
1483 if (r_symndx
== STN_UNDEF
|| (input_section
->flags
& SEC_ALLOC
) == 0)
1485 relocation
+= addend
;
1486 if (r_type
== R_MICROBLAZE_32
)
1487 bfd_put_32 (input_bfd
, relocation
, contents
+ offset
);
1490 if (r_type
== R_MICROBLAZE_64_PCREL
)
1491 relocation
-= (input_section
->output_section
->vma
1492 + input_section
->output_offset
1493 + offset
+ INST_WORD_SIZE
);
1494 else if (r_type
== R_MICROBLAZE_TEXTREL_64
1495 || r_type
== R_MICROBLAZE_TEXTREL_32_LO
)
1496 relocation
-= input_section
->output_section
->vma
;
1498 if (r_type
== R_MICROBLAZE_TEXTREL_32_LO
)
1499 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1500 contents
+ offset
+ endian
);
1504 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1505 contents
+ offset
+ endian
);
1506 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1507 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1513 if ((bfd_link_pic (info
)
1515 || (ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
1516 && !resolved_to_zero
)
1517 || h
->root
.type
!= bfd_link_hash_undefweak
)
1518 && (!howto
->pc_relative
1522 || !h
->def_regular
))))
1523 || (!bfd_link_pic (info
)
1529 || h
->root
.type
== bfd_link_hash_undefweak
1530 || h
->root
.type
== bfd_link_hash_undefined
)))
1532 Elf_Internal_Rela outrel
;
1536 /* When generating a shared object, these relocations
1537 are copied into the output file to be resolved at run
1540 BFD_ASSERT (sreloc
!= NULL
);
1545 _bfd_elf_section_offset (output_bfd
, info
, input_section
,
1547 if (outrel
.r_offset
== (bfd_vma
) -1)
1549 else if (outrel
.r_offset
== (bfd_vma
) -2)
1551 outrel
.r_offset
+= (input_section
->output_section
->vma
1552 + input_section
->output_offset
);
1555 memset (&outrel
, 0, sizeof outrel
);
1556 /* h->dynindx may be -1 if the symbol was marked to
1559 && ((! info
->symbolic
&& h
->dynindx
!= -1)
1560 || !h
->def_regular
))
1562 BFD_ASSERT (h
->dynindx
!= -1);
1563 outrel
.r_info
= ELF32_R_INFO (h
->dynindx
, r_type
);
1564 outrel
.r_addend
= addend
;
1568 if (r_type
== R_MICROBLAZE_32
)
1570 outrel
.r_info
= ELF32_R_INFO (0, R_MICROBLAZE_REL
);
1571 outrel
.r_addend
= relocation
+ addend
;
1577 (_("%pB: probably compiled without -fPIC?"),
1579 bfd_set_error (bfd_error_bad_value
);
1584 loc
= sreloc
->contents
;
1585 loc
+= sreloc
->reloc_count
++ * sizeof (Elf32_External_Rela
);
1586 bfd_elf32_swap_reloca_out (output_bfd
, &outrel
, loc
);
1591 relocation
+= addend
;
1592 if (r_type
== R_MICROBLAZE_32
)
1593 bfd_put_32 (input_bfd
, relocation
, contents
+ offset
);
1596 if (r_type
== R_MICROBLAZE_64_PCREL
)
1597 relocation
-= (input_section
->output_section
->vma
1598 + input_section
->output_offset
1599 + offset
+ INST_WORD_SIZE
);
1600 else if (r_type
== R_MICROBLAZE_TEXTREL_64
1601 || r_type
== R_MICROBLAZE_TEXTREL_32_LO
)
1602 relocation
-= input_section
->output_section
->vma
;
1604 if (r_type
== R_MICROBLAZE_TEXTREL_32_LO
)
1606 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1607 contents
+ offset
+ endian
);
1611 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1612 contents
+ offset
+ endian
);
1613 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1614 contents
+ offset
+ endian
1623 r
= _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
1625 relocation
, addend
);
1632 if (r
!= bfd_reloc_ok
)
1634 /* FIXME: This should be generic enough to go in a utility. */
1638 name
= h
->root
.root
.string
;
1641 name
= (bfd_elf_string_from_elf_section
1642 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
1643 if (name
== NULL
|| *name
== '\0')
1644 name
= bfd_section_name (sec
);
1652 case bfd_reloc_overflow
:
1653 (*info
->callbacks
->reloc_overflow
)
1654 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
,
1655 (bfd_vma
) 0, input_bfd
, input_section
, offset
);
1658 case bfd_reloc_undefined
:
1659 (*info
->callbacks
->undefined_symbol
)
1660 (info
, name
, input_bfd
, input_section
, offset
, true);
1663 case bfd_reloc_outofrange
:
1664 errmsg
= _("internal error: out of range error");
1667 case bfd_reloc_notsupported
:
1668 errmsg
= _("internal error: unsupported relocation error");
1671 case bfd_reloc_dangerous
:
1672 errmsg
= _("internal error: dangerous error");
1676 errmsg
= _("internal error: unknown error");
1679 (*info
->callbacks
->warning
) (info
, errmsg
, name
, input_bfd
,
1680 input_section
, offset
);
1689 /* Calculate fixup value for reference. */
1692 calc_fixup (bfd_vma start
, bfd_vma size
, asection
*sec
)
1694 bfd_vma end
= start
+ size
;
1695 size_t i
, fixup
= 0;
1696 struct _microblaze_elf_section_data
*sdata
;
1698 if (sec
== NULL
|| (sdata
= microblaze_elf_section_data (sec
)) == NULL
)
1701 /* Look for addr in relax table, total fixup value. */
1702 for (i
= 0; i
< sdata
->relax_count
; i
++)
1704 if (end
<= sdata
->relax
[i
].addr
)
1706 if (end
!= start
&& start
> sdata
->relax
[i
].addr
)
1708 fixup
+= sdata
->relax
[i
].size
;
1713 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1714 a 32-bit instruction. */
1716 microblaze_bfd_write_imm_value_32 (bfd
*abfd
, bfd_byte
*bfd_addr
, bfd_vma val
)
1718 unsigned long instr
= bfd_get_32 (abfd
, bfd_addr
);
1719 instr
&= ~0x0000ffff;
1720 instr
|= (val
& 0x0000ffff);
1721 bfd_put_32 (abfd
, instr
, bfd_addr
);
1724 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1725 two consecutive 32-bit instructions. */
1727 microblaze_bfd_write_imm_value_64 (bfd
*abfd
, bfd_byte
*bfd_addr
, bfd_vma val
)
1729 unsigned long instr_hi
;
1730 unsigned long instr_lo
;
1732 instr_hi
= bfd_get_32 (abfd
, bfd_addr
);
1733 instr_hi
&= ~0x0000ffff;
1734 instr_hi
|= ((val
>> 16) & 0x0000ffff);
1735 bfd_put_32 (abfd
, instr_hi
, bfd_addr
);
1737 instr_lo
= bfd_get_32 (abfd
, bfd_addr
+ INST_WORD_SIZE
);
1738 instr_lo
&= ~0x0000ffff;
1739 instr_lo
|= (val
& 0x0000ffff);
1740 bfd_put_32 (abfd
, instr_lo
, bfd_addr
+ INST_WORD_SIZE
);
1744 microblaze_elf_relax_section (bfd
*abfd
,
1746 struct bfd_link_info
*link_info
,
1749 Elf_Internal_Shdr
*symtab_hdr
;
1750 Elf_Internal_Rela
*internal_relocs
;
1751 Elf_Internal_Rela
*free_relocs
= NULL
;
1752 Elf_Internal_Rela
*irel
, *irelend
;
1753 bfd_byte
*contents
= NULL
;
1754 bfd_byte
*free_contents
= NULL
;
1757 size_t i
, sym_index
;
1759 struct elf_link_hash_entry
*sym_hash
;
1760 Elf_Internal_Sym
*isymbuf
, *isymend
;
1761 Elf_Internal_Sym
*isym
;
1765 struct _microblaze_elf_section_data
*sdata
;
1767 /* We only do this once per section. We may be able to delete some code
1768 by running multiple passes, but it is not worth it. */
1771 /* Only do this for a text section. */
1772 if (bfd_link_relocatable (link_info
)
1773 || (sec
->flags
& SEC_RELOC
) == 0
1774 || (sec
->flags
& SEC_CODE
) == 0
1775 || sec
->reloc_count
== 0
1776 || (sdata
= microblaze_elf_section_data (sec
)) == NULL
)
1779 BFD_ASSERT ((sec
->size
> 0) || (sec
->rawsize
> 0));
1781 /* If this is the first time we have been called for this section,
1782 initialize the cooked size. */
1784 sec
->size
= sec
->rawsize
;
1786 /* Get symbols for this section. */
1787 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1788 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1789 symcount
= symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
);
1790 if (isymbuf
== NULL
)
1791 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
, symcount
,
1792 0, NULL
, NULL
, NULL
);
1793 BFD_ASSERT (isymbuf
!= NULL
);
1795 internal_relocs
= _bfd_elf_link_read_relocs (abfd
, sec
, NULL
, NULL
, link_info
->keep_memory
);
1796 if (internal_relocs
== NULL
)
1798 if (! link_info
->keep_memory
)
1799 free_relocs
= internal_relocs
;
1801 sdata
->relax_count
= 0;
1802 sdata
->relax
= (struct relax_table
*) bfd_malloc ((sec
->reloc_count
+ 1)
1803 * sizeof (*sdata
->relax
));
1804 if (sdata
->relax
== NULL
)
1807 irelend
= internal_relocs
+ sec
->reloc_count
;
1809 for (irel
= internal_relocs
; irel
< irelend
; irel
++, rel_count
++)
1812 if ((ELF32_R_TYPE (irel
->r_info
) != (int) R_MICROBLAZE_64_PCREL
)
1813 && (ELF32_R_TYPE (irel
->r_info
) != (int) R_MICROBLAZE_64
)
1814 && (ELF32_R_TYPE (irel
->r_info
) != (int) R_MICROBLAZE_TEXTREL_64
))
1815 continue; /* Can't delete this reloc. */
1817 /* Get the section contents. */
1818 if (contents
== NULL
)
1820 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
1821 contents
= elf_section_data (sec
)->this_hdr
.contents
;
1824 contents
= (bfd_byte
*) bfd_malloc (sec
->size
);
1825 if (contents
== NULL
)
1827 free_contents
= contents
;
1829 if (!bfd_get_section_contents (abfd
, sec
, contents
,
1830 (file_ptr
) 0, sec
->size
))
1832 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1836 /* Get the value of the symbol referred to by the reloc. */
1837 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
1839 /* A local symbol. */
1842 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
1843 if (isym
->st_shndx
== SHN_UNDEF
)
1844 sym_sec
= bfd_und_section_ptr
;
1845 else if (isym
->st_shndx
== SHN_ABS
)
1846 sym_sec
= bfd_abs_section_ptr
;
1847 else if (isym
->st_shndx
== SHN_COMMON
)
1848 sym_sec
= bfd_com_section_ptr
;
1850 sym_sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
1852 symval
= _bfd_elf_rela_local_sym (abfd
, isym
, &sym_sec
, irel
);
1857 struct elf_link_hash_entry
*h
;
1859 indx
= ELF32_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
1860 h
= elf_sym_hashes (abfd
)[indx
];
1861 BFD_ASSERT (h
!= NULL
);
1863 if (h
->root
.type
!= bfd_link_hash_defined
1864 && h
->root
.type
!= bfd_link_hash_defweak
)
1865 /* This appears to be a reference to an undefined
1866 symbol. Just ignore it--it will be caught by the
1867 regular reloc processing. */
1870 symval
= (h
->root
.u
.def
.value
1871 + h
->root
.u
.def
.section
->output_section
->vma
1872 + h
->root
.u
.def
.section
->output_offset
);
1875 /* If this is a PC-relative reloc, subtract the instr offset from
1876 the symbol value. */
1877 if (ELF32_R_TYPE (irel
->r_info
) == (int) R_MICROBLAZE_64_PCREL
)
1879 symval
= symval
+ irel
->r_addend
1881 + sec
->output_section
->vma
1882 + sec
->output_offset
);
1884 else if (ELF32_R_TYPE (irel
->r_info
) == (int) R_MICROBLAZE_TEXTREL_64
)
1886 symval
= symval
+ irel
->r_addend
- (sec
->output_section
->vma
);
1889 symval
+= irel
->r_addend
;
1891 if ((symval
& 0xffff8000) == 0
1892 || (symval
& 0xffff8000) == 0xffff8000)
1894 /* We can delete this instruction. */
1895 sdata
->relax
[sdata
->relax_count
].addr
= irel
->r_offset
;
1896 sdata
->relax
[sdata
->relax_count
].size
= INST_WORD_SIZE
;
1897 sdata
->relax_count
++;
1899 /* Rewrite relocation type. */
1900 switch ((enum elf_microblaze_reloc_type
) ELF32_R_TYPE (irel
->r_info
))
1902 case R_MICROBLAZE_64_PCREL
:
1903 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1904 (int) R_MICROBLAZE_32_PCREL_LO
);
1906 case R_MICROBLAZE_64
:
1907 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1908 (int) R_MICROBLAZE_32_LO
);
1910 case R_MICROBLAZE_TEXTREL_64
:
1911 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1912 (int) R_MICROBLAZE_TEXTREL_32_LO
);
1915 /* Cannot happen. */
1919 } /* Loop through all relocations. */
1921 /* Loop through the relocs again, and see if anything needs to change. */
1922 if (sdata
->relax_count
> 0)
1924 shndx
= _bfd_elf_section_from_bfd_section (abfd
, sec
);
1926 sdata
->relax
[sdata
->relax_count
].addr
= sec
->size
;
1928 for (irel
= internal_relocs
; irel
< irelend
; irel
++, rel_count
++)
1932 /* Get the new reloc address. */
1933 nraddr
= irel
->r_offset
- calc_fixup (irel
->r_offset
, 0, sec
);
1934 switch ((enum elf_microblaze_reloc_type
) ELF32_R_TYPE (irel
->r_info
))
1938 case R_MICROBLAZE_64_PCREL
:
1940 case R_MICROBLAZE_TEXTREL_64
:
1941 case R_MICROBLAZE_TEXTREL_32_LO
:
1942 case R_MICROBLAZE_64
:
1943 case R_MICROBLAZE_32_LO
:
1944 /* If this reloc is against a symbol defined in this
1945 section, we must check the addend to see it will put the value in
1946 range to be adjusted, and hence must be changed. */
1947 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
1949 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
1950 /* Only handle relocs against .text. */
1951 if (isym
->st_shndx
== shndx
1952 && ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
)
1953 irel
->r_addend
-= calc_fixup (irel
->r_addend
, 0, sec
);
1956 case R_MICROBLAZE_NONE
:
1958 /* This was a PC-relative instruction that was
1959 completely resolved. */
1961 bfd_vma target_address
;
1962 target_address
= irel
->r_addend
+ irel
->r_offset
;
1963 sfix
= calc_fixup (irel
->r_offset
, 0, sec
);
1964 efix
= calc_fixup (target_address
, 0, sec
);
1965 irel
->r_addend
-= (efix
- sfix
);
1966 /* Should use HOWTO. */
1967 microblaze_bfd_write_imm_value_32 (abfd
, contents
+ irel
->r_offset
,
1971 case R_MICROBLAZE_64_NONE
:
1973 /* This was a PC-relative 64-bit instruction that was
1974 completely resolved. */
1976 bfd_vma target_address
;
1977 target_address
= irel
->r_addend
+ irel
->r_offset
+ INST_WORD_SIZE
;
1978 sfix
= calc_fixup (irel
->r_offset
+ INST_WORD_SIZE
, 0, sec
);
1979 efix
= calc_fixup (target_address
, 0, sec
);
1980 irel
->r_addend
-= (efix
- sfix
);
1981 microblaze_bfd_write_imm_value_32 (abfd
, contents
+ irel
->r_offset
1982 + INST_WORD_SIZE
, irel
->r_addend
);
1986 irel
->r_offset
= nraddr
;
1987 } /* Change all relocs in this section. */
1989 /* Look through all other sections. */
1990 for (o
= abfd
->sections
; o
!= NULL
; o
= o
->next
)
1992 Elf_Internal_Rela
*irelocs
;
1993 Elf_Internal_Rela
*irelscan
, *irelscanend
;
1994 bfd_byte
*ocontents
;
1997 || (o
->flags
& SEC_RELOC
) == 0
1998 || o
->reloc_count
== 0)
2001 /* We always cache the relocs. Perhaps, if info->keep_memory is
2002 FALSE, we should free them, if we are permitted to. */
2004 irelocs
= _bfd_elf_link_read_relocs (abfd
, o
, NULL
, NULL
, true);
2005 if (irelocs
== NULL
)
2009 irelscanend
= irelocs
+ o
->reloc_count
;
2010 for (irelscan
= irelocs
; irelscan
< irelscanend
; irelscan
++)
2012 if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32
)
2014 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2016 /* Look at the reloc only if the value has been resolved. */
2017 if (isym
->st_shndx
== shndx
2018 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2020 if (ocontents
== NULL
)
2022 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2023 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2026 /* We always cache the section contents.
2027 Perhaps, if info->keep_memory is FALSE, we
2028 should free them, if we are permitted to. */
2029 if (o
->rawsize
== 0)
2030 o
->rawsize
= o
->size
;
2031 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2032 if (ocontents
== NULL
)
2034 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2038 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2042 irelscan
->r_addend
-= calc_fixup (irelscan
->r_addend
, 0, sec
);
2044 else if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32_SYM_OP_SYM
)
2046 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2048 /* Look at the reloc only if the value has been resolved. */
2049 if (ocontents
== NULL
)
2051 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2052 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2055 /* We always cache the section contents.
2056 Perhaps, if info->keep_memory is FALSE, we
2057 should free them, if we are permitted to. */
2059 if (o
->rawsize
== 0)
2060 o
->rawsize
= o
->size
;
2061 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2062 if (ocontents
== NULL
)
2064 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2068 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2071 irelscan
->r_addend
-= calc_fixup (irel
->r_addend
2077 else if ((ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32_PCREL_LO
)
2078 || (ELF32_R_TYPE (irelscan
->r_info
)
2079 == (int) R_MICROBLAZE_32_LO
)
2080 || (ELF32_R_TYPE (irelscan
->r_info
)
2081 == (int) R_MICROBLAZE_TEXTREL_32_LO
))
2083 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2085 /* Look at the reloc only if the value has been resolved. */
2086 if (isym
->st_shndx
== shndx
2087 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2090 bfd_vma target_address
;
2092 if (ocontents
== NULL
)
2094 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2095 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2098 /* We always cache the section contents.
2099 Perhaps, if info->keep_memory is FALSE, we
2100 should free them, if we are permitted to. */
2101 if (o
->rawsize
== 0)
2102 o
->rawsize
= o
->size
;
2103 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2104 if (ocontents
== NULL
)
2106 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2110 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2114 unsigned long instr
= bfd_get_32 (abfd
, ocontents
+ irelscan
->r_offset
);
2115 immediate
= instr
& 0x0000ffff;
2116 target_address
= immediate
;
2117 offset
= calc_fixup (target_address
, 0, sec
);
2118 immediate
-= offset
;
2119 irelscan
->r_addend
-= offset
;
2120 microblaze_bfd_write_imm_value_32 (abfd
, ocontents
+ irelscan
->r_offset
,
2121 irelscan
->r_addend
);
2125 if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_64
2126 || (ELF32_R_TYPE (irelscan
->r_info
)
2127 == (int) R_MICROBLAZE_TEXTREL_64
))
2129 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2131 /* Look at the reloc only if the value has been resolved. */
2132 if (isym
->st_shndx
== shndx
2133 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2135 if (ocontents
== NULL
)
2137 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2138 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2141 /* We always cache the section contents.
2142 Perhaps, if info->keep_memory is FALSE, we
2143 should free them, if we are permitted to. */
2145 if (o
->rawsize
== 0)
2146 o
->rawsize
= o
->size
;
2147 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2148 if (ocontents
== NULL
)
2150 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2154 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2157 offset
= calc_fixup (irelscan
->r_addend
, 0, sec
);
2158 irelscan
->r_addend
-= offset
;
2161 else if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_64_PCREL
)
2163 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2165 /* Look at the reloc only if the value has been resolved. */
2166 if (isym
->st_shndx
== shndx
2167 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2170 bfd_vma target_address
;
2172 if (ocontents
== NULL
)
2174 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2175 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2178 /* We always cache the section contents.
2179 Perhaps, if info->keep_memory is FALSE, we
2180 should free them, if we are permitted to. */
2181 if (o
->rawsize
== 0)
2182 o
->rawsize
= o
->size
;
2183 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2184 if (ocontents
== NULL
)
2186 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2190 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2193 unsigned long instr_hi
= bfd_get_32 (abfd
, ocontents
2194 + irelscan
->r_offset
);
2195 unsigned long instr_lo
= bfd_get_32 (abfd
, ocontents
2196 + irelscan
->r_offset
2198 immediate
= (instr_hi
& 0x0000ffff) << 16;
2199 immediate
|= (instr_lo
& 0x0000ffff);
2200 target_address
= immediate
;
2201 offset
= calc_fixup (target_address
, 0, sec
);
2202 immediate
-= offset
;
2203 irelscan
->r_addend
-= offset
;
2204 microblaze_bfd_write_imm_value_64 (abfd
, ocontents
2205 + irelscan
->r_offset
, immediate
);
2211 /* Adjust the local symbols defined in this section. */
2212 isymend
= isymbuf
+ symtab_hdr
->sh_info
;
2213 for (isym
= isymbuf
; isym
< isymend
; isym
++)
2215 if (isym
->st_shndx
== shndx
)
2217 isym
->st_value
-= calc_fixup (isym
->st_value
, 0, sec
);
2219 isym
->st_size
-= calc_fixup (isym
->st_value
, isym
->st_size
, sec
);
2223 /* Now adjust the global symbols defined in this section. */
2224 isym
= isymbuf
+ symtab_hdr
->sh_info
;
2225 symcount
= (symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
)) - symtab_hdr
->sh_info
;
2226 for (sym_index
= 0; sym_index
< symcount
; sym_index
++)
2228 sym_hash
= elf_sym_hashes (abfd
)[sym_index
];
2229 if ((sym_hash
->root
.type
== bfd_link_hash_defined
2230 || sym_hash
->root
.type
== bfd_link_hash_defweak
)
2231 && sym_hash
->root
.u
.def
.section
== sec
)
2233 sym_hash
->root
.u
.def
.value
-= calc_fixup (sym_hash
->root
.u
.def
.value
,
2236 sym_hash
->size
-= calc_fixup (sym_hash
->root
.u
.def
.value
,
2237 sym_hash
->size
, sec
);
2241 /* Physically move the code and change the cooked size. */
2242 dest
= sdata
->relax
[0].addr
;
2243 for (i
= 0; i
< sdata
->relax_count
; i
++)
2246 src
= sdata
->relax
[i
].addr
+ sdata
->relax
[i
].size
;
2247 len
= (sdata
->relax
[i
+1].addr
- sdata
->relax
[i
].addr
2248 - sdata
->relax
[i
].size
);
2250 memmove (contents
+ dest
, contents
+ src
, len
);
2251 sec
->size
-= sdata
->relax
[i
].size
;
2255 elf_section_data (sec
)->relocs
= internal_relocs
;
2258 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2259 free_contents
= NULL
;
2261 symtab_hdr
->contents
= (bfd_byte
*) isymbuf
;
2267 if (free_contents
!= NULL
)
2269 if (!link_info
->keep_memory
)
2270 free (free_contents
);
2272 /* Cache the section contents for elf_link_input_bfd. */
2273 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2274 free_contents
= NULL
;
2277 if (sdata
->relax_count
== 0)
2280 free (sdata
->relax
);
2281 sdata
->relax
= NULL
;
2289 free (free_contents
);
2290 free (sdata
->relax
);
2291 sdata
->relax
= NULL
;
2292 sdata
->relax_count
= 0;
2296 /* Return the section that should be marked against GC for a given
2300 microblaze_elf_gc_mark_hook (asection
*sec
,
2301 struct bfd_link_info
* info
,
2302 Elf_Internal_Rela
* rel
,
2303 struct elf_link_hash_entry
* h
,
2304 Elf_Internal_Sym
* sym
)
2307 switch (ELF32_R_TYPE (rel
->r_info
))
2309 case R_MICROBLAZE_GNU_VTINHERIT
:
2310 case R_MICROBLAZE_GNU_VTENTRY
:
2314 return _bfd_elf_gc_mark_hook (sec
, info
, rel
, h
, sym
);
2319 #define PLT_ENTRY_SIZE 16
2321 #define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
2322 #define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
2323 #define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
2324 #define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
2325 #define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
2328 update_local_sym_info (bfd
*abfd
,
2329 Elf_Internal_Shdr
*symtab_hdr
,
2330 unsigned long r_symndx
,
2331 unsigned int tls_type
)
2333 bfd_signed_vma
*local_got_refcounts
= elf_local_got_refcounts (abfd
);
2334 unsigned char *local_got_tls_masks
;
2336 if (local_got_refcounts
== NULL
)
2338 bfd_size_type size
= symtab_hdr
->sh_info
;
2340 size
*= (sizeof (*local_got_refcounts
) + sizeof (*local_got_tls_masks
));
2341 local_got_refcounts
= bfd_zalloc (abfd
, size
);
2342 if (local_got_refcounts
== NULL
)
2344 elf_local_got_refcounts (abfd
) = local_got_refcounts
;
2347 local_got_tls_masks
=
2348 (unsigned char *) (local_got_refcounts
+ symtab_hdr
->sh_info
);
2349 local_got_tls_masks
[r_symndx
] |= tls_type
;
2350 local_got_refcounts
[r_symndx
] += 1;
2354 /* Look through the relocs for a section during the first phase. */
2357 microblaze_elf_check_relocs (bfd
* abfd
,
2358 struct bfd_link_info
* info
,
2360 const Elf_Internal_Rela
* relocs
)
2362 Elf_Internal_Shdr
* symtab_hdr
;
2363 struct elf_link_hash_entry
** sym_hashes
;
2364 const Elf_Internal_Rela
* rel
;
2365 const Elf_Internal_Rela
* rel_end
;
2366 struct elf32_mb_link_hash_table
*htab
;
2367 asection
*sreloc
= NULL
;
2369 if (bfd_link_relocatable (info
))
2372 htab
= elf32_mb_hash_table (info
);
2376 symtab_hdr
= & elf_tdata (abfd
)->symtab_hdr
;
2377 sym_hashes
= elf_sym_hashes (abfd
);
2379 rel_end
= relocs
+ sec
->reloc_count
;
2381 for (rel
= relocs
; rel
< rel_end
; rel
++)
2383 unsigned int r_type
;
2384 struct elf_link_hash_entry
* h
;
2385 unsigned long r_symndx
;
2386 unsigned char tls_type
= 0;
2388 r_symndx
= ELF32_R_SYM (rel
->r_info
);
2389 r_type
= ELF32_R_TYPE (rel
->r_info
);
2391 if (r_symndx
< symtab_hdr
->sh_info
)
2395 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
2396 while (h
->root
.type
== bfd_link_hash_indirect
2397 || h
->root
.type
== bfd_link_hash_warning
)
2398 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2403 /* This relocation describes the C++ object vtable hierarchy.
2404 Reconstruct it for later use during GC. */
2405 case R_MICROBLAZE_GNU_VTINHERIT
:
2406 if (!bfd_elf_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
2410 /* This relocation describes which C++ vtable entries are actually
2411 used. Record for later use during GC. */
2412 case R_MICROBLAZE_GNU_VTENTRY
:
2413 if (!bfd_elf_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
2417 /* This relocation requires .plt entry. */
2418 case R_MICROBLAZE_PLT_64
:
2422 h
->plt
.refcount
+= 1;
2426 /* This relocation requires .got entry. */
2427 case R_MICROBLAZE_TLSGD
:
2428 tls_type
|= (TLS_TLS
| TLS_GD
);
2430 case R_MICROBLAZE_TLSLD
:
2431 tls_type
|= (TLS_TLS
| TLS_LD
);
2434 sec
->has_tls_reloc
= 1;
2436 case R_MICROBLAZE_GOT_64
:
2437 if (htab
->elf
.sgot
== NULL
)
2439 if (htab
->elf
.dynobj
== NULL
)
2440 htab
->elf
.dynobj
= abfd
;
2441 if (!_bfd_elf_create_got_section (htab
->elf
.dynobj
, info
))
2446 h
->got
.refcount
+= 1;
2447 elf32_mb_hash_entry (h
)->tls_mask
|= tls_type
;
2451 if (! update_local_sym_info(abfd
, symtab_hdr
, r_symndx
, tls_type
) )
2456 case R_MICROBLAZE_GOTOFF_64
:
2457 case R_MICROBLAZE_GOTOFF_32
:
2458 if (htab
->elf
.sgot
== NULL
)
2460 if (htab
->elf
.dynobj
== NULL
)
2461 htab
->elf
.dynobj
= abfd
;
2462 if (!_bfd_elf_create_got_section (htab
->elf
.dynobj
, info
))
2467 case R_MICROBLAZE_64
:
2468 case R_MICROBLAZE_64_PCREL
:
2469 case R_MICROBLAZE_32
:
2471 if (h
!= NULL
&& !bfd_link_pic (info
))
2473 /* we may need a copy reloc. */
2476 /* we may also need a .plt entry. */
2477 h
->plt
.refcount
+= 1;
2478 if (ELF32_R_TYPE (rel
->r_info
) != R_MICROBLAZE_64_PCREL
)
2479 h
->pointer_equality_needed
= 1;
2483 /* If we are creating a shared library, and this is a reloc
2484 against a global symbol, or a non PC relative reloc
2485 against a local symbol, then we need to copy the reloc
2486 into the shared library. However, if we are linking with
2487 -Bsymbolic, we do not need to copy a reloc against a
2488 global symbol which is defined in an object we are
2489 including in the link (i.e., DEF_REGULAR is set). At
2490 this point we have not seen all the input files, so it is
2491 possible that DEF_REGULAR is not set now but will be set
2492 later (it is never cleared). In case of a weak definition,
2493 DEF_REGULAR may be cleared later by a strong definition in
2494 a shared library. We account for that possibility below by
2495 storing information in the relocs_copied field of the hash
2496 table entry. A similar situation occurs when creating
2497 shared libraries and symbol visibility changes render the
2500 If on the other hand, we are creating an executable, we
2501 may need to keep relocations for symbols satisfied by a
2502 dynamic library if we manage to avoid copy relocs for the
2505 if ((bfd_link_pic (info
)
2506 && (sec
->flags
& SEC_ALLOC
) != 0
2507 && (r_type
!= R_MICROBLAZE_64_PCREL
2509 && (! info
->symbolic
2510 || h
->root
.type
== bfd_link_hash_defweak
2511 || !h
->def_regular
))))
2512 || (!bfd_link_pic (info
)
2513 && (sec
->flags
& SEC_ALLOC
) != 0
2515 && (h
->root
.type
== bfd_link_hash_defweak
2516 || !h
->def_regular
)))
2518 struct elf_dyn_relocs
*p
;
2519 struct elf_dyn_relocs
**head
;
2521 /* When creating a shared object, we must copy these
2522 relocs into the output file. We create a reloc
2523 section in dynobj and make room for the reloc. */
2529 if (htab
->elf
.dynobj
== NULL
)
2530 htab
->elf
.dynobj
= abfd
;
2531 dynobj
= htab
->elf
.dynobj
;
2533 sreloc
= _bfd_elf_make_dynamic_reloc_section (sec
, dynobj
,
2539 /* If this is a global symbol, we count the number of
2540 relocations we need for this symbol. */
2542 head
= &h
->dyn_relocs
;
2545 /* Track dynamic relocs needed for local syms too.
2546 We really need local syms available to do this
2550 Elf_Internal_Sym
*isym
;
2553 isym
= bfd_sym_from_r_symndx (&htab
->elf
.sym_cache
,
2558 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
2562 vpp
= &elf_section_data (s
)->local_dynrel
;
2563 head
= (struct elf_dyn_relocs
**) vpp
;
2567 if (p
== NULL
|| p
->sec
!= sec
)
2569 size_t amt
= sizeof *p
;
2570 p
= ((struct elf_dyn_relocs
*)
2571 bfd_alloc (htab
->elf
.dynobj
, amt
));
2582 if (r_type
== R_MICROBLAZE_64_PCREL
)
2593 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2596 microblaze_elf_copy_indirect_symbol (struct bfd_link_info
*info
,
2597 struct elf_link_hash_entry
*dir
,
2598 struct elf_link_hash_entry
*ind
)
2600 struct elf32_mb_link_hash_entry
*edir
, *eind
;
2602 edir
= (struct elf32_mb_link_hash_entry
*) dir
;
2603 eind
= (struct elf32_mb_link_hash_entry
*) ind
;
2605 edir
->tls_mask
|= eind
->tls_mask
;
2607 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
2611 microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info
*info
,
2612 struct elf_link_hash_entry
*h
)
2614 struct elf32_mb_link_hash_table
*htab
;
2616 unsigned int power_of_two
;
2618 htab
= elf32_mb_hash_table (info
);
2622 /* If this is a function, put it in the procedure linkage table. We
2623 will fill in the contents of the procedure linkage table later,
2624 when we know the address of the .got section. */
2625 if (h
->type
== STT_FUNC
2628 if (h
->plt
.refcount
<= 0
2629 || SYMBOL_CALLS_LOCAL (info
, h
)
2630 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
2631 && h
->root
.type
== bfd_link_hash_undefweak
))
2633 /* This case can occur if we saw a PLT reloc in an input
2634 file, but the symbol was never referred to by a dynamic
2635 object, or if all references were garbage collected. In
2636 such a case, we don't actually need to build a procedure
2637 linkage table, and we can just do a PC32 reloc instead. */
2638 h
->plt
.offset
= (bfd_vma
) -1;
2645 /* It's possible that we incorrectly decided a .plt reloc was
2646 needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
2647 check_relocs. We can't decide accurately between function and
2648 non-function syms in check-relocs; Objects loaded later in
2649 the link may change h->type. So fix it now. */
2650 h
->plt
.offset
= (bfd_vma
) -1;
2652 /* If this is a weak symbol, and there is a real definition, the
2653 processor independent code will have arranged for us to see the
2654 real definition first, and we can just use the same value. */
2655 if (h
->is_weakalias
)
2657 struct elf_link_hash_entry
*def
= weakdef (h
);
2658 BFD_ASSERT (def
->root
.type
== bfd_link_hash_defined
);
2659 h
->root
.u
.def
.section
= def
->root
.u
.def
.section
;
2660 h
->root
.u
.def
.value
= def
->root
.u
.def
.value
;
2664 /* This is a reference to a symbol defined by a dynamic object which
2665 is not a function. */
2667 /* If we are creating a shared library, we must presume that the
2668 only references to the symbol are via the global offset table.
2669 For such cases we need not do anything here; the relocations will
2670 be handled correctly by relocate_section. */
2671 if (bfd_link_pic (info
))
2674 /* If there are no references to this symbol that do not use the
2675 GOT, we don't need to generate a copy reloc. */
2676 if (!h
->non_got_ref
)
2679 /* If -z nocopyreloc was given, we won't generate them either. */
2680 if (info
->nocopyreloc
)
2686 /* If we don't find any dynamic relocs in read-only sections, then
2687 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
2688 if (!_bfd_elf_readonly_dynrelocs (h
))
2694 /* We must allocate the symbol in our .dynbss section, which will
2695 become part of the .bss section of the executable. There will be
2696 an entry for this symbol in the .dynsym section. The dynamic
2697 object will contain position independent code, so all references
2698 from the dynamic object to this symbol will go through the global
2699 offset table. The dynamic linker will use the .dynsym entry to
2700 determine the address it must put in the global offset table, so
2701 both the dynamic object and the regular object will refer to the
2702 same memory location for the variable. */
2704 /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
2705 to copy the initial value out of the dynamic object and into the
2706 runtime process image. */
2707 if ((h
->root
.u
.def
.section
->flags
& SEC_READONLY
) != 0)
2709 s
= htab
->elf
.sdynrelro
;
2710 srel
= htab
->elf
.sreldynrelro
;
2714 s
= htab
->elf
.sdynbss
;
2715 srel
= htab
->elf
.srelbss
;
2717 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0)
2719 srel
->size
+= sizeof (Elf32_External_Rela
);
2723 /* We need to figure out the alignment required for this symbol. I
2724 have no idea how ELF linkers handle this. */
2725 power_of_two
= bfd_log2 (h
->size
);
2726 if (power_of_two
> 3)
2729 /* Apply the required alignment. */
2730 s
->size
= BFD_ALIGN (s
->size
, (bfd_size_type
) (1 << power_of_two
));
2731 if (power_of_two
> s
->alignment_power
)
2733 if (!bfd_set_section_alignment (s
, power_of_two
))
2737 /* Define the symbol as being at this point in the section. */
2738 h
->root
.u
.def
.section
= s
;
2739 h
->root
.u
.def
.value
= s
->size
;
2741 /* Increment the section size to make room for the symbol. */
2746 /* Allocate space in .plt, .got and associated reloc sections for
2750 allocate_dynrelocs (struct elf_link_hash_entry
*h
, void * dat
)
2752 struct bfd_link_info
*info
;
2753 struct elf32_mb_link_hash_table
*htab
;
2754 struct elf32_mb_link_hash_entry
*eh
;
2755 struct elf_dyn_relocs
*p
;
2757 if (h
->root
.type
== bfd_link_hash_indirect
)
2760 info
= (struct bfd_link_info
*) dat
;
2761 htab
= elf32_mb_hash_table (info
);
2765 if (htab
->elf
.dynamic_sections_created
2766 && h
->plt
.refcount
> 0)
2768 /* Make sure this symbol is output as a dynamic symbol.
2769 Undefined weak syms won't yet be marked as dynamic. */
2770 if (h
->dynindx
== -1
2771 && !h
->forced_local
)
2773 if (! bfd_elf_link_record_dynamic_symbol (info
, h
))
2777 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info
), h
))
2779 asection
*s
= htab
->elf
.splt
;
2781 /* The first entry in .plt is reserved. */
2783 s
->size
= PLT_ENTRY_SIZE
;
2785 h
->plt
.offset
= s
->size
;
2787 /* If this symbol is not defined in a regular file, and we are
2788 not generating a shared library, then set the symbol to this
2789 location in the .plt. This is required to make function
2790 pointers compare as equal between the normal executable and
2791 the shared library. */
2792 if (! bfd_link_pic (info
)
2795 h
->root
.u
.def
.section
= s
;
2796 h
->root
.u
.def
.value
= h
->plt
.offset
;
2799 /* Make room for this entry. */
2800 s
->size
+= PLT_ENTRY_SIZE
;
2802 /* We also need to make an entry in the .got.plt section, which
2803 will be placed in the .got section by the linker script. */
2804 htab
->elf
.sgotplt
->size
+= 4;
2806 /* We also need to make an entry in the .rel.plt section. */
2807 htab
->elf
.srelplt
->size
+= sizeof (Elf32_External_Rela
);
2811 h
->plt
.offset
= (bfd_vma
) -1;
2817 h
->plt
.offset
= (bfd_vma
) -1;
2821 eh
= (struct elf32_mb_link_hash_entry
*) h
;
2822 if (h
->got
.refcount
> 0)
2827 /* Make sure this symbol is output as a dynamic symbol.
2828 Undefined weak syms won't yet be marked as dynamic. */
2829 if (h
->dynindx
== -1
2830 && !h
->forced_local
)
2832 if (! bfd_elf_link_record_dynamic_symbol (info
, h
))
2837 if ((eh
->tls_mask
& TLS_TLS
) != 0)
2839 /* Handle TLS Symbol */
2840 if ((eh
->tls_mask
& TLS_LD
) != 0)
2842 if (!eh
->elf
.def_dynamic
)
2843 /* We'll just use htab->tlsld_got.offset. This should
2844 always be the case. It's a little odd if we have
2845 a local dynamic reloc against a non-local symbol. */
2846 htab
->tlsld_got
.refcount
+= 1;
2850 if ((eh
->tls_mask
& TLS_GD
) != 0)
2855 /* Regular (non-TLS) symbol */
2860 h
->got
.offset
= (bfd_vma
) -1;
2865 h
->got
.offset
= s
->size
;
2867 htab
->elf
.srelgot
->size
+= need
* (sizeof (Elf32_External_Rela
) / 4);
2871 h
->got
.offset
= (bfd_vma
) -1;
2873 if (h
->dyn_relocs
== NULL
)
2876 /* In the shared -Bsymbolic case, discard space allocated for
2877 dynamic pc-relative relocs against symbols which turn out to be
2878 defined in regular objects. For the normal shared case, discard
2879 space for pc-relative relocs that have become local due to symbol
2880 visibility changes. */
2882 if (bfd_link_pic (info
))
2888 struct elf_dyn_relocs
**pp
;
2890 for (pp
= &h
->dyn_relocs
; (p
= *pp
) != NULL
; )
2892 p
->count
-= p
->pc_count
;
2900 else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
2901 h
->dyn_relocs
= NULL
;
2905 /* For the non-shared case, discard space for relocs against
2906 symbols which turn out to need copy relocs or are not
2912 || (htab
->elf
.dynamic_sections_created
2913 && (h
->root
.type
== bfd_link_hash_undefweak
2914 || h
->root
.type
== bfd_link_hash_undefined
))))
2916 /* Make sure this symbol is output as a dynamic symbol.
2917 Undefined weak syms won't yet be marked as dynamic. */
2918 if (h
->dynindx
== -1
2919 && !h
->forced_local
)
2921 if (! bfd_elf_link_record_dynamic_symbol (info
, h
))
2925 /* If that succeeded, we know we'll be keeping all the
2927 if (h
->dynindx
!= -1)
2931 h
->dyn_relocs
= NULL
;
2936 /* Finally, allocate space. */
2937 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
2939 asection
*sreloc
= elf_section_data (p
->sec
)->sreloc
;
2940 sreloc
->size
+= p
->count
* sizeof (Elf32_External_Rela
);
2946 /* Set the sizes of the dynamic sections. */
2949 microblaze_elf_size_dynamic_sections (bfd
*output_bfd ATTRIBUTE_UNUSED
,
2950 struct bfd_link_info
*info
)
2952 struct elf32_mb_link_hash_table
*htab
;
2957 htab
= elf32_mb_hash_table (info
);
2961 dynobj
= htab
->elf
.dynobj
;
2962 BFD_ASSERT (dynobj
!= NULL
);
2964 /* Set up .got offsets for local syms, and space for local dynamic
2966 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
2968 bfd_signed_vma
*local_got
;
2969 bfd_signed_vma
*end_local_got
;
2970 bfd_size_type locsymcount
;
2971 Elf_Internal_Shdr
*symtab_hdr
;
2972 unsigned char *lgot_masks
;
2975 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
)
2978 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
2980 struct elf_dyn_relocs
*p
;
2982 for (p
= ((struct elf_dyn_relocs
*)
2983 elf_section_data (s
)->local_dynrel
);
2987 if (!bfd_is_abs_section (p
->sec
)
2988 && bfd_is_abs_section (p
->sec
->output_section
))
2990 /* Input section has been discarded, either because
2991 it is a copy of a linkonce section or due to
2992 linker script /DISCARD/, so we'll be discarding
2995 else if (p
->count
!= 0)
2997 srel
= elf_section_data (p
->sec
)->sreloc
;
2998 srel
->size
+= p
->count
* sizeof (Elf32_External_Rela
);
2999 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
3000 info
->flags
|= DF_TEXTREL
;
3005 local_got
= elf_local_got_refcounts (ibfd
);
3009 symtab_hdr
= &elf_tdata (ibfd
)->symtab_hdr
;
3010 locsymcount
= symtab_hdr
->sh_info
;
3011 end_local_got
= local_got
+ locsymcount
;
3012 lgot_masks
= (unsigned char *) end_local_got
;
3014 srel
= htab
->elf
.srelgot
;
3016 for (; local_got
< end_local_got
; ++local_got
, ++lgot_masks
)
3020 unsigned int need
= 0;
3021 if ((*lgot_masks
& TLS_TLS
) != 0)
3023 if ((*lgot_masks
& TLS_GD
) != 0)
3025 if ((*lgot_masks
& TLS_LD
) != 0)
3026 htab
->tlsld_got
.refcount
+= 1;
3033 *local_got
= (bfd_vma
) -1;
3037 *local_got
= s
->size
;
3039 if (bfd_link_pic (info
))
3040 srel
->size
+= need
* (sizeof (Elf32_External_Rela
) / 4);
3044 *local_got
= (bfd_vma
) -1;
3048 /* Allocate global sym .plt and .got entries, and space for global
3049 sym dynamic relocs. */
3050 elf_link_hash_traverse (elf_hash_table (info
), allocate_dynrelocs
, info
);
3052 if (htab
->tlsld_got
.refcount
> 0)
3054 htab
->tlsld_got
.offset
= htab
->elf
.sgot
->size
;
3055 htab
->elf
.sgot
->size
+= 8;
3056 if (bfd_link_pic (info
))
3057 htab
->elf
.srelgot
->size
+= sizeof (Elf32_External_Rela
);
3060 htab
->tlsld_got
.offset
= (bfd_vma
) -1;
3062 if (elf_hash_table (info
)->dynamic_sections_created
)
3064 /* Make space for the trailing nop in .plt. */
3065 if (htab
->elf
.splt
->size
> 0)
3066 htab
->elf
.splt
->size
+= 4;
3069 /* The check_relocs and adjust_dynamic_symbol entry points have
3070 determined the sizes of the various dynamic sections. Allocate
3072 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
3077 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
3080 /* It's OK to base decisions on the section name, because none
3081 of the dynobj section names depend upon the input files. */
3082 name
= bfd_section_name (s
);
3084 if (startswith (name
, ".rela"))
3088 /* If we don't need this section, strip it from the
3089 output file. This is to handle .rela.bss and
3090 .rela.plt. We must create it in
3091 create_dynamic_sections, because it must be created
3092 before the linker maps input sections to output
3093 sections. The linker does that before
3094 adjust_dynamic_symbol is called, and it is that
3095 function which decides whether anything needs to go
3096 into these sections. */
3101 /* We use the reloc_count field as a counter if we need
3102 to copy relocs into the output file. */
3106 else if (s
!= htab
->elf
.splt
3107 && s
!= htab
->elf
.sgot
3108 && s
!= htab
->elf
.sgotplt
3109 && s
!= htab
->elf
.sdynbss
3110 && s
!= htab
->elf
.sdynrelro
)
3112 /* It's not one of our sections, so don't allocate space. */
3118 s
->flags
|= SEC_EXCLUDE
;
3122 /* Allocate memory for the section contents. */
3123 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
3124 Unused entries should be reclaimed before the section's contents
3125 are written out, but at the moment this does not happen. Thus in
3126 order to prevent writing out garbage, we initialise the section's
3127 contents to zero. */
3128 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
3129 if (s
->contents
== NULL
&& s
->size
!= 0)
3133 /* ??? Force DF_BIND_NOW? */
3134 info
->flags
|= DF_BIND_NOW
;
3135 return _bfd_elf_add_dynamic_tags (output_bfd
, info
, true);
3138 /* Finish up dynamic symbol handling. We set the contents of various
3139 dynamic sections here. */
3142 microblaze_elf_finish_dynamic_symbol (bfd
*output_bfd
,
3143 struct bfd_link_info
*info
,
3144 struct elf_link_hash_entry
*h
,
3145 Elf_Internal_Sym
*sym
)
3147 struct elf32_mb_link_hash_table
*htab
;
3148 struct elf32_mb_link_hash_entry
*eh
= elf32_mb_hash_entry(h
);
3150 htab
= elf32_mb_hash_table (info
);
3154 if (h
->plt
.offset
!= (bfd_vma
) -1)
3159 Elf_Internal_Rela rela
;
3165 /* This symbol has an entry in the procedure linkage table. Set
3167 BFD_ASSERT (h
->dynindx
!= -1);
3169 splt
= htab
->elf
.splt
;
3170 srela
= htab
->elf
.srelplt
;
3171 sgotplt
= htab
->elf
.sgotplt
;
3172 BFD_ASSERT (splt
!= NULL
&& srela
!= NULL
&& sgotplt
!= NULL
);
3174 plt_index
= h
->plt
.offset
/ PLT_ENTRY_SIZE
- 1; /* first entry reserved. */
3175 got_offset
= (plt_index
+ 3) * 4; /* 3 reserved ??? */
3176 got_addr
= got_offset
;
3178 /* For non-PIC objects we need absolute address of the GOT entry. */
3179 if (!bfd_link_pic (info
))
3180 got_addr
+= sgotplt
->output_section
->vma
+ sgotplt
->output_offset
;
3182 /* Fill in the entry in the procedure linkage table. */
3183 bfd_put_32 (output_bfd
, PLT_ENTRY_WORD_0
+ ((got_addr
>> 16) & 0xffff),
3184 splt
->contents
+ h
->plt
.offset
);
3185 if (bfd_link_pic (info
))
3186 bfd_put_32 (output_bfd
, PLT_ENTRY_WORD_1
+ (got_addr
& 0xffff),
3187 splt
->contents
+ h
->plt
.offset
+ 4);
3189 bfd_put_32 (output_bfd
, PLT_ENTRY_WORD_1_NOPIC
+ (got_addr
& 0xffff),
3190 splt
->contents
+ h
->plt
.offset
+ 4);
3191 bfd_put_32 (output_bfd
, (bfd_vma
) PLT_ENTRY_WORD_2
,
3192 splt
->contents
+ h
->plt
.offset
+ 8);
3193 bfd_put_32 (output_bfd
, (bfd_vma
) PLT_ENTRY_WORD_3
,
3194 splt
->contents
+ h
->plt
.offset
+ 12);
3196 /* Any additions to the .got section??? */
3197 /* bfd_put_32 (output_bfd,
3198 splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
3199 sgotplt->contents + got_offset); */
3201 /* Fill in the entry in the .rela.plt section. */
3202 rela
.r_offset
= (sgotplt
->output_section
->vma
3203 + sgotplt
->output_offset
3205 rela
.r_info
= ELF32_R_INFO (h
->dynindx
, R_MICROBLAZE_JUMP_SLOT
);
3207 loc
= srela
->contents
;
3208 loc
+= plt_index
* sizeof (Elf32_External_Rela
);
3209 bfd_elf32_swap_reloca_out (output_bfd
, &rela
, loc
);
3211 if (!h
->def_regular
)
3213 /* Mark the symbol as undefined, rather than as defined in
3214 the .plt section. Zero the value. */
3215 sym
->st_shndx
= SHN_UNDEF
;
3220 /* h->got.refcount to be checked ? */
3221 if (h
->got
.offset
!= (bfd_vma
) -1 &&
3222 ! ((h
->got
.offset
& 1) ||
3223 IS_TLS_LD(eh
->tls_mask
) || IS_TLS_GD(eh
->tls_mask
)))
3229 /* This symbol has an entry in the global offset table. Set it
3232 sgot
= htab
->elf
.sgot
;
3233 srela
= htab
->elf
.srelgot
;
3234 BFD_ASSERT (sgot
!= NULL
&& srela
!= NULL
);
3236 offset
= (sgot
->output_section
->vma
+ sgot
->output_offset
3237 + (h
->got
.offset
&~ (bfd_vma
) 1));
3239 /* If this is a -Bsymbolic link, and the symbol is defined
3240 locally, we just want to emit a RELATIVE reloc. Likewise if
3241 the symbol was forced to be local because of a version file.
3242 The entry in the global offset table will already have been
3243 initialized in the relocate_section function. */
3244 if (bfd_link_pic (info
)
3245 && ((info
->symbolic
&& h
->def_regular
)
3246 || h
->dynindx
== -1))
3248 asection
*sec
= h
->root
.u
.def
.section
;
3251 value
= h
->root
.u
.def
.value
;
3252 if (sec
->output_section
!= NULL
)
3253 /* PR 21180: If the output section is NULL, then the symbol is no
3254 longer needed, and in theory the GOT entry is redundant. But
3255 it is too late to change our minds now... */
3256 value
+= sec
->output_section
->vma
+ sec
->output_offset
;
3258 microblaze_elf_output_dynamic_relocation (output_bfd
,
3259 srela
, srela
->reloc_count
++,
3261 R_MICROBLAZE_REL
, offset
,
3266 microblaze_elf_output_dynamic_relocation (output_bfd
,
3267 srela
, srela
->reloc_count
++,
3269 R_MICROBLAZE_GLOB_DAT
,
3273 bfd_put_32 (output_bfd
, (bfd_vma
) 0,
3274 sgot
->contents
+ (h
->got
.offset
&~ (bfd_vma
) 1));
3280 Elf_Internal_Rela rela
;
3283 /* This symbols needs a copy reloc. Set it up. */
3285 BFD_ASSERT (h
->dynindx
!= -1);
3287 rela
.r_offset
= (h
->root
.u
.def
.value
3288 + h
->root
.u
.def
.section
->output_section
->vma
3289 + h
->root
.u
.def
.section
->output_offset
);
3290 rela
.r_info
= ELF32_R_INFO (h
->dynindx
, R_MICROBLAZE_COPY
);
3292 if (h
->root
.u
.def
.section
== htab
->elf
.sdynrelro
)
3293 s
= htab
->elf
.sreldynrelro
;
3295 s
= htab
->elf
.srelbss
;
3296 loc
= s
->contents
+ s
->reloc_count
++ * sizeof (Elf32_External_Rela
);
3297 bfd_elf32_swap_reloca_out (output_bfd
, &rela
, loc
);
3300 /* Mark some specially defined symbols as absolute. */
3301 if (h
== htab
->elf
.hdynamic
3302 || h
== htab
->elf
.hgot
3303 || h
== htab
->elf
.hplt
)
3304 sym
->st_shndx
= SHN_ABS
;
3310 /* Finish up the dynamic sections. */
3313 microblaze_elf_finish_dynamic_sections (bfd
*output_bfd
,
3314 struct bfd_link_info
*info
)
3317 asection
*sdyn
, *sgot
;
3318 struct elf32_mb_link_hash_table
*htab
;
3320 htab
= elf32_mb_hash_table (info
);
3324 dynobj
= htab
->elf
.dynobj
;
3326 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
3328 if (htab
->elf
.dynamic_sections_created
)
3331 Elf32_External_Dyn
*dyncon
, *dynconend
;
3333 dyncon
= (Elf32_External_Dyn
*) sdyn
->contents
;
3334 dynconend
= (Elf32_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
3335 for (; dyncon
< dynconend
; dyncon
++)
3337 Elf_Internal_Dyn dyn
;
3341 bfd_elf32_swap_dyn_in (dynobj
, dyncon
, &dyn
);
3346 s
= htab
->elf
.sgotplt
;
3351 s
= htab
->elf
.srelplt
;
3356 s
= htab
->elf
.srelplt
;
3369 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
3371 dyn
.d_un
.d_val
= s
->size
;
3373 bfd_elf32_swap_dyn_out (output_bfd
, &dyn
, dyncon
);
3376 splt
= htab
->elf
.splt
;
3377 BFD_ASSERT (splt
!= NULL
&& sdyn
!= NULL
);
3379 /* Clear the first entry in the procedure linkage table,
3380 and put a nop in the last four bytes. */
3383 memset (splt
->contents
, 0, PLT_ENTRY_SIZE
);
3384 bfd_put_32 (output_bfd
, (bfd_vma
) 0x80000000 /* nop. */,
3385 splt
->contents
+ splt
->size
- 4);
3387 if (splt
->output_section
!= bfd_abs_section_ptr
)
3388 elf_section_data (splt
->output_section
)->this_hdr
.sh_entsize
= 4;
3392 /* Set the first entry in the global offset table to the address of
3393 the dynamic section. */
3394 sgot
= htab
->elf
.sgotplt
;
3395 if (sgot
&& sgot
->size
> 0)
3398 bfd_put_32 (output_bfd
, (bfd_vma
) 0, sgot
->contents
);
3400 bfd_put_32 (output_bfd
,
3401 sdyn
->output_section
->vma
+ sdyn
->output_offset
,
3403 elf_section_data (sgot
->output_section
)->this_hdr
.sh_entsize
= 4;
3406 if (htab
->elf
.sgot
&& htab
->elf
.sgot
->size
> 0)
3407 elf_section_data (htab
->elf
.sgot
->output_section
)->this_hdr
.sh_entsize
= 4;
3412 /* Hook called by the linker routine which adds symbols from an object
3413 file. We use it to put .comm items in .sbss, and not .bss. */
3416 microblaze_elf_add_symbol_hook (bfd
*abfd
,
3417 struct bfd_link_info
*info
,
3418 Elf_Internal_Sym
*sym
,
3419 const char **namep ATTRIBUTE_UNUSED
,
3420 flagword
*flagsp ATTRIBUTE_UNUSED
,
3424 if (sym
->st_shndx
== SHN_COMMON
3425 && !bfd_link_relocatable (info
)
3426 && sym
->st_size
<= elf_gp_size (abfd
))
3428 /* Common symbols less than or equal to -G nn bytes are automatically
3430 *secp
= bfd_make_section_old_way (abfd
, ".sbss");
3432 || !bfd_set_section_flags (*secp
, SEC_IS_COMMON
| SEC_SMALL_DATA
))
3435 *valp
= sym
->st_size
;
3441 #define TARGET_LITTLE_SYM microblaze_elf32_le_vec
3442 #define TARGET_LITTLE_NAME "elf32-microblazeel"
3444 #define TARGET_BIG_SYM microblaze_elf32_vec
3445 #define TARGET_BIG_NAME "elf32-microblaze"
3447 #define ELF_ARCH bfd_arch_microblaze
3448 #define ELF_TARGET_ID MICROBLAZE_ELF_DATA
3449 #define ELF_MACHINE_CODE EM_MICROBLAZE
3450 #define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
3451 #define ELF_MAXPAGESIZE 0x1000
3452 #define elf_info_to_howto microblaze_elf_info_to_howto
3453 #define elf_info_to_howto_rel NULL
3455 #define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
3456 #define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name
3457 #define bfd_elf32_new_section_hook microblaze_elf_new_section_hook
3458 #define elf_backend_relocate_section microblaze_elf_relocate_section
3459 #define bfd_elf32_bfd_relax_section microblaze_elf_relax_section
3460 #define bfd_elf32_bfd_merge_private_bfd_data _bfd_generic_verify_endian_match
3461 #define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
3463 #define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
3464 #define elf_backend_check_relocs microblaze_elf_check_relocs
3465 #define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
3466 #define bfd_elf32_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
3467 #define elf_backend_can_gc_sections 1
3468 #define elf_backend_can_refcount 1
3469 #define elf_backend_want_got_plt 1
3470 #define elf_backend_plt_readonly 1
3471 #define elf_backend_got_header_size 12
3472 #define elf_backend_want_dynrelro 1
3473 #define elf_backend_rela_normal 1
3474 #define elf_backend_dtrel_excludes_plt 1
3476 #define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
3477 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
3478 #define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
3479 #define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
3480 #define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
3481 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
3483 #include "elf32-target.h"