1 /* Xilinx MicroBlaze-specific support for 32-bit ELF
3 Copyright (C) 2009-2025 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_32_NONE
, /* Type. */
180 2, /* Size (0 = byte, 1 = short, 2 = long). */
182 true, /* PC_relative. */
184 complain_overflow_bitfield
, /* Complain on overflow. */
185 NULL
, /* Special Function. */
186 "R_MICROBLAZE_32_NONE", /* Name. */
187 false, /* Partial Inplace. */
188 0, /* Source Mask. */
190 false), /* PC relative offset? */
192 /* This reloc does nothing. Used for relaxation. */
193 HOWTO (R_MICROBLAZE_64_NONE
, /* Type. */
197 true, /* PC_relative. */
199 complain_overflow_dont
, /* Complain on overflow. */
200 NULL
, /* Special Function. */
201 "R_MICROBLAZE_64_NONE",/* Name. */
202 false, /* Partial Inplace. */
203 0, /* Source Mask. */
205 false), /* PC relative offset? */
207 /* Symbol Op Symbol relocation. */
208 HOWTO (R_MICROBLAZE_32_SYM_OP_SYM
, /* Type. */
212 false, /* PC_relative. */
214 complain_overflow_bitfield
, /* Complain on overflow. */
215 bfd_elf_generic_reloc
,/* Special Function. */
216 "R_MICROBLAZE_32_SYM_OP_SYM", /* Name. */
217 false, /* Partial Inplace. */
218 0, /* Source Mask. */
219 0xffffffff, /* Dest Mask. */
220 false), /* PC relative offset? */
222 /* GNU extension to record C++ vtable hierarchy. */
223 HOWTO (R_MICROBLAZE_GNU_VTINHERIT
, /* Type. */
227 false, /* PC_relative. */
229 complain_overflow_dont
,/* Complain on overflow. */
230 NULL
, /* Special Function. */
231 "R_MICROBLAZE_GNU_VTINHERIT", /* Name. */
232 false, /* Partial Inplace. */
233 0, /* Source Mask. */
235 false), /* PC relative offset? */
237 /* GNU extension to record C++ vtable member usage. */
238 HOWTO (R_MICROBLAZE_GNU_VTENTRY
, /* Type. */
242 false, /* PC_relative. */
244 complain_overflow_dont
,/* Complain on overflow. */
245 _bfd_elf_rel_vtable_reloc_fn
, /* Special Function. */
246 "R_MICROBLAZE_GNU_VTENTRY", /* Name. */
247 false, /* Partial Inplace. */
248 0, /* Source Mask. */
250 false), /* PC relative offset? */
252 /* A 64 bit GOTPC relocation. Table-entry not really used. */
253 HOWTO (R_MICROBLAZE_GOTPC_64
, /* Type. */
257 true, /* PC_relative. */
259 complain_overflow_dont
, /* Complain on overflow. */
260 bfd_elf_generic_reloc
, /* Special Function. */
261 "R_MICROBLAZE_GOTPC_64", /* Name. */
262 false, /* Partial Inplace. */
263 0, /* Source Mask. */
264 0x0000ffff, /* Dest Mask. */
265 true), /* PC relative offset? */
267 /* A 64 bit TEXTPCREL relocation. Table-entry not really used. */
268 HOWTO (R_MICROBLAZE_TEXTPCREL_64
, /* Type. */
272 true, /* PC_relative. */
274 complain_overflow_dont
, /* Complain on overflow. */
275 bfd_elf_generic_reloc
, /* Special Function. */
276 "R_MICROBLAZE_TEXTPCREL_64", /* Name. */
277 false, /* Partial Inplace. */
278 0, /* Source Mask. */
279 0x0000ffff, /* Dest Mask. */
280 true), /* PC relative offset? */
282 /* A 64 bit GOT relocation. Table-entry not really used. */
283 HOWTO (R_MICROBLAZE_GOT_64
, /* Type. */
287 false, /* PC_relative. */
289 complain_overflow_dont
, /* Complain on overflow. */
290 bfd_elf_generic_reloc
,/* Special Function. */
291 "R_MICROBLAZE_GOT_64",/* Name. */
292 false, /* Partial Inplace. */
293 0, /* Source Mask. */
294 0x0000ffff, /* Dest Mask. */
295 false), /* PC relative offset? */
297 /* A 64 bit TEXTREL relocation. Table-entry not really used. */
298 HOWTO (R_MICROBLAZE_TEXTREL_64
, /* Type. */
302 false, /* PC_relative. */
304 complain_overflow_dont
, /* Complain on overflow. */
305 bfd_elf_generic_reloc
,/* Special Function. */
306 "R_MICROBLAZE_TEXTREL_64",/* Name. */
307 false, /* Partial Inplace. */
308 0, /* Source Mask. */
309 0x0000ffff, /* Dest Mask. */
310 false), /* PC relative offset? */
312 /* A 64 bit PLT relocation. Table-entry not really used. */
313 HOWTO (R_MICROBLAZE_PLT_64
, /* Type. */
317 true, /* PC_relative. */
319 complain_overflow_dont
, /* Complain on overflow. */
320 bfd_elf_generic_reloc
,/* Special Function. */
321 "R_MICROBLAZE_PLT_64",/* Name. */
322 false, /* Partial Inplace. */
323 0, /* Source Mask. */
324 0x0000ffff, /* Dest Mask. */
325 true), /* PC relative offset? */
327 /* Table-entry not really used. */
328 HOWTO (R_MICROBLAZE_REL
, /* Type. */
332 true, /* PC_relative. */
334 complain_overflow_dont
, /* Complain on overflow. */
335 bfd_elf_generic_reloc
,/* Special Function. */
336 "R_MICROBLAZE_REL", /* Name. */
337 false, /* Partial Inplace. */
338 0, /* Source Mask. */
339 0x0000ffff, /* Dest Mask. */
340 true), /* PC relative offset? */
342 /* Table-entry not really used. */
343 HOWTO (R_MICROBLAZE_JUMP_SLOT
,/* Type. */
347 true, /* PC_relative. */
349 complain_overflow_dont
, /* Complain on overflow. */
350 bfd_elf_generic_reloc
,/* Special Function. */
351 "R_MICROBLAZE_JUMP_SLOT", /* Name. */
352 false, /* Partial Inplace. */
353 0, /* Source Mask. */
354 0x0000ffff, /* Dest Mask. */
355 true), /* PC relative offset? */
357 /* Table-entry not really used. */
358 HOWTO (R_MICROBLAZE_GLOB_DAT
,/* Type. */
362 true, /* PC_relative. */
364 complain_overflow_dont
, /* Complain on overflow. */
365 bfd_elf_generic_reloc
,/* Special Function. */
366 "R_MICROBLAZE_GLOB_DAT", /* Name. */
367 false, /* Partial Inplace. */
368 0, /* Source Mask. */
369 0x0000ffff, /* Dest Mask. */
370 true), /* PC relative offset? */
372 /* A 64 bit GOT relative relocation. Table-entry not really used. */
373 HOWTO (R_MICROBLAZE_GOTOFF_64
, /* Type. */
377 false, /* PC_relative. */
379 complain_overflow_dont
, /* Complain on overflow. */
380 bfd_elf_generic_reloc
,/* Special Function. */
381 "R_MICROBLAZE_GOTOFF_64", /* Name. */
382 false, /* Partial Inplace. */
383 0, /* Source Mask. */
384 0x0000ffff, /* Dest Mask. */
385 false), /* PC relative offset? */
387 /* A 32 bit GOT relative relocation. Table-entry not really used. */
388 HOWTO (R_MICROBLAZE_GOTOFF_32
, /* Type. */
392 false, /* PC_relative. */
394 complain_overflow_dont
, /* Complain on overflow. */
395 bfd_elf_generic_reloc
, /* Special Function. */
396 "R_MICROBLAZE_GOTOFF_32", /* Name. */
397 false, /* Partial Inplace. */
398 0, /* Source Mask. */
399 0x0000ffff, /* Dest Mask. */
400 false), /* PC relative offset? */
402 /* COPY relocation. Table-entry not really used. */
403 HOWTO (R_MICROBLAZE_COPY
, /* Type. */
407 false, /* PC_relative. */
409 complain_overflow_dont
, /* Complain on overflow. */
410 bfd_elf_generic_reloc
,/* Special Function. */
411 "R_MICROBLAZE_COPY", /* Name. */
412 false, /* Partial Inplace. */
413 0, /* Source Mask. */
414 0x0000ffff, /* Dest Mask. */
415 false), /* PC relative offset? */
417 /* Marker relocs for TLS. */
418 HOWTO (R_MICROBLAZE_TLS
,
422 false, /* pc_relative */
424 complain_overflow_dont
, /* complain_on_overflow */
425 bfd_elf_generic_reloc
, /* special_function */
426 "R_MICROBLAZE_TLS", /* name */
427 false, /* partial_inplace */
429 0x0000ffff, /* dst_mask */
430 false), /* pcrel_offset */
432 HOWTO (R_MICROBLAZE_TLSGD
,
436 false, /* pc_relative */
438 complain_overflow_dont
, /* complain_on_overflow */
439 bfd_elf_generic_reloc
, /* special_function */
440 "R_MICROBLAZE_TLSGD", /* name */
441 false, /* partial_inplace */
443 0x0000ffff, /* dst_mask */
444 false), /* pcrel_offset */
446 HOWTO (R_MICROBLAZE_TLSLD
,
450 false, /* pc_relative */
452 complain_overflow_dont
, /* complain_on_overflow */
453 bfd_elf_generic_reloc
, /* special_function */
454 "R_MICROBLAZE_TLSLD", /* name */
455 false, /* partial_inplace */
457 0x0000ffff, /* dst_mask */
458 false), /* pcrel_offset */
460 /* Computes the load module index of the load module that contains the
461 definition of its TLS sym. */
462 HOWTO (R_MICROBLAZE_TLSDTPMOD32
,
466 false, /* pc_relative */
468 complain_overflow_dont
, /* complain_on_overflow */
469 bfd_elf_generic_reloc
, /* special_function */
470 "R_MICROBLAZE_TLSDTPMOD32", /* name */
471 false, /* partial_inplace */
473 0x0000ffff, /* dst_mask */
474 false), /* pcrel_offset */
476 /* Computes a dtv-relative displacement, the difference between the value
477 of sym+add and the base address of the thread-local storage block that
478 contains the definition of sym, minus 0x8000. Used for initializing GOT */
479 HOWTO (R_MICROBLAZE_TLSDTPREL32
,
483 false, /* pc_relative */
485 complain_overflow_dont
, /* complain_on_overflow */
486 bfd_elf_generic_reloc
, /* special_function */
487 "R_MICROBLAZE_TLSDTPREL32", /* name */
488 false, /* partial_inplace */
490 0x0000ffff, /* dst_mask */
491 false), /* pcrel_offset */
493 /* Computes a dtv-relative displacement, the difference between the value
494 of sym+add and the base address of the thread-local storage block that
495 contains the definition of sym, minus 0x8000. */
496 HOWTO (R_MICROBLAZE_TLSDTPREL64
,
500 false, /* pc_relative */
502 complain_overflow_dont
, /* complain_on_overflow */
503 bfd_elf_generic_reloc
, /* special_function */
504 "R_MICROBLAZE_TLSDTPREL64", /* name */
505 false, /* partial_inplace */
507 0x0000ffff, /* dst_mask */
508 false), /* pcrel_offset */
510 /* Computes a tp-relative displacement, the difference between the value of
511 sym+add and the value of the thread pointer (r13). */
512 HOWTO (R_MICROBLAZE_TLSGOTTPREL32
,
516 false, /* pc_relative */
518 complain_overflow_dont
, /* complain_on_overflow */
519 bfd_elf_generic_reloc
, /* special_function */
520 "R_MICROBLAZE_TLSGOTTPREL32", /* name */
521 false, /* partial_inplace */
523 0x0000ffff, /* dst_mask */
524 false), /* pcrel_offset */
526 /* Computes a tp-relative displacement, the difference between the value of
527 sym+add and the value of the thread pointer (r13). */
528 HOWTO (R_MICROBLAZE_TLSTPREL32
,
532 false, /* pc_relative */
534 complain_overflow_dont
, /* complain_on_overflow */
535 bfd_elf_generic_reloc
, /* special_function */
536 "R_MICROBLAZE_TLSTPREL32", /* name */
537 false, /* partial_inplace */
539 0x0000ffff, /* dst_mask */
540 false), /* pcrel_offset */
545 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
548 /* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */
551 microblaze_elf_howto_init (void)
555 for (i
= NUM_ELEM (microblaze_elf_howto_raw
); i
--;)
559 type
= microblaze_elf_howto_raw
[i
].type
;
561 BFD_ASSERT (type
< NUM_ELEM (microblaze_elf_howto_table
));
563 microblaze_elf_howto_table
[type
] = & microblaze_elf_howto_raw
[i
];
567 static reloc_howto_type
*
568 microblaze_elf_reloc_type_lookup (bfd
* abfd ATTRIBUTE_UNUSED
,
569 bfd_reloc_code_real_type code
)
571 enum elf_microblaze_reloc_type microblaze_reloc
= R_MICROBLAZE_NONE
;
576 microblaze_reloc
= R_MICROBLAZE_NONE
;
578 case BFD_RELOC_MICROBLAZE_32_NONE
:
579 microblaze_reloc
= R_MICROBLAZE_32_NONE
;
581 case BFD_RELOC_MICROBLAZE_64_NONE
:
582 microblaze_reloc
= R_MICROBLAZE_64_NONE
;
585 microblaze_reloc
= R_MICROBLAZE_32
;
587 /* RVA is treated the same as 32 */
589 microblaze_reloc
= R_MICROBLAZE_32
;
591 case BFD_RELOC_32_PCREL
:
592 microblaze_reloc
= R_MICROBLAZE_32_PCREL
;
594 case BFD_RELOC_64_PCREL
:
595 microblaze_reloc
= R_MICROBLAZE_64_PCREL
;
597 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
598 microblaze_reloc
= R_MICROBLAZE_32_PCREL_LO
;
601 microblaze_reloc
= R_MICROBLAZE_64
;
603 case BFD_RELOC_MICROBLAZE_32_LO
:
604 microblaze_reloc
= R_MICROBLAZE_32_LO
;
606 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
607 microblaze_reloc
= R_MICROBLAZE_SRO32
;
609 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
610 microblaze_reloc
= R_MICROBLAZE_SRW32
;
612 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
613 microblaze_reloc
= R_MICROBLAZE_32_SYM_OP_SYM
;
615 case BFD_RELOC_VTABLE_INHERIT
:
616 microblaze_reloc
= R_MICROBLAZE_GNU_VTINHERIT
;
618 case BFD_RELOC_VTABLE_ENTRY
:
619 microblaze_reloc
= R_MICROBLAZE_GNU_VTENTRY
;
621 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
622 microblaze_reloc
= R_MICROBLAZE_GOTPC_64
;
624 case BFD_RELOC_MICROBLAZE_64_GOT
:
625 microblaze_reloc
= R_MICROBLAZE_GOT_64
;
627 case BFD_RELOC_MICROBLAZE_64_TEXTPCREL
:
628 microblaze_reloc
= R_MICROBLAZE_TEXTPCREL_64
;
630 case BFD_RELOC_MICROBLAZE_64_TEXTREL
:
631 microblaze_reloc
= R_MICROBLAZE_TEXTREL_64
;
633 case BFD_RELOC_MICROBLAZE_64_PLT
:
634 microblaze_reloc
= R_MICROBLAZE_PLT_64
;
636 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
637 microblaze_reloc
= R_MICROBLAZE_GOTOFF_64
;
639 case BFD_RELOC_MICROBLAZE_32_GOTOFF
:
640 microblaze_reloc
= R_MICROBLAZE_GOTOFF_32
;
642 case BFD_RELOC_MICROBLAZE_64_TLSGD
:
643 microblaze_reloc
= R_MICROBLAZE_TLSGD
;
645 case BFD_RELOC_MICROBLAZE_64_TLSLD
:
646 microblaze_reloc
= R_MICROBLAZE_TLSLD
;
648 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL
:
649 microblaze_reloc
= R_MICROBLAZE_TLSDTPREL32
;
651 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL
:
652 microblaze_reloc
= R_MICROBLAZE_TLSDTPREL64
;
654 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
:
655 microblaze_reloc
= R_MICROBLAZE_TLSDTPMOD32
;
657 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
:
658 microblaze_reloc
= R_MICROBLAZE_TLSGOTTPREL32
;
660 case BFD_RELOC_MICROBLAZE_64_TLSTPREL
:
661 microblaze_reloc
= R_MICROBLAZE_TLSTPREL32
;
663 case BFD_RELOC_MICROBLAZE_COPY
:
664 microblaze_reloc
= R_MICROBLAZE_COPY
;
667 return (reloc_howto_type
*) NULL
;
670 if (!microblaze_elf_howto_table
[R_MICROBLAZE_32
])
671 /* Initialize howto table if needed. */
672 microblaze_elf_howto_init ();
674 return microblaze_elf_howto_table
[(int) microblaze_reloc
];
677 static reloc_howto_type
*
678 microblaze_elf_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
683 for (i
= 0; i
< NUM_ELEM (microblaze_elf_howto_raw
); i
++)
684 if (microblaze_elf_howto_raw
[i
].name
!= NULL
685 && strcasecmp (microblaze_elf_howto_raw
[i
].name
, r_name
) == 0)
686 return µblaze_elf_howto_raw
[i
];
691 /* Set the howto pointer for a RCE ELF reloc. */
694 microblaze_elf_info_to_howto (bfd
* abfd
,
696 Elf_Internal_Rela
* dst
)
700 if (!microblaze_elf_howto_table
[R_MICROBLAZE_32
])
701 /* Initialize howto table if needed. */
702 microblaze_elf_howto_init ();
704 r_type
= ELF32_R_TYPE (dst
->r_info
);
705 if (r_type
>= R_MICROBLAZE_max
)
707 /* xgettext:c-format */
708 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
710 bfd_set_error (bfd_error_bad_value
);
714 cache_ptr
->howto
= microblaze_elf_howto_table
[r_type
];
718 /* Relax table contains information about instructions which can
719 be removed by relaxation -- replacing a long address with a
723 /* Address where bytes may be deleted. */
726 /* Number of bytes to be deleted. */
730 struct _microblaze_elf_section_data
732 struct bfd_elf_section_data elf
;
733 /* Count of used relaxation table entries. */
735 /* Relaxation table. */
736 struct relax_table
*relax
;
739 #define microblaze_elf_section_data(sec) \
740 ((struct _microblaze_elf_section_data *) elf_section_data (sec))
743 microblaze_elf_new_section_hook (bfd
*abfd
, asection
*sec
)
745 struct _microblaze_elf_section_data
*sdata
;
747 sdata
= bfd_zalloc (abfd
, sizeof (*sdata
));
750 sec
->used_by_bfd
= sdata
;
752 return _bfd_elf_new_section_hook (abfd
, sec
);
755 /* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
758 microblaze_elf_is_local_label_name (bfd
*abfd
, const char *name
)
760 if (name
[0] == 'L' && name
[1] == '.')
763 if (name
[0] == '$' && name
[1] == 'L')
766 /* With gcc, the labels go back to starting with '.', so we accept
767 the generic ELF local label syntax as well. */
768 return _bfd_elf_is_local_label_name (abfd
, name
);
771 /* ELF linker hash entry. */
773 struct elf32_mb_link_hash_entry
775 struct elf_link_hash_entry elf
;
777 /* TLS Reference Types for the symbol; Updated by check_relocs */
778 #define TLS_GD 1 /* GD reloc. */
779 #define TLS_LD 2 /* LD reloc. */
780 #define TLS_TPREL 4 /* TPREL reloc, => IE. */
781 #define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
782 #define TLS_TLS 16 /* Any TLS reloc. */
783 unsigned char tls_mask
;
787 #define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD))
788 #define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD))
789 #define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL))
790 #define IS_TLS_NONE(x) (x == 0)
792 #define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent))
794 /* ELF linker hash table. */
796 struct elf32_mb_link_hash_table
798 struct elf_link_hash_table elf
;
800 /* TLS Local Dynamic GOT Entry */
802 bfd_signed_vma refcount
;
807 /* Nonzero if this section has TLS related relocations. */
808 #define has_tls_reloc sec_flg0
810 /* Get the ELF linker hash table from a link_info structure. */
812 #define elf32_mb_hash_table(p) \
813 ((is_elf_hash_table ((p)->hash) \
814 && elf_hash_table_id (elf_hash_table (p)) == MICROBLAZE_ELF_DATA) \
815 ? (struct elf32_mb_link_hash_table *) (p)->hash : NULL)
817 /* Create an entry in a microblaze ELF linker hash table. */
819 static struct bfd_hash_entry
*
820 link_hash_newfunc (struct bfd_hash_entry
*entry
,
821 struct bfd_hash_table
*table
,
824 /* Allocate the structure if it has not already been allocated by a
828 entry
= bfd_hash_allocate (table
,
829 sizeof (struct elf32_mb_link_hash_entry
));
834 /* Call the allocation method of the superclass. */
835 entry
= _bfd_elf_link_hash_newfunc (entry
, table
, string
);
838 struct elf32_mb_link_hash_entry
*eh
;
840 eh
= (struct elf32_mb_link_hash_entry
*) entry
;
847 /* Create a mb ELF linker hash table. */
849 static struct bfd_link_hash_table
*
850 microblaze_elf_link_hash_table_create (bfd
*abfd
)
852 struct elf32_mb_link_hash_table
*ret
;
853 size_t amt
= sizeof (struct elf32_mb_link_hash_table
);
855 ret
= (struct elf32_mb_link_hash_table
*) bfd_zmalloc (amt
);
859 if (!_bfd_elf_link_hash_table_init (&ret
->elf
, abfd
, link_hash_newfunc
,
860 sizeof (struct elf32_mb_link_hash_entry
)))
866 return &ret
->elf
.root
;
869 /* Set the values of the small data pointers. */
872 microblaze_elf_final_sdp (struct bfd_link_info
*info
)
874 struct bfd_link_hash_entry
*h
;
876 h
= bfd_link_hash_lookup (info
->hash
, RO_SDA_ANCHOR_NAME
, false, false, true);
877 if (h
!= (struct bfd_link_hash_entry
*) NULL
878 && h
->type
== bfd_link_hash_defined
)
879 ro_small_data_pointer
= (h
->u
.def
.value
880 + h
->u
.def
.section
->output_section
->vma
881 + h
->u
.def
.section
->output_offset
);
883 h
= bfd_link_hash_lookup (info
->hash
, RW_SDA_ANCHOR_NAME
, false, false, true);
884 if (h
!= (struct bfd_link_hash_entry
*) NULL
885 && h
->type
== bfd_link_hash_defined
)
886 rw_small_data_pointer
= (h
->u
.def
.value
887 + h
->u
.def
.section
->output_section
->vma
888 + h
->u
.def
.section
->output_offset
);
892 dtprel_base (struct bfd_link_info
*info
)
894 /* If tls_sec is NULL, we should have signalled an error already. */
895 if (elf_hash_table (info
)->tls_sec
== NULL
)
897 return elf_hash_table (info
)->tls_sec
->vma
;
900 /* The size of the thread control block. */
903 /* Output a simple dynamic relocation into SRELOC. */
906 microblaze_elf_output_dynamic_relocation (bfd
*output_bfd
,
908 unsigned long reloc_index
,
915 Elf_Internal_Rela rel
;
917 rel
.r_info
= ELF32_R_INFO (indx
, r_type
);
918 rel
.r_offset
= offset
;
919 rel
.r_addend
= addend
;
921 bfd_elf32_swap_reloca_out (output_bfd
, &rel
,
922 (sreloc
->contents
+ reloc_index
* sizeof (Elf32_External_Rela
)));
925 /* This code is taken from elf32-m32r.c
926 There is some attempt to make this function usable for many architectures,
927 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
928 if only to serve as a learning tool.
930 The RELOCATE_SECTION function is called by the new ELF backend linker
931 to handle the relocations for a section.
933 The relocs are always passed as Rela structures; if the section
934 actually uses Rel structures, the r_addend field will always be
937 This function is responsible for adjust the section contents as
938 necessary, and (if using Rela relocs and generating a
939 relocatable output file) adjusting the reloc addend as
942 This function does not have to worry about setting the reloc
943 address or the reloc symbol index.
945 LOCAL_SYMS is a pointer to the swapped in local symbols.
947 LOCAL_SECTIONS is an array giving the section in the input file
948 corresponding to the st_shndx field of each local symbol.
950 The global hash table entry for the global symbols can be found
951 via elf_sym_hashes (input_bfd).
953 When generating relocatable output, this function must handle
954 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
955 going to be the section symbol corresponding to the output
956 section, which means that the addend must be adjusted
960 microblaze_elf_relocate_section (bfd
*output_bfd
,
961 struct bfd_link_info
*info
,
963 asection
*input_section
,
965 Elf_Internal_Rela
*relocs
,
966 Elf_Internal_Sym
*local_syms
,
967 asection
**local_sections
)
969 struct elf32_mb_link_hash_table
*htab
;
970 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
971 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
972 Elf_Internal_Rela
*rel
, *relend
;
973 int endian
= (bfd_little_endian (output_bfd
)) ? 0 : 2;
974 /* Assume success. */
977 bfd_vma
*local_got_offsets
;
978 unsigned int tls_type
;
980 if (!microblaze_elf_howto_table
[R_MICROBLAZE_max
-1])
981 microblaze_elf_howto_init ();
983 htab
= elf32_mb_hash_table (info
);
987 local_got_offsets
= elf_local_got_offsets (input_bfd
);
989 sreloc
= elf_section_data (input_section
)->sreloc
;
992 relend
= relocs
+ input_section
->reloc_count
;
993 for (; rel
< relend
; rel
++)
996 reloc_howto_type
*howto
;
997 unsigned long r_symndx
;
998 bfd_vma addend
= rel
->r_addend
;
999 bfd_vma offset
= rel
->r_offset
;
1000 struct elf_link_hash_entry
*h
;
1001 Elf_Internal_Sym
*sym
;
1003 const char *sym_name
;
1004 bfd_reloc_status_type r
= bfd_reloc_ok
;
1005 const char *errmsg
= NULL
;
1006 bool unresolved_reloc
= false;
1009 r_type
= ELF32_R_TYPE (rel
->r_info
);
1012 if (r_type
< 0 || r_type
>= (int) R_MICROBLAZE_max
)
1014 /* xgettext:c-format */
1015 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
1016 input_bfd
, (int) r_type
);
1017 bfd_set_error (bfd_error_bad_value
);
1022 howto
= microblaze_elf_howto_table
[r_type
];
1023 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1025 if (bfd_link_relocatable (info
))
1027 /* This is a relocatable link. We don't have to change
1028 anything, unless the reloc is against a section symbol,
1029 in which case we have to adjust according to where the
1030 section symbol winds up in the output section. */
1032 if (r_symndx
>= symtab_hdr
->sh_info
)
1033 /* External symbol. */
1037 sym
= local_syms
+ r_symndx
;
1038 sym_name
= "<local symbol>";
1039 /* STT_SECTION: symbol is associated with a section. */
1040 if (ELF_ST_TYPE (sym
->st_info
) != STT_SECTION
)
1041 /* Symbol isn't associated with a section. Nothing to do. */
1044 sec
= local_sections
[r_symndx
];
1045 addend
+= sec
->output_offset
+ sym
->st_value
;
1047 /* This can't be done for USE_REL because it doesn't mean anything
1048 and elf_link_input_bfd asserts this stays zero. */
1049 /* rel->r_addend = addend; */
1053 /* Addends are stored with relocs. We're done. */
1056 /* If partial_inplace, we need to store any additional addend
1057 back in the section. */
1058 if (!howto
->partial_inplace
)
1060 /* ??? Here is a nice place to call a special_function like handler. */
1061 r
= _bfd_relocate_contents (howto
, input_bfd
, addend
,
1063 #endif /* USE_REL */
1068 bool resolved_to_zero
;
1070 /* This is a final link. */
1073 unresolved_reloc
= false;
1075 if (r_symndx
< symtab_hdr
->sh_info
)
1078 sym
= local_syms
+ r_symndx
;
1079 sec
= local_sections
[r_symndx
];
1082 sym_name
= "<local symbol>";
1083 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
1084 /* r_addend may have changed if the reference section was
1086 addend
= rel
->r_addend
;
1090 /* External symbol. */
1091 bool warned ATTRIBUTE_UNUSED
;
1092 bool ignored ATTRIBUTE_UNUSED
;
1094 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
1095 r_symndx
, symtab_hdr
, sym_hashes
,
1097 unresolved_reloc
, warned
, ignored
);
1098 sym_name
= h
->root
.root
.string
;
1101 /* Sanity check the address. */
1102 if (offset
> bfd_get_section_limit (input_bfd
, input_section
))
1104 r
= bfd_reloc_outofrange
;
1108 resolved_to_zero
= (h
!= NULL
1109 && UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
));
1111 switch ((int) r_type
)
1113 case (int) R_MICROBLAZE_SRO32
:
1117 /* Only relocate if the symbol is defined. */
1120 name
= bfd_section_name (sec
);
1122 if (strcmp (name
, ".sdata2") == 0
1123 || strcmp (name
, ".sbss2") == 0)
1125 if (ro_small_data_pointer
== 0)
1126 microblaze_elf_final_sdp (info
);
1127 if (ro_small_data_pointer
== 0)
1130 r
= bfd_reloc_undefined
;
1134 /* At this point `relocation' contains the object's
1136 relocation
-= ro_small_data_pointer
;
1137 /* Now it contains the offset from _SDA2_BASE_. */
1138 r
= _bfd_final_link_relocate (howto
, input_bfd
,
1141 relocation
, addend
);
1146 /* xgettext:c-format */
1147 (_("%pB: the target (%s) of an %s relocation"
1148 " is in the wrong section (%pA)"),
1151 microblaze_elf_howto_table
[(int) r_type
]->name
,
1153 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1161 case (int) R_MICROBLAZE_SRW32
:
1165 /* Only relocate if the symbol is defined. */
1168 name
= bfd_section_name (sec
);
1170 if (strcmp (name
, ".sdata") == 0
1171 || strcmp (name
, ".sbss") == 0)
1173 if (rw_small_data_pointer
== 0)
1174 microblaze_elf_final_sdp (info
);
1175 if (rw_small_data_pointer
== 0)
1178 r
= bfd_reloc_undefined
;
1182 /* At this point `relocation' contains the object's
1184 relocation
-= rw_small_data_pointer
;
1185 /* Now it contains the offset from _SDA_BASE_. */
1186 r
= _bfd_final_link_relocate (howto
, input_bfd
,
1189 relocation
, addend
);
1194 /* xgettext:c-format */
1195 (_("%pB: the target (%s) of an %s relocation"
1196 " is in the wrong section (%pA)"),
1199 microblaze_elf_howto_table
[(int) r_type
]->name
,
1201 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1209 case (int) R_MICROBLAZE_32_SYM_OP_SYM
:
1210 break; /* Do nothing. */
1212 case (int) R_MICROBLAZE_GOTPC_64
:
1213 relocation
= (htab
->elf
.sgotplt
->output_section
->vma
1214 + htab
->elf
.sgotplt
->output_offset
);
1215 relocation
-= (input_section
->output_section
->vma
1216 + input_section
->output_offset
1217 + offset
+ INST_WORD_SIZE
);
1218 relocation
+= addend
;
1219 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1220 contents
+ offset
+ endian
);
1221 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1222 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1225 case (int) R_MICROBLAZE_TEXTPCREL_64
:
1226 relocation
= input_section
->output_section
->vma
;
1227 relocation
-= (input_section
->output_section
->vma
1228 + input_section
->output_offset
1229 + offset
+ INST_WORD_SIZE
);
1230 relocation
+= addend
;
1231 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1232 contents
+ offset
+ endian
);
1233 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1234 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1237 case (int) R_MICROBLAZE_PLT_64
:
1240 if (htab
->elf
.splt
!= NULL
&& h
!= NULL
1241 && h
->plt
.offset
!= (bfd_vma
) -1)
1243 relocation
= (htab
->elf
.splt
->output_section
->vma
1244 + htab
->elf
.splt
->output_offset
1246 unresolved_reloc
= false;
1247 immediate
= relocation
- (input_section
->output_section
->vma
1248 + input_section
->output_offset
1249 + offset
+ INST_WORD_SIZE
);
1250 bfd_put_16 (input_bfd
, (immediate
>> 16) & 0xffff,
1251 contents
+ offset
+ endian
);
1252 bfd_put_16 (input_bfd
, immediate
& 0xffff,
1253 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1257 relocation
-= (input_section
->output_section
->vma
1258 + input_section
->output_offset
1259 + offset
+ INST_WORD_SIZE
);
1260 immediate
= relocation
;
1261 bfd_put_16 (input_bfd
, (immediate
>> 16) & 0xffff,
1262 contents
+ offset
+ endian
);
1263 bfd_put_16 (input_bfd
, immediate
& 0xffff,
1264 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1269 case (int) R_MICROBLAZE_TLSGD
:
1270 tls_type
= (TLS_TLS
| TLS_GD
);
1272 case (int) R_MICROBLAZE_TLSLD
:
1273 tls_type
= (TLS_TLS
| TLS_LD
);
1276 case (int) R_MICROBLAZE_GOT_64
:
1281 bfd_vma static_value
;
1283 bool need_relocs
= false;
1284 if (htab
->elf
.sgot
== NULL
)
1290 /* 1. Identify GOT Offset;
1291 2. Compute Static Values
1292 3. Process Module Id, Process Offset
1293 4. Fixup Relocation with GOT offset value. */
1295 /* 1. Determine GOT Offset to use : TLS_LD, global, local */
1296 if (IS_TLS_LD (tls_type
))
1297 offp
= &htab
->tlsld_got
.offset
;
1300 if (htab
->elf
.sgotplt
!= NULL
1301 && h
->got
.offset
!= (bfd_vma
) -1)
1302 offp
= &h
->got
.offset
;
1308 if (local_got_offsets
== NULL
)
1310 offp
= &local_got_offsets
[r_symndx
];
1319 if (IS_TLS_LD(tls_type
) || IS_TLS_GD(tls_type
))
1322 /* Symbol index to use for relocs */
1326 elf_hash_table (info
)->dynamic_sections_created
;
1328 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
,
1329 bfd_link_pic (info
),
1331 && (!bfd_link_pic (info
)
1332 || !SYMBOL_REFERENCES_LOCAL (info
, h
)))
1336 /* Need to generate relocs ? */
1337 if ((bfd_link_pic (info
) || indx
!= 0)
1339 || (ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
1340 && !resolved_to_zero
)
1341 || h
->root
.type
!= bfd_link_hash_undefweak
))
1344 /* 2. Compute/Emit Static value of r-expression */
1345 static_value
= relocation
+ addend
;
1347 /* 3. Process module-id and offset */
1348 if (! ((*offp
) & 1) )
1352 got_offset
= (htab
->elf
.sgot
->output_section
->vma
1353 + htab
->elf
.sgot
->output_offset
1356 /* Process module-id */
1357 if (IS_TLS_LD(tls_type
))
1359 if (! bfd_link_pic (info
))
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= */ 0, R_MICROBLAZE_TLSDTPMOD32
,
1370 else if (IS_TLS_GD(tls_type
))
1373 bfd_put_32 (output_bfd
, 1,
1374 htab
->elf
.sgot
->contents
+ off
);
1376 microblaze_elf_output_dynamic_relocation
1379 htab
->elf
.srelgot
->reloc_count
++,
1380 /* symindex= */ indx
, R_MICROBLAZE_TLSDTPMOD32
,
1381 got_offset
, indx
? 0 : static_value
);
1384 /* Process Offset */
1385 if (htab
->elf
.srelgot
== NULL
)
1388 got_offset
= (htab
->elf
.sgot
->output_section
->vma
1389 + htab
->elf
.sgot
->output_offset
1391 if (IS_TLS_LD(tls_type
))
1393 /* For LD, offset should be 0 */
1395 bfd_put_32 (output_bfd
, 0,
1396 htab
->elf
.sgot
->contents
+ off2
);
1398 else if (IS_TLS_GD(tls_type
))
1401 static_value
-= dtprel_base(info
);
1403 microblaze_elf_output_dynamic_relocation
1406 htab
->elf
.srelgot
->reloc_count
++,
1407 /* symindex= */ indx
, R_MICROBLAZE_TLSDTPREL32
,
1408 got_offset
, indx
? 0 : static_value
);
1410 bfd_put_32 (output_bfd
, static_value
,
1411 htab
->elf
.sgot
->contents
+ off2
);
1415 bfd_put_32 (output_bfd
, static_value
,
1416 htab
->elf
.sgot
->contents
+ off2
);
1418 /* Relocs for dyn symbols generated by
1419 finish_dynamic_symbols */
1420 if (bfd_link_pic (info
) && h
== NULL
)
1423 microblaze_elf_output_dynamic_relocation
1426 htab
->elf
.srelgot
->reloc_count
++,
1427 /* symindex= */ indx
, R_MICROBLAZE_REL
,
1428 got_offset
, static_value
);
1433 /* 4. Fixup Relocation with GOT offset value
1434 Compute relative address of GOT entry for applying
1435 the current relocation */
1436 relocation
= htab
->elf
.sgot
->output_section
->vma
1437 + htab
->elf
.sgot
->output_offset
1439 - htab
->elf
.sgotplt
->output_section
->vma
1440 - htab
->elf
.sgotplt
->output_offset
;
1442 /* Apply Current Relocation */
1443 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1444 contents
+ offset
+ endian
);
1445 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1446 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1448 unresolved_reloc
= false;
1452 case (int) R_MICROBLAZE_GOTOFF_64
:
1455 unsigned short lo
, high
;
1456 relocation
+= addend
;
1457 relocation
-= (htab
->elf
.sgotplt
->output_section
->vma
1458 + htab
->elf
.sgotplt
->output_offset
);
1459 /* Write this value into correct location. */
1460 immediate
= relocation
;
1461 lo
= immediate
& 0x0000ffff;
1462 high
= (immediate
>> 16) & 0x0000ffff;
1463 bfd_put_16 (input_bfd
, high
, contents
+ offset
+ endian
);
1464 bfd_put_16 (input_bfd
, lo
,
1465 contents
+ offset
+ INST_WORD_SIZE
+ endian
);
1469 case (int) R_MICROBLAZE_GOTOFF_32
:
1471 relocation
+= addend
;
1472 relocation
-= (htab
->elf
.sgotplt
->output_section
->vma
1473 + htab
->elf
.sgotplt
->output_offset
);
1474 /* Write this value into correct location. */
1475 bfd_put_32 (input_bfd
, relocation
, contents
+ offset
);
1479 case (int) R_MICROBLAZE_TLSDTPREL64
:
1480 relocation
+= addend
;
1481 relocation
-= dtprel_base(info
);
1482 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1483 contents
+ offset
+ endian
);
1484 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1485 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1487 case (int) R_MICROBLAZE_TEXTREL_64
:
1488 case (int) R_MICROBLAZE_TEXTREL_32_LO
:
1489 case (int) R_MICROBLAZE_64_PCREL
:
1490 case (int) R_MICROBLAZE_64
:
1491 case (int) R_MICROBLAZE_32
:
1493 /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
1494 from removed linkonce sections, or sections discarded by
1496 if (r_symndx
== STN_UNDEF
|| (input_section
->flags
& SEC_ALLOC
) == 0)
1498 relocation
+= addend
;
1499 if (r_type
== R_MICROBLAZE_32
)
1500 bfd_put_32 (input_bfd
, relocation
, contents
+ offset
);
1503 if (r_type
== R_MICROBLAZE_64_PCREL
)
1504 relocation
-= (input_section
->output_section
->vma
1505 + input_section
->output_offset
1506 + offset
+ INST_WORD_SIZE
);
1507 else if (r_type
== R_MICROBLAZE_TEXTREL_64
1508 || r_type
== R_MICROBLAZE_TEXTREL_32_LO
)
1509 relocation
-= input_section
->output_section
->vma
;
1511 if (r_type
== R_MICROBLAZE_TEXTREL_32_LO
)
1512 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1513 contents
+ offset
+ endian
);
1517 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1518 contents
+ offset
+ endian
);
1519 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1520 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1526 if ((bfd_link_pic (info
)
1528 || (ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
1529 && !resolved_to_zero
)
1530 || h
->root
.type
!= bfd_link_hash_undefweak
)
1531 && (!howto
->pc_relative
1535 || !h
->def_regular
))))
1536 || (!bfd_link_pic (info
)
1542 || h
->root
.type
== bfd_link_hash_undefweak
1543 || h
->root
.type
== bfd_link_hash_undefined
)))
1545 Elf_Internal_Rela outrel
;
1549 /* When generating a shared object, these relocations
1550 are copied into the output file to be resolved at run
1553 BFD_ASSERT (sreloc
!= NULL
);
1558 _bfd_elf_section_offset (output_bfd
, info
, input_section
,
1560 if (outrel
.r_offset
== (bfd_vma
) -1)
1562 else if (outrel
.r_offset
== (bfd_vma
) -2)
1564 outrel
.r_offset
+= (input_section
->output_section
->vma
1565 + input_section
->output_offset
);
1568 memset (&outrel
, 0, sizeof outrel
);
1569 /* h->dynindx may be -1 if the symbol was marked to
1572 && ((! info
->symbolic
&& h
->dynindx
!= -1)
1573 || !h
->def_regular
))
1575 BFD_ASSERT (h
->dynindx
!= -1);
1576 outrel
.r_info
= ELF32_R_INFO (h
->dynindx
, r_type
);
1577 outrel
.r_addend
= addend
;
1581 if (r_type
== R_MICROBLAZE_32
)
1583 outrel
.r_info
= ELF32_R_INFO (0, R_MICROBLAZE_REL
);
1584 outrel
.r_addend
= relocation
+ addend
;
1590 (_("%pB: probably compiled without -fPIC?"),
1592 bfd_set_error (bfd_error_bad_value
);
1597 loc
= sreloc
->contents
;
1598 loc
+= sreloc
->reloc_count
++ * sizeof (Elf32_External_Rela
);
1599 bfd_elf32_swap_reloca_out (output_bfd
, &outrel
, loc
);
1604 relocation
+= addend
;
1605 if (r_type
== R_MICROBLAZE_32
)
1606 bfd_put_32 (input_bfd
, relocation
, contents
+ offset
);
1609 if (r_type
== R_MICROBLAZE_64_PCREL
)
1610 relocation
-= (input_section
->output_section
->vma
1611 + input_section
->output_offset
1612 + offset
+ INST_WORD_SIZE
);
1613 else if (r_type
== R_MICROBLAZE_TEXTREL_64
1614 || r_type
== R_MICROBLAZE_TEXTREL_32_LO
)
1615 relocation
-= input_section
->output_section
->vma
;
1617 if (r_type
== R_MICROBLAZE_TEXTREL_32_LO
)
1619 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1620 contents
+ offset
+ endian
);
1624 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1625 contents
+ offset
+ endian
);
1626 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1627 contents
+ offset
+ endian
1636 r
= _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
1638 relocation
, addend
);
1645 if (r
!= bfd_reloc_ok
)
1647 /* FIXME: This should be generic enough to go in a utility. */
1651 name
= h
->root
.root
.string
;
1654 name
= (bfd_elf_string_from_elf_section
1655 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
1656 if (name
== NULL
|| *name
== '\0')
1657 name
= bfd_section_name (sec
);
1665 case bfd_reloc_overflow
:
1666 (*info
->callbacks
->reloc_overflow
)
1667 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
,
1668 (bfd_vma
) 0, input_bfd
, input_section
, offset
);
1671 case bfd_reloc_undefined
:
1672 (*info
->callbacks
->undefined_symbol
)
1673 (info
, name
, input_bfd
, input_section
, offset
, true);
1676 case bfd_reloc_outofrange
:
1677 errmsg
= _("internal error: out of range error");
1680 case bfd_reloc_notsupported
:
1681 errmsg
= _("internal error: unsupported relocation error");
1684 case bfd_reloc_dangerous
:
1685 errmsg
= _("internal error: dangerous error");
1689 errmsg
= _("internal error: unknown error");
1692 (*info
->callbacks
->warning
) (info
, errmsg
, name
, input_bfd
,
1693 input_section
, offset
);
1702 /* Calculate fixup value for reference. */
1705 calc_fixup (bfd_vma start
, bfd_vma size
, asection
*sec
)
1707 bfd_vma end
= start
+ size
;
1708 size_t i
, fixup
= 0;
1709 struct _microblaze_elf_section_data
*sdata
;
1711 if (sec
== NULL
|| (sdata
= microblaze_elf_section_data (sec
)) == NULL
)
1714 /* Look for addr in relax table, total fixup value. */
1715 for (i
= 0; i
< sdata
->relax_count
; i
++)
1717 if (end
<= sdata
->relax
[i
].addr
)
1719 if (end
!= start
&& start
> sdata
->relax
[i
].addr
)
1721 fixup
+= sdata
->relax
[i
].size
;
1726 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1727 a 32-bit instruction. */
1729 microblaze_bfd_write_imm_value_32 (bfd
*abfd
, bfd_byte
*bfd_addr
, bfd_vma val
)
1731 unsigned long instr
= bfd_get_32 (abfd
, bfd_addr
);
1732 instr
&= ~0x0000ffff;
1733 instr
|= (val
& 0x0000ffff);
1734 bfd_put_32 (abfd
, instr
, bfd_addr
);
1737 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1738 two consecutive 32-bit instructions. */
1740 microblaze_bfd_write_imm_value_64 (bfd
*abfd
, bfd_byte
*bfd_addr
, bfd_vma val
)
1742 unsigned long instr_hi
;
1743 unsigned long instr_lo
;
1745 instr_hi
= bfd_get_32 (abfd
, bfd_addr
);
1746 instr_hi
&= ~0x0000ffff;
1747 instr_hi
|= ((val
>> 16) & 0x0000ffff);
1748 bfd_put_32 (abfd
, instr_hi
, bfd_addr
);
1750 instr_lo
= bfd_get_32 (abfd
, bfd_addr
+ INST_WORD_SIZE
);
1751 instr_lo
&= ~0x0000ffff;
1752 instr_lo
|= (val
& 0x0000ffff);
1753 bfd_put_32 (abfd
, instr_lo
, bfd_addr
+ INST_WORD_SIZE
);
1757 microblaze_elf_relax_section (bfd
*abfd
,
1759 struct bfd_link_info
*link_info
,
1762 Elf_Internal_Shdr
*symtab_hdr
;
1763 Elf_Internal_Rela
*internal_relocs
;
1764 Elf_Internal_Rela
*free_relocs
= NULL
;
1765 Elf_Internal_Rela
*irel
, *irelend
;
1766 bfd_byte
*contents
= NULL
;
1767 bfd_byte
*free_contents
= NULL
;
1770 size_t i
, sym_index
;
1772 struct elf_link_hash_entry
*sym_hash
;
1773 Elf_Internal_Sym
*isymbuf
, *isymend
;
1774 Elf_Internal_Sym
*isym
;
1778 struct _microblaze_elf_section_data
*sdata
;
1780 /* We only do this once per section. We may be able to delete some code
1781 by running multiple passes, but it is not worth it. */
1784 /* Only do this for a text section. */
1785 if (bfd_link_relocatable (link_info
)
1786 || (sec
->flags
& SEC_RELOC
) == 0
1787 || (sec
->flags
& SEC_CODE
) == 0
1788 || sec
->reloc_count
== 0
1789 || (sdata
= microblaze_elf_section_data (sec
)) == NULL
)
1792 BFD_ASSERT ((sec
->size
> 0) || (sec
->rawsize
> 0));
1794 /* If this is the first time we have been called for this section,
1795 initialize the cooked size. */
1797 sec
->size
= sec
->rawsize
;
1799 /* Get symbols for this section. */
1800 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1801 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1802 symcount
= symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
);
1803 if (isymbuf
== NULL
)
1804 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
, symcount
,
1805 0, NULL
, NULL
, NULL
);
1806 BFD_ASSERT (isymbuf
!= NULL
);
1808 internal_relocs
= _bfd_elf_link_read_relocs (abfd
, sec
, NULL
, NULL
, link_info
->keep_memory
);
1809 if (internal_relocs
== NULL
)
1811 if (! link_info
->keep_memory
)
1812 free_relocs
= internal_relocs
;
1814 sdata
->relax_count
= 0;
1815 sdata
->relax
= (struct relax_table
*) bfd_malloc ((sec
->reloc_count
+ 1)
1816 * sizeof (*sdata
->relax
));
1817 if (sdata
->relax
== NULL
)
1820 irelend
= internal_relocs
+ sec
->reloc_count
;
1822 for (irel
= internal_relocs
; irel
< irelend
; irel
++, rel_count
++)
1825 if ((ELF32_R_TYPE (irel
->r_info
) != (int) R_MICROBLAZE_64_PCREL
)
1826 && (ELF32_R_TYPE (irel
->r_info
) != (int) R_MICROBLAZE_64
)
1827 && (ELF32_R_TYPE (irel
->r_info
) != (int) R_MICROBLAZE_TEXTREL_64
))
1828 continue; /* Can't delete this reloc. */
1830 /* Get the section contents. */
1831 if (contents
== NULL
)
1833 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
1834 contents
= elf_section_data (sec
)->this_hdr
.contents
;
1837 contents
= (bfd_byte
*) bfd_malloc (sec
->size
);
1838 if (contents
== NULL
)
1840 free_contents
= contents
;
1842 if (!bfd_get_section_contents (abfd
, sec
, contents
,
1843 (file_ptr
) 0, sec
->size
))
1845 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1849 /* Get the value of the symbol referred to by the reloc. */
1850 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
1852 /* A local symbol. */
1855 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
1856 if (isym
->st_shndx
== SHN_UNDEF
)
1857 sym_sec
= bfd_und_section_ptr
;
1858 else if (isym
->st_shndx
== SHN_ABS
)
1859 sym_sec
= bfd_abs_section_ptr
;
1860 else if (isym
->st_shndx
== SHN_COMMON
)
1861 sym_sec
= bfd_com_section_ptr
;
1863 sym_sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
1865 symval
= _bfd_elf_rela_local_sym (abfd
, isym
, &sym_sec
, irel
);
1870 struct elf_link_hash_entry
*h
;
1872 indx
= ELF32_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
1873 h
= elf_sym_hashes (abfd
)[indx
];
1874 BFD_ASSERT (h
!= NULL
);
1876 if (h
->root
.type
!= bfd_link_hash_defined
1877 && h
->root
.type
!= bfd_link_hash_defweak
)
1878 /* This appears to be a reference to an undefined
1879 symbol. Just ignore it--it will be caught by the
1880 regular reloc processing. */
1883 symval
= (h
->root
.u
.def
.value
1884 + h
->root
.u
.def
.section
->output_section
->vma
1885 + h
->root
.u
.def
.section
->output_offset
);
1888 /* If this is a PC-relative reloc, subtract the instr offset from
1889 the symbol value. */
1890 if (ELF32_R_TYPE (irel
->r_info
) == (int) R_MICROBLAZE_64_PCREL
)
1892 symval
= symval
+ irel
->r_addend
1894 + sec
->output_section
->vma
1895 + sec
->output_offset
);
1897 else if (ELF32_R_TYPE (irel
->r_info
) == (int) R_MICROBLAZE_TEXTREL_64
)
1899 symval
= symval
+ irel
->r_addend
- (sec
->output_section
->vma
);
1902 symval
+= irel
->r_addend
;
1904 if ((symval
& 0xffff8000) == 0
1905 || (symval
& 0xffff8000) == 0xffff8000)
1907 /* We can delete this instruction. */
1908 sdata
->relax
[sdata
->relax_count
].addr
= irel
->r_offset
;
1909 sdata
->relax
[sdata
->relax_count
].size
= INST_WORD_SIZE
;
1910 sdata
->relax_count
++;
1912 /* Rewrite relocation type. */
1913 switch ((enum elf_microblaze_reloc_type
) ELF32_R_TYPE (irel
->r_info
))
1915 case R_MICROBLAZE_64_PCREL
:
1916 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1917 (int) R_MICROBLAZE_32_PCREL_LO
);
1919 case R_MICROBLAZE_64
:
1920 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1921 (int) R_MICROBLAZE_32_LO
);
1923 case R_MICROBLAZE_TEXTREL_64
:
1924 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1925 (int) R_MICROBLAZE_TEXTREL_32_LO
);
1928 /* Cannot happen. */
1932 } /* Loop through all relocations. */
1934 /* Loop through the relocs again, and see if anything needs to change. */
1935 if (sdata
->relax_count
> 0)
1937 shndx
= _bfd_elf_section_from_bfd_section (abfd
, sec
);
1939 sdata
->relax
[sdata
->relax_count
].addr
= sec
->size
;
1941 for (irel
= internal_relocs
; irel
< irelend
; irel
++, rel_count
++)
1945 /* Get the new reloc address. */
1946 nraddr
= irel
->r_offset
- calc_fixup (irel
->r_offset
, 0, sec
);
1947 switch ((enum elf_microblaze_reloc_type
) ELF32_R_TYPE (irel
->r_info
))
1951 case R_MICROBLAZE_64_PCREL
:
1953 case R_MICROBLAZE_TEXTREL_64
:
1954 case R_MICROBLAZE_TEXTREL_32_LO
:
1955 case R_MICROBLAZE_64
:
1956 case R_MICROBLAZE_32_LO
:
1957 /* If this reloc is against a symbol defined in this
1958 section, we must check the addend to see it will put the value in
1959 range to be adjusted, and hence must be changed. */
1960 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
1962 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
1963 /* Only handle relocs against .text. */
1964 if (isym
->st_shndx
== shndx
1965 && ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
)
1966 irel
->r_addend
-= calc_fixup (irel
->r_addend
, 0, sec
);
1969 case R_MICROBLAZE_NONE
:
1970 case R_MICROBLAZE_32_NONE
:
1972 /* This was a PC-relative instruction that was
1973 completely resolved. */
1975 bfd_vma target_address
;
1976 target_address
= irel
->r_addend
+ irel
->r_offset
;
1977 sfix
= calc_fixup (irel
->r_offset
, 0, sec
);
1978 efix
= calc_fixup (target_address
, 0, sec
);
1979 irel
->r_addend
-= (efix
- sfix
);
1980 /* Should use HOWTO. */
1981 microblaze_bfd_write_imm_value_32 (abfd
, contents
+ irel
->r_offset
,
1985 case R_MICROBLAZE_64_NONE
:
1987 /* This was a PC-relative 64-bit instruction that was
1988 completely resolved. */
1990 bfd_vma target_address
;
1991 target_address
= irel
->r_addend
+ irel
->r_offset
+ INST_WORD_SIZE
;
1992 sfix
= calc_fixup (irel
->r_offset
+ INST_WORD_SIZE
, 0, sec
);
1993 efix
= calc_fixup (target_address
, 0, sec
);
1994 irel
->r_addend
-= (efix
- sfix
);
1995 microblaze_bfd_write_imm_value_32 (abfd
, contents
+ irel
->r_offset
1996 + INST_WORD_SIZE
, irel
->r_addend
);
2000 irel
->r_offset
= nraddr
;
2001 } /* Change all relocs in this section. */
2003 /* Look through all other sections. */
2004 for (o
= abfd
->sections
; o
!= NULL
; o
= o
->next
)
2006 Elf_Internal_Rela
*irelocs
;
2007 Elf_Internal_Rela
*irelscan
, *irelscanend
;
2008 bfd_byte
*ocontents
;
2011 || (o
->flags
& SEC_RELOC
) == 0
2012 || o
->reloc_count
== 0)
2015 /* We always cache the relocs. Perhaps, if info->keep_memory is
2016 FALSE, we should free them, if we are permitted to. */
2018 irelocs
= _bfd_elf_link_read_relocs (abfd
, o
, NULL
, NULL
, true);
2019 if (irelocs
== NULL
)
2023 irelscanend
= irelocs
+ o
->reloc_count
;
2024 for (irelscan
= irelocs
; irelscan
< irelscanend
; irelscan
++)
2026 if ((ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32
)
2027 || (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32_NONE
))
2029 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2031 /* Look at the reloc only if the value has been resolved. */
2032 if (isym
->st_shndx
== shndx
2033 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2035 if (ocontents
== NULL
)
2037 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2038 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2041 /* We always cache the section contents.
2042 Perhaps, if info->keep_memory is FALSE, we
2043 should free them, if we are permitted to. */
2044 if (o
->rawsize
== 0)
2045 o
->rawsize
= o
->size
;
2046 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2047 if (ocontents
== NULL
)
2049 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2053 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2057 irelscan
->r_addend
-= calc_fixup (irelscan
->r_addend
, 0, sec
);
2059 else if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32_SYM_OP_SYM
)
2061 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2063 /* Look at the reloc only if the value has been resolved. */
2064 if (ocontents
== NULL
)
2066 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2067 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2070 /* We always cache the section contents.
2071 Perhaps, if info->keep_memory is FALSE, we
2072 should free them, if we are permitted to. */
2074 if (o
->rawsize
== 0)
2075 o
->rawsize
= o
->size
;
2076 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2077 if (ocontents
== NULL
)
2079 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2083 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2086 irelscan
->r_addend
-= calc_fixup (irelscan
->r_addend
2092 else if ((ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32_PCREL_LO
)
2093 || (ELF32_R_TYPE (irelscan
->r_info
)
2094 == (int) R_MICROBLAZE_32_LO
)
2095 || (ELF32_R_TYPE (irelscan
->r_info
)
2096 == (int) R_MICROBLAZE_TEXTREL_32_LO
))
2098 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2100 /* Look at the reloc only if the value has been resolved. */
2101 if (isym
->st_shndx
== shndx
2102 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2105 bfd_vma target_address
;
2107 if (ocontents
== NULL
)
2109 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2110 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2113 /* We always cache the section contents.
2114 Perhaps, if info->keep_memory is FALSE, we
2115 should free them, if we are permitted to. */
2116 if (o
->rawsize
== 0)
2117 o
->rawsize
= o
->size
;
2118 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2119 if (ocontents
== NULL
)
2121 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2125 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2129 unsigned long instr
= bfd_get_32 (abfd
, ocontents
+ irelscan
->r_offset
);
2130 immediate
= instr
& 0x0000ffff;
2131 target_address
= immediate
;
2132 offset
= calc_fixup (target_address
, 0, sec
);
2133 immediate
-= offset
;
2134 irelscan
->r_addend
-= offset
;
2135 microblaze_bfd_write_imm_value_32 (abfd
, ocontents
+ irelscan
->r_offset
,
2136 irelscan
->r_addend
);
2140 if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_64
2141 || (ELF32_R_TYPE (irelscan
->r_info
)
2142 == (int) R_MICROBLAZE_TEXTREL_64
))
2144 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2146 /* Look at the reloc only if the value has been resolved. */
2147 if (isym
->st_shndx
== shndx
2148 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2150 if (ocontents
== NULL
)
2152 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2153 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2156 /* We always cache the section contents.
2157 Perhaps, if info->keep_memory is FALSE, we
2158 should free them, if we are permitted to. */
2160 if (o
->rawsize
== 0)
2161 o
->rawsize
= o
->size
;
2162 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2163 if (ocontents
== NULL
)
2165 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2169 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2172 offset
= calc_fixup (irelscan
->r_addend
, 0, sec
);
2173 irelscan
->r_addend
-= offset
;
2176 else if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_64_PCREL
)
2178 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2180 /* Look at the reloc only if the value has been resolved. */
2181 if (isym
->st_shndx
== shndx
2182 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2185 bfd_vma target_address
;
2187 if (ocontents
== NULL
)
2189 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2190 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2193 /* We always cache the section contents.
2194 Perhaps, if info->keep_memory is FALSE, we
2195 should free them, if we are permitted to. */
2196 if (o
->rawsize
== 0)
2197 o
->rawsize
= o
->size
;
2198 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2199 if (ocontents
== NULL
)
2201 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2205 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2208 unsigned long instr_hi
= bfd_get_32 (abfd
, ocontents
2209 + irelscan
->r_offset
);
2210 unsigned long instr_lo
= bfd_get_32 (abfd
, ocontents
2211 + irelscan
->r_offset
2213 immediate
= (instr_hi
& 0x0000ffff) << 16;
2214 immediate
|= (instr_lo
& 0x0000ffff);
2215 target_address
= immediate
;
2216 offset
= calc_fixup (target_address
, 0, sec
);
2217 immediate
-= offset
;
2218 irelscan
->r_addend
-= offset
;
2219 microblaze_bfd_write_imm_value_64 (abfd
, ocontents
2220 + irelscan
->r_offset
, immediate
);
2226 /* Adjust the local symbols defined in this section. */
2227 isymend
= isymbuf
+ symtab_hdr
->sh_info
;
2228 for (isym
= isymbuf
; isym
< isymend
; isym
++)
2230 if (isym
->st_shndx
== shndx
)
2232 isym
->st_value
-= calc_fixup (isym
->st_value
, 0, sec
);
2234 isym
->st_size
-= calc_fixup (isym
->st_value
, isym
->st_size
, sec
);
2238 /* Now adjust the global symbols defined in this section. */
2239 isym
= isymbuf
+ symtab_hdr
->sh_info
;
2240 symcount
= (symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
)) - symtab_hdr
->sh_info
;
2241 for (sym_index
= 0; sym_index
< symcount
; sym_index
++)
2243 sym_hash
= elf_sym_hashes (abfd
)[sym_index
];
2244 if ((sym_hash
->root
.type
== bfd_link_hash_defined
2245 || sym_hash
->root
.type
== bfd_link_hash_defweak
)
2246 && sym_hash
->root
.u
.def
.section
== sec
)
2248 sym_hash
->root
.u
.def
.value
-= calc_fixup (sym_hash
->root
.u
.def
.value
,
2251 sym_hash
->size
-= calc_fixup (sym_hash
->root
.u
.def
.value
,
2252 sym_hash
->size
, sec
);
2256 /* Physically move the code and change the cooked size. */
2257 dest
= sdata
->relax
[0].addr
;
2258 for (i
= 0; i
< sdata
->relax_count
; i
++)
2261 src
= sdata
->relax
[i
].addr
+ sdata
->relax
[i
].size
;
2262 len
= (sdata
->relax
[i
+1].addr
- sdata
->relax
[i
].addr
2263 - sdata
->relax
[i
].size
);
2265 memmove (contents
+ dest
, contents
+ src
, len
);
2266 sec
->size
-= sdata
->relax
[i
].size
;
2270 elf_section_data (sec
)->relocs
= internal_relocs
;
2273 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2274 free_contents
= NULL
;
2276 symtab_hdr
->contents
= (bfd_byte
*) isymbuf
;
2282 if (free_contents
!= NULL
)
2284 if (!link_info
->keep_memory
)
2285 free (free_contents
);
2287 /* Cache the section contents for elf_link_input_bfd. */
2288 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2289 free_contents
= NULL
;
2292 if (sdata
->relax_count
== 0)
2295 free (sdata
->relax
);
2296 sdata
->relax
= NULL
;
2304 free (free_contents
);
2305 free (sdata
->relax
);
2306 sdata
->relax
= NULL
;
2307 sdata
->relax_count
= 0;
2311 /* Return the section that should be marked against GC for a given
2315 microblaze_elf_gc_mark_hook (asection
*sec
,
2316 struct bfd_link_info
* info
,
2317 Elf_Internal_Rela
* rel
,
2318 struct elf_link_hash_entry
* h
,
2319 Elf_Internal_Sym
* sym
)
2322 switch (ELF32_R_TYPE (rel
->r_info
))
2324 case R_MICROBLAZE_GNU_VTINHERIT
:
2325 case R_MICROBLAZE_GNU_VTENTRY
:
2329 return _bfd_elf_gc_mark_hook (sec
, info
, rel
, h
, sym
);
2334 #define PLT_ENTRY_SIZE 16
2336 #define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
2337 #define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
2338 #define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
2339 #define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
2340 #define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
2343 update_local_sym_info (bfd
*abfd
,
2344 Elf_Internal_Shdr
*symtab_hdr
,
2345 unsigned long r_symndx
,
2346 unsigned int tls_type
)
2348 bfd_signed_vma
*local_got_refcounts
= elf_local_got_refcounts (abfd
);
2349 unsigned char *local_got_tls_masks
;
2351 if (local_got_refcounts
== NULL
)
2353 bfd_size_type size
= symtab_hdr
->sh_info
;
2355 size
*= (sizeof (*local_got_refcounts
) + sizeof (*local_got_tls_masks
));
2356 local_got_refcounts
= bfd_zalloc (abfd
, size
);
2357 if (local_got_refcounts
== NULL
)
2359 elf_local_got_refcounts (abfd
) = local_got_refcounts
;
2362 local_got_tls_masks
=
2363 (unsigned char *) (local_got_refcounts
+ symtab_hdr
->sh_info
);
2364 local_got_tls_masks
[r_symndx
] |= tls_type
;
2365 local_got_refcounts
[r_symndx
] += 1;
2369 /* Look through the relocs for a section during the first phase. */
2372 microblaze_elf_check_relocs (bfd
* abfd
,
2373 struct bfd_link_info
* info
,
2375 const Elf_Internal_Rela
* relocs
)
2377 Elf_Internal_Shdr
* symtab_hdr
;
2378 struct elf_link_hash_entry
** sym_hashes
;
2379 const Elf_Internal_Rela
* rel
;
2380 const Elf_Internal_Rela
* rel_end
;
2381 struct elf32_mb_link_hash_table
*htab
;
2382 asection
*sreloc
= NULL
;
2384 if (bfd_link_relocatable (info
))
2387 htab
= elf32_mb_hash_table (info
);
2391 symtab_hdr
= & elf_tdata (abfd
)->symtab_hdr
;
2392 sym_hashes
= elf_sym_hashes (abfd
);
2394 rel_end
= relocs
+ sec
->reloc_count
;
2396 for (rel
= relocs
; rel
< rel_end
; rel
++)
2398 unsigned int r_type
;
2399 struct elf_link_hash_entry
* h
;
2400 unsigned long r_symndx
;
2401 unsigned char tls_type
= 0;
2403 r_symndx
= ELF32_R_SYM (rel
->r_info
);
2404 r_type
= ELF32_R_TYPE (rel
->r_info
);
2406 if (r_symndx
< symtab_hdr
->sh_info
)
2410 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
2411 while (h
->root
.type
== bfd_link_hash_indirect
2412 || h
->root
.type
== bfd_link_hash_warning
)
2413 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2418 /* This relocation describes the C++ object vtable hierarchy.
2419 Reconstruct it for later use during GC. */
2420 case R_MICROBLAZE_GNU_VTINHERIT
:
2421 if (!bfd_elf_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
2425 /* This relocation describes which C++ vtable entries are actually
2426 used. Record for later use during GC. */
2427 case R_MICROBLAZE_GNU_VTENTRY
:
2428 if (!bfd_elf_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
2432 /* This relocation requires .plt entry. */
2433 case R_MICROBLAZE_PLT_64
:
2437 h
->plt
.refcount
+= 1;
2441 /* This relocation requires .got entry. */
2442 case R_MICROBLAZE_TLSGD
:
2443 tls_type
|= (TLS_TLS
| TLS_GD
);
2445 case R_MICROBLAZE_TLSLD
:
2446 tls_type
|= (TLS_TLS
| TLS_LD
);
2449 sec
->has_tls_reloc
= 1;
2451 case R_MICROBLAZE_GOT_64
:
2452 if (htab
->elf
.sgot
== NULL
)
2454 if (htab
->elf
.dynobj
== NULL
)
2455 htab
->elf
.dynobj
= abfd
;
2456 if (!_bfd_elf_create_got_section (htab
->elf
.dynobj
, info
))
2461 h
->got
.refcount
+= 1;
2462 elf32_mb_hash_entry (h
)->tls_mask
|= tls_type
;
2466 if (! update_local_sym_info(abfd
, symtab_hdr
, r_symndx
, tls_type
) )
2471 case R_MICROBLAZE_GOTOFF_64
:
2472 case R_MICROBLAZE_GOTOFF_32
:
2473 if (htab
->elf
.sgot
== NULL
)
2475 if (htab
->elf
.dynobj
== NULL
)
2476 htab
->elf
.dynobj
= abfd
;
2477 if (!_bfd_elf_create_got_section (htab
->elf
.dynobj
, info
))
2482 case R_MICROBLAZE_64
:
2483 case R_MICROBLAZE_64_PCREL
:
2484 case R_MICROBLAZE_32
:
2486 if (h
!= NULL
&& !bfd_link_pic (info
))
2488 /* we may need a copy reloc. */
2491 /* we may also need a .plt entry. */
2492 h
->plt
.refcount
+= 1;
2493 if (ELF32_R_TYPE (rel
->r_info
) != R_MICROBLAZE_64_PCREL
)
2494 h
->pointer_equality_needed
= 1;
2498 /* If we are creating a shared library, and this is a reloc
2499 against a global symbol, or a non PC relative reloc
2500 against a local symbol, then we need to copy the reloc
2501 into the shared library. However, if we are linking with
2502 -Bsymbolic, we do not need to copy a reloc against a
2503 global symbol which is defined in an object we are
2504 including in the link (i.e., DEF_REGULAR is set). At
2505 this point we have not seen all the input files, so it is
2506 possible that DEF_REGULAR is not set now but will be set
2507 later (it is never cleared). In case of a weak definition,
2508 DEF_REGULAR may be cleared later by a strong definition in
2509 a shared library. We account for that possibility below by
2510 storing information in the relocs_copied field of the hash
2511 table entry. A similar situation occurs when creating
2512 shared libraries and symbol visibility changes render the
2515 If on the other hand, we are creating an executable, we
2516 may need to keep relocations for symbols satisfied by a
2517 dynamic library if we manage to avoid copy relocs for the
2520 if ((bfd_link_pic (info
)
2521 && (sec
->flags
& SEC_ALLOC
) != 0
2522 && (r_type
!= R_MICROBLAZE_64_PCREL
2524 && (! info
->symbolic
2525 || h
->root
.type
== bfd_link_hash_defweak
2526 || !h
->def_regular
))))
2527 || (!bfd_link_pic (info
)
2528 && (sec
->flags
& SEC_ALLOC
) != 0
2530 && (h
->root
.type
== bfd_link_hash_defweak
2531 || !h
->def_regular
)))
2533 struct elf_dyn_relocs
*p
;
2534 struct elf_dyn_relocs
**head
;
2536 /* When creating a shared object, we must copy these
2537 relocs into the output file. We create a reloc
2538 section in dynobj and make room for the reloc. */
2544 if (htab
->elf
.dynobj
== NULL
)
2545 htab
->elf
.dynobj
= abfd
;
2546 dynobj
= htab
->elf
.dynobj
;
2548 sreloc
= _bfd_elf_make_dynamic_reloc_section (sec
, dynobj
,
2554 /* If this is a global symbol, we count the number of
2555 relocations we need for this symbol. */
2557 head
= &h
->dyn_relocs
;
2560 /* Track dynamic relocs needed for local syms too.
2561 We really need local syms available to do this
2565 Elf_Internal_Sym
*isym
;
2568 isym
= bfd_sym_from_r_symndx (&htab
->elf
.sym_cache
,
2573 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
2577 vpp
= &elf_section_data (s
)->local_dynrel
;
2578 head
= (struct elf_dyn_relocs
**) vpp
;
2582 if (p
== NULL
|| p
->sec
!= sec
)
2584 size_t amt
= sizeof *p
;
2585 p
= ((struct elf_dyn_relocs
*)
2586 bfd_alloc (htab
->elf
.dynobj
, amt
));
2597 if (r_type
== R_MICROBLAZE_64_PCREL
)
2608 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2611 microblaze_elf_copy_indirect_symbol (struct bfd_link_info
*info
,
2612 struct elf_link_hash_entry
*dir
,
2613 struct elf_link_hash_entry
*ind
)
2615 struct elf32_mb_link_hash_entry
*edir
, *eind
;
2617 edir
= (struct elf32_mb_link_hash_entry
*) dir
;
2618 eind
= (struct elf32_mb_link_hash_entry
*) ind
;
2620 edir
->tls_mask
|= eind
->tls_mask
;
2622 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
2626 microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info
*info
,
2627 struct elf_link_hash_entry
*h
)
2629 struct elf32_mb_link_hash_table
*htab
;
2631 unsigned int power_of_two
;
2633 htab
= elf32_mb_hash_table (info
);
2637 /* If this is a function, put it in the procedure linkage table. We
2638 will fill in the contents of the procedure linkage table later,
2639 when we know the address of the .got section. */
2640 if (h
->type
== STT_FUNC
2643 if (h
->plt
.refcount
<= 0
2644 || SYMBOL_CALLS_LOCAL (info
, h
)
2645 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
2646 && h
->root
.type
== bfd_link_hash_undefweak
))
2648 /* This case can occur if we saw a PLT reloc in an input
2649 file, but the symbol was never referred to by a dynamic
2650 object, or if all references were garbage collected. In
2651 such a case, we don't actually need to build a procedure
2652 linkage table, and we can just do a PC32 reloc instead. */
2653 h
->plt
.offset
= (bfd_vma
) -1;
2660 /* It's possible that we incorrectly decided a .plt reloc was
2661 needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
2662 check_relocs. We can't decide accurately between function and
2663 non-function syms in check-relocs; Objects loaded later in
2664 the link may change h->type. So fix it now. */
2665 h
->plt
.offset
= (bfd_vma
) -1;
2667 /* If this is a weak symbol, and there is a real definition, the
2668 processor independent code will have arranged for us to see the
2669 real definition first, and we can just use the same value. */
2670 if (h
->is_weakalias
)
2672 struct elf_link_hash_entry
*def
= weakdef (h
);
2673 BFD_ASSERT (def
->root
.type
== bfd_link_hash_defined
);
2674 h
->root
.u
.def
.section
= def
->root
.u
.def
.section
;
2675 h
->root
.u
.def
.value
= def
->root
.u
.def
.value
;
2679 /* This is a reference to a symbol defined by a dynamic object which
2680 is not a function. */
2682 /* If we are creating a shared library, we must presume that the
2683 only references to the symbol are via the global offset table.
2684 For such cases we need not do anything here; the relocations will
2685 be handled correctly by relocate_section. */
2686 if (bfd_link_pic (info
))
2689 /* If there are no references to this symbol that do not use the
2690 GOT, we don't need to generate a copy reloc. */
2691 if (!h
->non_got_ref
)
2694 /* If -z nocopyreloc was given, we won't generate them either. */
2695 if (info
->nocopyreloc
)
2701 /* If we don't find any dynamic relocs in read-only sections, then
2702 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
2703 if (!_bfd_elf_readonly_dynrelocs (h
))
2709 /* We must allocate the symbol in our .dynbss section, which will
2710 become part of the .bss section of the executable. There will be
2711 an entry for this symbol in the .dynsym section. The dynamic
2712 object will contain position independent code, so all references
2713 from the dynamic object to this symbol will go through the global
2714 offset table. The dynamic linker will use the .dynsym entry to
2715 determine the address it must put in the global offset table, so
2716 both the dynamic object and the regular object will refer to the
2717 same memory location for the variable. */
2719 /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
2720 to copy the initial value out of the dynamic object and into the
2721 runtime process image. */
2722 if ((h
->root
.u
.def
.section
->flags
& SEC_READONLY
) != 0)
2724 s
= htab
->elf
.sdynrelro
;
2725 srel
= htab
->elf
.sreldynrelro
;
2729 s
= htab
->elf
.sdynbss
;
2730 srel
= htab
->elf
.srelbss
;
2732 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0)
2734 srel
->size
+= sizeof (Elf32_External_Rela
);
2738 /* We need to figure out the alignment required for this symbol. I
2739 have no idea how ELF linkers handle this. */
2740 power_of_two
= bfd_log2 (h
->size
);
2741 if (power_of_two
> 3)
2744 /* Apply the required alignment. */
2745 s
->size
= BFD_ALIGN (s
->size
, (bfd_size_type
) (1 << power_of_two
));
2746 if (power_of_two
> s
->alignment_power
)
2748 if (!bfd_set_section_alignment (s
, power_of_two
))
2752 /* Define the symbol as being at this point in the section. */
2753 h
->root
.u
.def
.section
= s
;
2754 h
->root
.u
.def
.value
= s
->size
;
2756 /* Increment the section size to make room for the symbol. */
2761 /* Allocate space in .plt, .got and associated reloc sections for
2765 allocate_dynrelocs (struct elf_link_hash_entry
*h
, void * dat
)
2767 struct bfd_link_info
*info
;
2768 struct elf32_mb_link_hash_table
*htab
;
2769 struct elf32_mb_link_hash_entry
*eh
;
2770 struct elf_dyn_relocs
*p
;
2772 if (h
->root
.type
== bfd_link_hash_indirect
)
2775 info
= (struct bfd_link_info
*) dat
;
2776 htab
= elf32_mb_hash_table (info
);
2780 if (htab
->elf
.dynamic_sections_created
2781 && h
->plt
.refcount
> 0)
2783 /* Make sure this symbol is output as a dynamic symbol.
2784 Undefined weak syms won't yet be marked as dynamic. */
2785 if (h
->dynindx
== -1
2786 && !h
->forced_local
)
2788 if (! bfd_elf_link_record_dynamic_symbol (info
, h
))
2792 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info
), h
))
2794 asection
*s
= htab
->elf
.splt
;
2796 /* The first entry in .plt is reserved. */
2798 s
->size
= PLT_ENTRY_SIZE
;
2800 h
->plt
.offset
= s
->size
;
2802 /* If this symbol is not defined in a regular file, and we are
2803 not generating a shared library, then set the symbol to this
2804 location in the .plt. This is required to make function
2805 pointers compare as equal between the normal executable and
2806 the shared library. */
2807 if (! bfd_link_pic (info
)
2810 h
->root
.u
.def
.section
= s
;
2811 h
->root
.u
.def
.value
= h
->plt
.offset
;
2814 /* Make room for this entry. */
2815 s
->size
+= PLT_ENTRY_SIZE
;
2817 /* We also need to make an entry in the .got.plt section, which
2818 will be placed in the .got section by the linker script. */
2819 htab
->elf
.sgotplt
->size
+= 4;
2821 /* We also need to make an entry in the .rel.plt section. */
2822 htab
->elf
.srelplt
->size
+= sizeof (Elf32_External_Rela
);
2826 h
->plt
.offset
= (bfd_vma
) -1;
2832 h
->plt
.offset
= (bfd_vma
) -1;
2836 eh
= (struct elf32_mb_link_hash_entry
*) h
;
2837 if (h
->got
.refcount
> 0)
2842 /* Make sure this symbol is output as a dynamic symbol.
2843 Undefined weak syms won't yet be marked as dynamic. */
2844 if (h
->dynindx
== -1
2845 && !h
->forced_local
)
2847 if (! bfd_elf_link_record_dynamic_symbol (info
, h
))
2852 if ((eh
->tls_mask
& TLS_TLS
) != 0)
2854 /* Handle TLS Symbol */
2855 if ((eh
->tls_mask
& TLS_LD
) != 0)
2857 if (!eh
->elf
.def_dynamic
)
2858 /* We'll just use htab->tlsld_got.offset. This should
2859 always be the case. It's a little odd if we have
2860 a local dynamic reloc against a non-local symbol. */
2861 htab
->tlsld_got
.refcount
+= 1;
2865 if ((eh
->tls_mask
& TLS_GD
) != 0)
2870 /* Regular (non-TLS) symbol */
2875 h
->got
.offset
= (bfd_vma
) -1;
2880 h
->got
.offset
= s
->size
;
2882 htab
->elf
.srelgot
->size
+= need
* (sizeof (Elf32_External_Rela
) / 4);
2886 h
->got
.offset
= (bfd_vma
) -1;
2888 if (h
->dyn_relocs
== NULL
)
2891 /* In the shared -Bsymbolic case, discard space allocated for
2892 dynamic pc-relative relocs against symbols which turn out to be
2893 defined in regular objects. For the normal shared case, discard
2894 space for pc-relative relocs that have become local due to symbol
2895 visibility changes. */
2897 if (bfd_link_pic (info
))
2903 struct elf_dyn_relocs
**pp
;
2905 for (pp
= &h
->dyn_relocs
; (p
= *pp
) != NULL
; )
2907 p
->count
-= p
->pc_count
;
2915 else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
2916 h
->dyn_relocs
= NULL
;
2920 /* For the non-shared case, discard space for relocs against
2921 symbols which turn out to need copy relocs or are not
2927 || (htab
->elf
.dynamic_sections_created
2928 && (h
->root
.type
== bfd_link_hash_undefweak
2929 || h
->root
.type
== bfd_link_hash_undefined
))))
2931 /* Make sure this symbol is output as a dynamic symbol.
2932 Undefined weak syms won't yet be marked as dynamic. */
2933 if (h
->dynindx
== -1
2934 && !h
->forced_local
)
2936 if (! bfd_elf_link_record_dynamic_symbol (info
, h
))
2940 /* If that succeeded, we know we'll be keeping all the
2942 if (h
->dynindx
!= -1)
2946 h
->dyn_relocs
= NULL
;
2951 /* Finally, allocate space. */
2952 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
2954 asection
*sreloc
= elf_section_data (p
->sec
)->sreloc
;
2955 sreloc
->size
+= p
->count
* sizeof (Elf32_External_Rela
);
2961 /* Set the sizes of the dynamic sections. */
2964 microblaze_elf_late_size_sections (bfd
*output_bfd ATTRIBUTE_UNUSED
,
2965 struct bfd_link_info
*info
)
2967 struct elf32_mb_link_hash_table
*htab
;
2972 htab
= elf32_mb_hash_table (info
);
2976 dynobj
= htab
->elf
.dynobj
;
2980 /* Set up .got offsets for local syms, and space for local dynamic
2982 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
2984 bfd_signed_vma
*local_got
;
2985 bfd_signed_vma
*end_local_got
;
2986 bfd_size_type locsymcount
;
2987 Elf_Internal_Shdr
*symtab_hdr
;
2988 unsigned char *lgot_masks
;
2991 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
)
2994 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
2996 struct elf_dyn_relocs
*p
;
2998 for (p
= ((struct elf_dyn_relocs
*)
2999 elf_section_data (s
)->local_dynrel
);
3003 if (!bfd_is_abs_section (p
->sec
)
3004 && bfd_is_abs_section (p
->sec
->output_section
))
3006 /* Input section has been discarded, either because
3007 it is a copy of a linkonce section or due to
3008 linker script /DISCARD/, so we'll be discarding
3011 else if (p
->count
!= 0)
3013 srel
= elf_section_data (p
->sec
)->sreloc
;
3014 srel
->size
+= p
->count
* sizeof (Elf32_External_Rela
);
3015 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
3016 info
->flags
|= DF_TEXTREL
;
3021 local_got
= elf_local_got_refcounts (ibfd
);
3025 symtab_hdr
= &elf_tdata (ibfd
)->symtab_hdr
;
3026 locsymcount
= symtab_hdr
->sh_info
;
3027 end_local_got
= local_got
+ locsymcount
;
3028 lgot_masks
= (unsigned char *) end_local_got
;
3030 srel
= htab
->elf
.srelgot
;
3032 for (; local_got
< end_local_got
; ++local_got
, ++lgot_masks
)
3036 unsigned int need
= 0;
3037 if ((*lgot_masks
& TLS_TLS
) != 0)
3039 if ((*lgot_masks
& TLS_GD
) != 0)
3041 if ((*lgot_masks
& TLS_LD
) != 0)
3042 htab
->tlsld_got
.refcount
+= 1;
3049 *local_got
= (bfd_vma
) -1;
3053 *local_got
= s
->size
;
3055 if (bfd_link_pic (info
))
3056 srel
->size
+= need
* (sizeof (Elf32_External_Rela
) / 4);
3060 *local_got
= (bfd_vma
) -1;
3064 /* Allocate global sym .plt and .got entries, and space for global
3065 sym dynamic relocs. */
3066 elf_link_hash_traverse (elf_hash_table (info
), allocate_dynrelocs
, info
);
3068 if (htab
->tlsld_got
.refcount
> 0)
3070 htab
->tlsld_got
.offset
= htab
->elf
.sgot
->size
;
3071 htab
->elf
.sgot
->size
+= 8;
3072 if (bfd_link_pic (info
))
3073 htab
->elf
.srelgot
->size
+= sizeof (Elf32_External_Rela
);
3076 htab
->tlsld_got
.offset
= (bfd_vma
) -1;
3078 if (elf_hash_table (info
)->dynamic_sections_created
)
3080 /* Make space for the trailing nop in .plt. */
3081 if (htab
->elf
.splt
->size
> 0)
3082 htab
->elf
.splt
->size
+= 4;
3085 /* The check_relocs and adjust_dynamic_symbol entry points have
3086 determined the sizes of the various dynamic sections. Allocate
3088 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
3093 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
3096 /* It's OK to base decisions on the section name, because none
3097 of the dynobj section names depend upon the input files. */
3098 name
= bfd_section_name (s
);
3100 if (startswith (name
, ".rela"))
3104 /* If we don't need this section, strip it from the
3105 output file. This is to handle .rela.bss and
3106 .rela.plt. We must create it in
3107 create_dynamic_sections, because it must be created
3108 before the linker maps input sections to output
3109 sections. The linker does that before
3110 adjust_dynamic_symbol is called, and it is that
3111 function which decides whether anything needs to go
3112 into these sections. */
3117 /* We use the reloc_count field as a counter if we need
3118 to copy relocs into the output file. */
3122 else if (s
!= htab
->elf
.splt
3123 && s
!= htab
->elf
.sgot
3124 && s
!= htab
->elf
.sgotplt
3125 && s
!= htab
->elf
.sdynbss
3126 && s
!= htab
->elf
.sdynrelro
)
3128 /* It's not one of our sections, so don't allocate space. */
3134 s
->flags
|= SEC_EXCLUDE
;
3138 /* Allocate memory for the section contents. */
3139 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
3140 Unused entries should be reclaimed before the section's contents
3141 are written out, but at the moment this does not happen. Thus in
3142 order to prevent writing out garbage, we initialise the section's
3143 contents to zero. */
3144 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
3145 if (s
->contents
== NULL
&& s
->size
!= 0)
3149 /* ??? Force DF_BIND_NOW? */
3150 info
->flags
|= DF_BIND_NOW
;
3151 return _bfd_elf_add_dynamic_tags (output_bfd
, info
, true);
3154 /* Finish up dynamic symbol handling. We set the contents of various
3155 dynamic sections here. */
3158 microblaze_elf_finish_dynamic_symbol (bfd
*output_bfd
,
3159 struct bfd_link_info
*info
,
3160 struct elf_link_hash_entry
*h
,
3161 Elf_Internal_Sym
*sym
)
3163 struct elf32_mb_link_hash_table
*htab
;
3164 struct elf32_mb_link_hash_entry
*eh
= elf32_mb_hash_entry(h
);
3166 htab
= elf32_mb_hash_table (info
);
3168 if (h
->plt
.offset
!= (bfd_vma
) -1)
3173 Elf_Internal_Rela rela
;
3179 /* This symbol has an entry in the procedure linkage table. Set
3181 BFD_ASSERT (h
->dynindx
!= -1);
3183 splt
= htab
->elf
.splt
;
3184 srela
= htab
->elf
.srelplt
;
3185 sgotplt
= htab
->elf
.sgotplt
;
3186 BFD_ASSERT (splt
!= NULL
&& srela
!= NULL
&& sgotplt
!= NULL
);
3188 plt_index
= h
->plt
.offset
/ PLT_ENTRY_SIZE
- 1; /* first entry reserved. */
3189 got_offset
= (plt_index
+ 3) * 4; /* 3 reserved ??? */
3190 got_addr
= got_offset
;
3192 /* For non-PIC objects we need absolute address of the GOT entry. */
3193 if (!bfd_link_pic (info
))
3194 got_addr
+= sgotplt
->output_section
->vma
+ sgotplt
->output_offset
;
3196 /* Fill in the entry in the procedure linkage table. */
3197 bfd_put_32 (output_bfd
, PLT_ENTRY_WORD_0
+ ((got_addr
>> 16) & 0xffff),
3198 splt
->contents
+ h
->plt
.offset
);
3199 if (bfd_link_pic (info
))
3200 bfd_put_32 (output_bfd
, PLT_ENTRY_WORD_1
+ (got_addr
& 0xffff),
3201 splt
->contents
+ h
->plt
.offset
+ 4);
3203 bfd_put_32 (output_bfd
, PLT_ENTRY_WORD_1_NOPIC
+ (got_addr
& 0xffff),
3204 splt
->contents
+ h
->plt
.offset
+ 4);
3205 bfd_put_32 (output_bfd
, (bfd_vma
) PLT_ENTRY_WORD_2
,
3206 splt
->contents
+ h
->plt
.offset
+ 8);
3207 bfd_put_32 (output_bfd
, (bfd_vma
) PLT_ENTRY_WORD_3
,
3208 splt
->contents
+ h
->plt
.offset
+ 12);
3210 /* Any additions to the .got section??? */
3211 /* bfd_put_32 (output_bfd,
3212 splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
3213 sgotplt->contents + got_offset); */
3215 /* Fill in the entry in the .rela.plt section. */
3216 rela
.r_offset
= (sgotplt
->output_section
->vma
3217 + sgotplt
->output_offset
3219 rela
.r_info
= ELF32_R_INFO (h
->dynindx
, R_MICROBLAZE_JUMP_SLOT
);
3221 loc
= srela
->contents
;
3222 loc
+= plt_index
* sizeof (Elf32_External_Rela
);
3223 bfd_elf32_swap_reloca_out (output_bfd
, &rela
, loc
);
3225 if (!h
->def_regular
)
3227 /* Mark the symbol as undefined, rather than as defined in
3228 the .plt section. Zero the value. */
3229 sym
->st_shndx
= SHN_UNDEF
;
3234 /* h->got.refcount to be checked ? */
3235 if ((h
->got
.offset
!= (bfd_vma
) -1)
3236 && ! ((h
->got
.offset
& 1)
3237 || IS_TLS_LD(eh
->tls_mask
) || IS_TLS_GD(eh
->tls_mask
)))
3243 /* This symbol has an entry in the global offset table. Set it
3246 sgot
= htab
->elf
.sgot
;
3247 srela
= htab
->elf
.srelgot
;
3248 BFD_ASSERT (sgot
!= NULL
&& srela
!= NULL
);
3250 offset
= (sgot
->output_section
->vma
+ sgot
->output_offset
3251 + (h
->got
.offset
&~ (bfd_vma
) 1));
3253 /* If this is a -Bsymbolic link, and the symbol is defined
3254 locally, we just want to emit a RELATIVE reloc. Likewise if
3255 the symbol was forced to be local because of a version file.
3256 The entry in the global offset table will already have been
3257 initialized in the relocate_section function. */
3258 if (bfd_link_pic (info
)
3259 && ((info
->symbolic
&& h
->def_regular
)
3260 || h
->dynindx
== -1))
3262 asection
*sec
= h
->root
.u
.def
.section
;
3265 value
= h
->root
.u
.def
.value
;
3266 if (sec
->output_section
!= NULL
)
3267 /* PR 21180: If the output section is NULL, then the symbol is no
3268 longer needed, and in theory the GOT entry is redundant. But
3269 it is too late to change our minds now... */
3270 value
+= sec
->output_section
->vma
+ sec
->output_offset
;
3272 microblaze_elf_output_dynamic_relocation (output_bfd
,
3273 srela
, srela
->reloc_count
++,
3275 R_MICROBLAZE_REL
, offset
,
3280 microblaze_elf_output_dynamic_relocation (output_bfd
,
3281 srela
, srela
->reloc_count
++,
3283 R_MICROBLAZE_GLOB_DAT
,
3287 bfd_put_32 (output_bfd
, (bfd_vma
) 0,
3288 sgot
->contents
+ (h
->got
.offset
&~ (bfd_vma
) 1));
3294 Elf_Internal_Rela rela
;
3297 /* This symbols needs a copy reloc. Set it up. */
3299 BFD_ASSERT (h
->dynindx
!= -1);
3301 rela
.r_offset
= (h
->root
.u
.def
.value
3302 + h
->root
.u
.def
.section
->output_section
->vma
3303 + h
->root
.u
.def
.section
->output_offset
);
3304 rela
.r_info
= ELF32_R_INFO (h
->dynindx
, R_MICROBLAZE_COPY
);
3306 if (h
->root
.u
.def
.section
== htab
->elf
.sdynrelro
)
3307 s
= htab
->elf
.sreldynrelro
;
3309 s
= htab
->elf
.srelbss
;
3310 loc
= s
->contents
+ s
->reloc_count
++ * sizeof (Elf32_External_Rela
);
3311 bfd_elf32_swap_reloca_out (output_bfd
, &rela
, loc
);
3314 /* Mark some specially defined symbols as absolute. */
3315 if (h
== htab
->elf
.hdynamic
3316 || h
== htab
->elf
.hgot
3317 || h
== htab
->elf
.hplt
)
3318 sym
->st_shndx
= SHN_ABS
;
3324 /* Finish up the dynamic sections. */
3327 microblaze_elf_finish_dynamic_sections (bfd
*output_bfd
,
3328 struct bfd_link_info
*info
)
3331 asection
*sdyn
, *sgot
;
3332 struct elf32_mb_link_hash_table
*htab
;
3334 htab
= elf32_mb_hash_table (info
);
3338 dynobj
= htab
->elf
.dynobj
;
3340 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
3342 if (htab
->elf
.dynamic_sections_created
)
3345 Elf32_External_Dyn
*dyncon
, *dynconend
;
3347 dyncon
= (Elf32_External_Dyn
*) sdyn
->contents
;
3348 dynconend
= (Elf32_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
3349 for (; dyncon
< dynconend
; dyncon
++)
3351 Elf_Internal_Dyn dyn
;
3355 bfd_elf32_swap_dyn_in (dynobj
, dyncon
, &dyn
);
3360 s
= htab
->elf
.sgotplt
;
3365 s
= htab
->elf
.srelplt
;
3370 s
= htab
->elf
.srelplt
;
3383 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
3385 dyn
.d_un
.d_val
= s
->size
;
3387 bfd_elf32_swap_dyn_out (output_bfd
, &dyn
, dyncon
);
3390 splt
= htab
->elf
.splt
;
3391 BFD_ASSERT (splt
!= NULL
&& sdyn
!= NULL
);
3393 /* Clear the first entry in the procedure linkage table,
3394 and put a nop in the last four bytes. */
3397 memset (splt
->contents
, 0, PLT_ENTRY_SIZE
);
3398 bfd_put_32 (output_bfd
, (bfd_vma
) 0x80000000 /* nop. */,
3399 splt
->contents
+ splt
->size
- 4);
3401 if (splt
->output_section
!= bfd_abs_section_ptr
)
3402 elf_section_data (splt
->output_section
)->this_hdr
.sh_entsize
= 4;
3406 /* Set the first entry in the global offset table to the address of
3407 the dynamic section. */
3408 sgot
= htab
->elf
.sgotplt
;
3409 if (sgot
&& sgot
->size
> 0)
3412 bfd_put_32 (output_bfd
, (bfd_vma
) 0, sgot
->contents
);
3414 bfd_put_32 (output_bfd
,
3415 sdyn
->output_section
->vma
+ sdyn
->output_offset
,
3417 elf_section_data (sgot
->output_section
)->this_hdr
.sh_entsize
= 4;
3420 if (htab
->elf
.sgot
&& htab
->elf
.sgot
->size
> 0)
3421 elf_section_data (htab
->elf
.sgot
->output_section
)->this_hdr
.sh_entsize
= 4;
3426 /* Hook called by the linker routine which adds symbols from an object
3427 file. We use it to put .comm items in .sbss, and not .bss. */
3430 microblaze_elf_add_symbol_hook (bfd
*abfd
,
3431 struct bfd_link_info
*info
,
3432 Elf_Internal_Sym
*sym
,
3433 const char **namep ATTRIBUTE_UNUSED
,
3434 flagword
*flagsp ATTRIBUTE_UNUSED
,
3438 if (sym
->st_shndx
== SHN_COMMON
3439 && !bfd_link_relocatable (info
)
3440 && sym
->st_size
<= elf_gp_size (abfd
))
3442 /* Common symbols less than or equal to -G nn bytes are automatically
3444 *secp
= bfd_make_section_old_way (abfd
, ".sbss");
3446 || !bfd_set_section_flags (*secp
, SEC_IS_COMMON
| SEC_SMALL_DATA
))
3449 *valp
= sym
->st_size
;
3455 #define TARGET_LITTLE_SYM microblaze_elf32_le_vec
3456 #define TARGET_LITTLE_NAME "elf32-microblazeel"
3458 #define TARGET_BIG_SYM microblaze_elf32_vec
3459 #define TARGET_BIG_NAME "elf32-microblaze"
3461 #define ELF_ARCH bfd_arch_microblaze
3462 #define ELF_TARGET_ID MICROBLAZE_ELF_DATA
3463 #define ELF_MACHINE_CODE EM_MICROBLAZE
3464 #define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
3465 #define ELF_MAXPAGESIZE 0x1000
3466 #define elf_info_to_howto microblaze_elf_info_to_howto
3467 #define elf_info_to_howto_rel NULL
3469 #define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
3470 #define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name
3471 #define bfd_elf32_new_section_hook microblaze_elf_new_section_hook
3472 #define elf_backend_relocate_section microblaze_elf_relocate_section
3473 #define bfd_elf32_bfd_relax_section microblaze_elf_relax_section
3474 #define bfd_elf32_bfd_merge_private_bfd_data _bfd_generic_verify_endian_match
3475 #define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
3477 #define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
3478 #define elf_backend_check_relocs microblaze_elf_check_relocs
3479 #define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
3480 #define bfd_elf32_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
3481 #define elf_backend_can_gc_sections 1
3482 #define elf_backend_can_refcount 1
3483 #define elf_backend_want_got_plt 1
3484 #define elf_backend_plt_readonly 1
3485 #define elf_backend_got_header_size 12
3486 #define elf_backend_want_dynrelro 1
3487 #define elf_backend_rela_normal 1
3488 #define elf_backend_dtrel_excludes_plt 1
3490 #define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
3491 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
3492 #define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
3493 #define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
3494 #define elf_backend_late_size_sections microblaze_elf_late_size_sections
3495 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
3497 #include "elf32-target.h"