1 /* Xilinx MicroBlaze-specific support for 32-bit ELF
3 Copyright (C) 2009-2024 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 if (!sec
->used_by_bfd
)
747 struct _microblaze_elf_section_data
*sdata
;
748 size_t amt
= sizeof (*sdata
);
750 sdata
= bfd_zalloc (abfd
, amt
);
753 sec
->used_by_bfd
= sdata
;
756 return _bfd_elf_new_section_hook (abfd
, sec
);
759 /* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
762 microblaze_elf_is_local_label_name (bfd
*abfd
, const char *name
)
764 if (name
[0] == 'L' && name
[1] == '.')
767 if (name
[0] == '$' && name
[1] == 'L')
770 /* With gcc, the labels go back to starting with '.', so we accept
771 the generic ELF local label syntax as well. */
772 return _bfd_elf_is_local_label_name (abfd
, name
);
775 /* ELF linker hash entry. */
777 struct elf32_mb_link_hash_entry
779 struct elf_link_hash_entry elf
;
781 /* TLS Reference Types for the symbol; Updated by check_relocs */
782 #define TLS_GD 1 /* GD reloc. */
783 #define TLS_LD 2 /* LD reloc. */
784 #define TLS_TPREL 4 /* TPREL reloc, => IE. */
785 #define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
786 #define TLS_TLS 16 /* Any TLS reloc. */
787 unsigned char tls_mask
;
791 #define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD))
792 #define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD))
793 #define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL))
794 #define IS_TLS_NONE(x) (x == 0)
796 #define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent))
798 /* ELF linker hash table. */
800 struct elf32_mb_link_hash_table
802 struct elf_link_hash_table elf
;
804 /* TLS Local Dynamic GOT Entry */
806 bfd_signed_vma refcount
;
811 /* Nonzero if this section has TLS related relocations. */
812 #define has_tls_reloc sec_flg0
814 /* Get the ELF linker hash table from a link_info structure. */
816 #define elf32_mb_hash_table(p) \
817 ((is_elf_hash_table ((p)->hash) \
818 && elf_hash_table_id (elf_hash_table (p)) == MICROBLAZE_ELF_DATA) \
819 ? (struct elf32_mb_link_hash_table *) (p)->hash : NULL)
821 /* Create an entry in a microblaze ELF linker hash table. */
823 static struct bfd_hash_entry
*
824 link_hash_newfunc (struct bfd_hash_entry
*entry
,
825 struct bfd_hash_table
*table
,
828 /* Allocate the structure if it has not already been allocated by a
832 entry
= bfd_hash_allocate (table
,
833 sizeof (struct elf32_mb_link_hash_entry
));
838 /* Call the allocation method of the superclass. */
839 entry
= _bfd_elf_link_hash_newfunc (entry
, table
, string
);
842 struct elf32_mb_link_hash_entry
*eh
;
844 eh
= (struct elf32_mb_link_hash_entry
*) entry
;
851 /* Create a mb ELF linker hash table. */
853 static struct bfd_link_hash_table
*
854 microblaze_elf_link_hash_table_create (bfd
*abfd
)
856 struct elf32_mb_link_hash_table
*ret
;
857 size_t amt
= sizeof (struct elf32_mb_link_hash_table
);
859 ret
= (struct elf32_mb_link_hash_table
*) bfd_zmalloc (amt
);
863 if (!_bfd_elf_link_hash_table_init (&ret
->elf
, abfd
, link_hash_newfunc
,
864 sizeof (struct elf32_mb_link_hash_entry
),
865 MICROBLAZE_ELF_DATA
))
871 return &ret
->elf
.root
;
874 /* Set the values of the small data pointers. */
877 microblaze_elf_final_sdp (struct bfd_link_info
*info
)
879 struct bfd_link_hash_entry
*h
;
881 h
= bfd_link_hash_lookup (info
->hash
, RO_SDA_ANCHOR_NAME
, false, false, true);
882 if (h
!= (struct bfd_link_hash_entry
*) NULL
883 && h
->type
== bfd_link_hash_defined
)
884 ro_small_data_pointer
= (h
->u
.def
.value
885 + h
->u
.def
.section
->output_section
->vma
886 + h
->u
.def
.section
->output_offset
);
888 h
= bfd_link_hash_lookup (info
->hash
, RW_SDA_ANCHOR_NAME
, false, false, true);
889 if (h
!= (struct bfd_link_hash_entry
*) NULL
890 && h
->type
== bfd_link_hash_defined
)
891 rw_small_data_pointer
= (h
->u
.def
.value
892 + h
->u
.def
.section
->output_section
->vma
893 + h
->u
.def
.section
->output_offset
);
897 dtprel_base (struct bfd_link_info
*info
)
899 /* If tls_sec is NULL, we should have signalled an error already. */
900 if (elf_hash_table (info
)->tls_sec
== NULL
)
902 return elf_hash_table (info
)->tls_sec
->vma
;
905 /* The size of the thread control block. */
908 /* Output a simple dynamic relocation into SRELOC. */
911 microblaze_elf_output_dynamic_relocation (bfd
*output_bfd
,
913 unsigned long reloc_index
,
920 Elf_Internal_Rela rel
;
922 rel
.r_info
= ELF32_R_INFO (indx
, r_type
);
923 rel
.r_offset
= offset
;
924 rel
.r_addend
= addend
;
926 bfd_elf32_swap_reloca_out (output_bfd
, &rel
,
927 (sreloc
->contents
+ reloc_index
* sizeof (Elf32_External_Rela
)));
930 /* This code is taken from elf32-m32r.c
931 There is some attempt to make this function usable for many architectures,
932 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
933 if only to serve as a learning tool.
935 The RELOCATE_SECTION function is called by the new ELF backend linker
936 to handle the relocations for a section.
938 The relocs are always passed as Rela structures; if the section
939 actually uses Rel structures, the r_addend field will always be
942 This function is responsible for adjust the section contents as
943 necessary, and (if using Rela relocs and generating a
944 relocatable output file) adjusting the reloc addend as
947 This function does not have to worry about setting the reloc
948 address or the reloc symbol index.
950 LOCAL_SYMS is a pointer to the swapped in local symbols.
952 LOCAL_SECTIONS is an array giving the section in the input file
953 corresponding to the st_shndx field of each local symbol.
955 The global hash table entry for the global symbols can be found
956 via elf_sym_hashes (input_bfd).
958 When generating relocatable output, this function must handle
959 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
960 going to be the section symbol corresponding to the output
961 section, which means that the addend must be adjusted
965 microblaze_elf_relocate_section (bfd
*output_bfd
,
966 struct bfd_link_info
*info
,
968 asection
*input_section
,
970 Elf_Internal_Rela
*relocs
,
971 Elf_Internal_Sym
*local_syms
,
972 asection
**local_sections
)
974 struct elf32_mb_link_hash_table
*htab
;
975 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
976 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
977 Elf_Internal_Rela
*rel
, *relend
;
978 int endian
= (bfd_little_endian (output_bfd
)) ? 0 : 2;
979 /* Assume success. */
982 bfd_vma
*local_got_offsets
;
983 unsigned int tls_type
;
985 if (!microblaze_elf_howto_table
[R_MICROBLAZE_max
-1])
986 microblaze_elf_howto_init ();
988 htab
= elf32_mb_hash_table (info
);
992 local_got_offsets
= elf_local_got_offsets (input_bfd
);
994 sreloc
= elf_section_data (input_section
)->sreloc
;
997 relend
= relocs
+ input_section
->reloc_count
;
998 for (; rel
< relend
; rel
++)
1001 reloc_howto_type
*howto
;
1002 unsigned long r_symndx
;
1003 bfd_vma addend
= rel
->r_addend
;
1004 bfd_vma offset
= rel
->r_offset
;
1005 struct elf_link_hash_entry
*h
;
1006 Elf_Internal_Sym
*sym
;
1008 const char *sym_name
;
1009 bfd_reloc_status_type r
= bfd_reloc_ok
;
1010 const char *errmsg
= NULL
;
1011 bool unresolved_reloc
= false;
1014 r_type
= ELF32_R_TYPE (rel
->r_info
);
1017 if (r_type
< 0 || r_type
>= (int) R_MICROBLAZE_max
)
1019 /* xgettext:c-format */
1020 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
1021 input_bfd
, (int) r_type
);
1022 bfd_set_error (bfd_error_bad_value
);
1027 howto
= microblaze_elf_howto_table
[r_type
];
1028 r_symndx
= ELF32_R_SYM (rel
->r_info
);
1030 if (bfd_link_relocatable (info
))
1032 /* This is a relocatable link. We don't have to change
1033 anything, unless the reloc is against a section symbol,
1034 in which case we have to adjust according to where the
1035 section symbol winds up in the output section. */
1037 if (r_symndx
>= symtab_hdr
->sh_info
)
1038 /* External symbol. */
1042 sym
= local_syms
+ r_symndx
;
1043 sym_name
= "<local symbol>";
1044 /* STT_SECTION: symbol is associated with a section. */
1045 if (ELF_ST_TYPE (sym
->st_info
) != STT_SECTION
)
1046 /* Symbol isn't associated with a section. Nothing to do. */
1049 sec
= local_sections
[r_symndx
];
1050 addend
+= sec
->output_offset
+ sym
->st_value
;
1052 /* This can't be done for USE_REL because it doesn't mean anything
1053 and elf_link_input_bfd asserts this stays zero. */
1054 /* rel->r_addend = addend; */
1058 /* Addends are stored with relocs. We're done. */
1061 /* If partial_inplace, we need to store any additional addend
1062 back in the section. */
1063 if (!howto
->partial_inplace
)
1065 /* ??? Here is a nice place to call a special_function like handler. */
1066 r
= _bfd_relocate_contents (howto
, input_bfd
, addend
,
1068 #endif /* USE_REL */
1073 bool resolved_to_zero
;
1075 /* This is a final link. */
1078 unresolved_reloc
= false;
1080 if (r_symndx
< symtab_hdr
->sh_info
)
1083 sym
= local_syms
+ r_symndx
;
1084 sec
= local_sections
[r_symndx
];
1087 sym_name
= "<local symbol>";
1088 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
1089 /* r_addend may have changed if the reference section was
1091 addend
= rel
->r_addend
;
1095 /* External symbol. */
1096 bool warned ATTRIBUTE_UNUSED
;
1097 bool ignored ATTRIBUTE_UNUSED
;
1099 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
1100 r_symndx
, symtab_hdr
, sym_hashes
,
1102 unresolved_reloc
, warned
, ignored
);
1103 sym_name
= h
->root
.root
.string
;
1106 /* Sanity check the address. */
1107 if (offset
> bfd_get_section_limit (input_bfd
, input_section
))
1109 r
= bfd_reloc_outofrange
;
1113 resolved_to_zero
= (h
!= NULL
1114 && UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
));
1116 switch ((int) r_type
)
1118 case (int) R_MICROBLAZE_SRO32
:
1122 /* Only relocate if the symbol is defined. */
1125 name
= bfd_section_name (sec
);
1127 if (strcmp (name
, ".sdata2") == 0
1128 || strcmp (name
, ".sbss2") == 0)
1130 if (ro_small_data_pointer
== 0)
1131 microblaze_elf_final_sdp (info
);
1132 if (ro_small_data_pointer
== 0)
1135 r
= bfd_reloc_undefined
;
1139 /* At this point `relocation' contains the object's
1141 relocation
-= ro_small_data_pointer
;
1142 /* Now it contains the offset from _SDA2_BASE_. */
1143 r
= _bfd_final_link_relocate (howto
, input_bfd
,
1146 relocation
, addend
);
1151 /* xgettext:c-format */
1152 (_("%pB: the target (%s) of an %s relocation"
1153 " is in the wrong section (%pA)"),
1156 microblaze_elf_howto_table
[(int) r_type
]->name
,
1158 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1166 case (int) R_MICROBLAZE_SRW32
:
1170 /* Only relocate if the symbol is defined. */
1173 name
= bfd_section_name (sec
);
1175 if (strcmp (name
, ".sdata") == 0
1176 || strcmp (name
, ".sbss") == 0)
1178 if (rw_small_data_pointer
== 0)
1179 microblaze_elf_final_sdp (info
);
1180 if (rw_small_data_pointer
== 0)
1183 r
= bfd_reloc_undefined
;
1187 /* At this point `relocation' contains the object's
1189 relocation
-= rw_small_data_pointer
;
1190 /* Now it contains the offset from _SDA_BASE_. */
1191 r
= _bfd_final_link_relocate (howto
, input_bfd
,
1194 relocation
, addend
);
1199 /* xgettext:c-format */
1200 (_("%pB: the target (%s) of an %s relocation"
1201 " is in the wrong section (%pA)"),
1204 microblaze_elf_howto_table
[(int) r_type
]->name
,
1206 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1214 case (int) R_MICROBLAZE_32_SYM_OP_SYM
:
1215 break; /* Do nothing. */
1217 case (int) R_MICROBLAZE_GOTPC_64
:
1218 relocation
= (htab
->elf
.sgotplt
->output_section
->vma
1219 + htab
->elf
.sgotplt
->output_offset
);
1220 relocation
-= (input_section
->output_section
->vma
1221 + input_section
->output_offset
1222 + offset
+ INST_WORD_SIZE
);
1223 relocation
+= addend
;
1224 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1225 contents
+ offset
+ endian
);
1226 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1227 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1230 case (int) R_MICROBLAZE_TEXTPCREL_64
:
1231 relocation
= input_section
->output_section
->vma
;
1232 relocation
-= (input_section
->output_section
->vma
1233 + input_section
->output_offset
1234 + offset
+ INST_WORD_SIZE
);
1235 relocation
+= addend
;
1236 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1237 contents
+ offset
+ endian
);
1238 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1239 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1242 case (int) R_MICROBLAZE_PLT_64
:
1245 if (htab
->elf
.splt
!= NULL
&& h
!= NULL
1246 && h
->plt
.offset
!= (bfd_vma
) -1)
1248 relocation
= (htab
->elf
.splt
->output_section
->vma
1249 + htab
->elf
.splt
->output_offset
1251 unresolved_reloc
= false;
1252 immediate
= relocation
- (input_section
->output_section
->vma
1253 + input_section
->output_offset
1254 + offset
+ INST_WORD_SIZE
);
1255 bfd_put_16 (input_bfd
, (immediate
>> 16) & 0xffff,
1256 contents
+ offset
+ endian
);
1257 bfd_put_16 (input_bfd
, immediate
& 0xffff,
1258 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1262 relocation
-= (input_section
->output_section
->vma
1263 + input_section
->output_offset
1264 + offset
+ INST_WORD_SIZE
);
1265 immediate
= relocation
;
1266 bfd_put_16 (input_bfd
, (immediate
>> 16) & 0xffff,
1267 contents
+ offset
+ endian
);
1268 bfd_put_16 (input_bfd
, immediate
& 0xffff,
1269 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1274 case (int) R_MICROBLAZE_TLSGD
:
1275 tls_type
= (TLS_TLS
| TLS_GD
);
1277 case (int) R_MICROBLAZE_TLSLD
:
1278 tls_type
= (TLS_TLS
| TLS_LD
);
1281 case (int) R_MICROBLAZE_GOT_64
:
1286 bfd_vma static_value
;
1288 bool need_relocs
= false;
1289 if (htab
->elf
.sgot
== NULL
)
1295 /* 1. Identify GOT Offset;
1296 2. Compute Static Values
1297 3. Process Module Id, Process Offset
1298 4. Fixup Relocation with GOT offset value. */
1300 /* 1. Determine GOT Offset to use : TLS_LD, global, local */
1301 if (IS_TLS_LD (tls_type
))
1302 offp
= &htab
->tlsld_got
.offset
;
1305 if (htab
->elf
.sgotplt
!= NULL
1306 && h
->got
.offset
!= (bfd_vma
) -1)
1307 offp
= &h
->got
.offset
;
1313 if (local_got_offsets
== NULL
)
1315 offp
= &local_got_offsets
[r_symndx
];
1324 if (IS_TLS_LD(tls_type
) || IS_TLS_GD(tls_type
))
1327 /* Symbol index to use for relocs */
1331 elf_hash_table (info
)->dynamic_sections_created
;
1333 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
,
1334 bfd_link_pic (info
),
1336 && (!bfd_link_pic (info
)
1337 || !SYMBOL_REFERENCES_LOCAL (info
, h
)))
1341 /* Need to generate relocs ? */
1342 if ((bfd_link_pic (info
) || indx
!= 0)
1344 || (ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
1345 && !resolved_to_zero
)
1346 || h
->root
.type
!= bfd_link_hash_undefweak
))
1349 /* 2. Compute/Emit Static value of r-expression */
1350 static_value
= relocation
+ addend
;
1352 /* 3. Process module-id and offset */
1353 if (! ((*offp
) & 1) )
1357 got_offset
= (htab
->elf
.sgot
->output_section
->vma
1358 + htab
->elf
.sgot
->output_offset
1361 /* Process module-id */
1362 if (IS_TLS_LD(tls_type
))
1364 if (! bfd_link_pic (info
))
1365 bfd_put_32 (output_bfd
, 1,
1366 htab
->elf
.sgot
->contents
+ off
);
1368 microblaze_elf_output_dynamic_relocation
1371 htab
->elf
.srelgot
->reloc_count
++,
1372 /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32
,
1375 else if (IS_TLS_GD(tls_type
))
1378 bfd_put_32 (output_bfd
, 1,
1379 htab
->elf
.sgot
->contents
+ off
);
1381 microblaze_elf_output_dynamic_relocation
1384 htab
->elf
.srelgot
->reloc_count
++,
1385 /* symindex= */ indx
, R_MICROBLAZE_TLSDTPMOD32
,
1386 got_offset
, indx
? 0 : static_value
);
1389 /* Process Offset */
1390 if (htab
->elf
.srelgot
== NULL
)
1393 got_offset
= (htab
->elf
.sgot
->output_section
->vma
1394 + htab
->elf
.sgot
->output_offset
1396 if (IS_TLS_LD(tls_type
))
1398 /* For LD, offset should be 0 */
1400 bfd_put_32 (output_bfd
, 0,
1401 htab
->elf
.sgot
->contents
+ off2
);
1403 else if (IS_TLS_GD(tls_type
))
1406 static_value
-= dtprel_base(info
);
1408 microblaze_elf_output_dynamic_relocation
1411 htab
->elf
.srelgot
->reloc_count
++,
1412 /* symindex= */ indx
, R_MICROBLAZE_TLSDTPREL32
,
1413 got_offset
, indx
? 0 : static_value
);
1415 bfd_put_32 (output_bfd
, static_value
,
1416 htab
->elf
.sgot
->contents
+ off2
);
1420 bfd_put_32 (output_bfd
, static_value
,
1421 htab
->elf
.sgot
->contents
+ off2
);
1423 /* Relocs for dyn symbols generated by
1424 finish_dynamic_symbols */
1425 if (bfd_link_pic (info
) && h
== NULL
)
1428 microblaze_elf_output_dynamic_relocation
1431 htab
->elf
.srelgot
->reloc_count
++,
1432 /* symindex= */ indx
, R_MICROBLAZE_REL
,
1433 got_offset
, static_value
);
1438 /* 4. Fixup Relocation with GOT offset value
1439 Compute relative address of GOT entry for applying
1440 the current relocation */
1441 relocation
= htab
->elf
.sgot
->output_section
->vma
1442 + htab
->elf
.sgot
->output_offset
1444 - htab
->elf
.sgotplt
->output_section
->vma
1445 - htab
->elf
.sgotplt
->output_offset
;
1447 /* Apply Current Relocation */
1448 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1449 contents
+ offset
+ endian
);
1450 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1451 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1453 unresolved_reloc
= false;
1457 case (int) R_MICROBLAZE_GOTOFF_64
:
1460 unsigned short lo
, high
;
1461 relocation
+= addend
;
1462 relocation
-= (htab
->elf
.sgotplt
->output_section
->vma
1463 + htab
->elf
.sgotplt
->output_offset
);
1464 /* Write this value into correct location. */
1465 immediate
= relocation
;
1466 lo
= immediate
& 0x0000ffff;
1467 high
= (immediate
>> 16) & 0x0000ffff;
1468 bfd_put_16 (input_bfd
, high
, contents
+ offset
+ endian
);
1469 bfd_put_16 (input_bfd
, lo
,
1470 contents
+ offset
+ INST_WORD_SIZE
+ endian
);
1474 case (int) R_MICROBLAZE_GOTOFF_32
:
1476 relocation
+= addend
;
1477 relocation
-= (htab
->elf
.sgotplt
->output_section
->vma
1478 + htab
->elf
.sgotplt
->output_offset
);
1479 /* Write this value into correct location. */
1480 bfd_put_32 (input_bfd
, relocation
, contents
+ offset
);
1484 case (int) R_MICROBLAZE_TLSDTPREL64
:
1485 relocation
+= addend
;
1486 relocation
-= dtprel_base(info
);
1487 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1488 contents
+ offset
+ endian
);
1489 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1490 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1492 case (int) R_MICROBLAZE_TEXTREL_64
:
1493 case (int) R_MICROBLAZE_TEXTREL_32_LO
:
1494 case (int) R_MICROBLAZE_64_PCREL
:
1495 case (int) R_MICROBLAZE_64
:
1496 case (int) R_MICROBLAZE_32
:
1498 /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
1499 from removed linkonce sections, or sections discarded by
1501 if (r_symndx
== STN_UNDEF
|| (input_section
->flags
& SEC_ALLOC
) == 0)
1503 relocation
+= addend
;
1504 if (r_type
== R_MICROBLAZE_32
)
1505 bfd_put_32 (input_bfd
, relocation
, contents
+ offset
);
1508 if (r_type
== R_MICROBLAZE_64_PCREL
)
1509 relocation
-= (input_section
->output_section
->vma
1510 + input_section
->output_offset
1511 + offset
+ INST_WORD_SIZE
);
1512 else if (r_type
== R_MICROBLAZE_TEXTREL_64
1513 || r_type
== R_MICROBLAZE_TEXTREL_32_LO
)
1514 relocation
-= input_section
->output_section
->vma
;
1516 if (r_type
== R_MICROBLAZE_TEXTREL_32_LO
)
1517 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1518 contents
+ offset
+ endian
);
1522 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1523 contents
+ offset
+ endian
);
1524 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1525 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1531 if ((bfd_link_pic (info
)
1533 || (ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
1534 && !resolved_to_zero
)
1535 || h
->root
.type
!= bfd_link_hash_undefweak
)
1536 && (!howto
->pc_relative
1540 || !h
->def_regular
))))
1541 || (!bfd_link_pic (info
)
1547 || h
->root
.type
== bfd_link_hash_undefweak
1548 || h
->root
.type
== bfd_link_hash_undefined
)))
1550 Elf_Internal_Rela outrel
;
1554 /* When generating a shared object, these relocations
1555 are copied into the output file to be resolved at run
1558 BFD_ASSERT (sreloc
!= NULL
);
1563 _bfd_elf_section_offset (output_bfd
, info
, input_section
,
1565 if (outrel
.r_offset
== (bfd_vma
) -1)
1567 else if (outrel
.r_offset
== (bfd_vma
) -2)
1569 outrel
.r_offset
+= (input_section
->output_section
->vma
1570 + input_section
->output_offset
);
1573 memset (&outrel
, 0, sizeof outrel
);
1574 /* h->dynindx may be -1 if the symbol was marked to
1577 && ((! info
->symbolic
&& h
->dynindx
!= -1)
1578 || !h
->def_regular
))
1580 BFD_ASSERT (h
->dynindx
!= -1);
1581 outrel
.r_info
= ELF32_R_INFO (h
->dynindx
, r_type
);
1582 outrel
.r_addend
= addend
;
1586 if (r_type
== R_MICROBLAZE_32
)
1588 outrel
.r_info
= ELF32_R_INFO (0, R_MICROBLAZE_REL
);
1589 outrel
.r_addend
= relocation
+ addend
;
1595 (_("%pB: probably compiled without -fPIC?"),
1597 bfd_set_error (bfd_error_bad_value
);
1602 loc
= sreloc
->contents
;
1603 loc
+= sreloc
->reloc_count
++ * sizeof (Elf32_External_Rela
);
1604 bfd_elf32_swap_reloca_out (output_bfd
, &outrel
, loc
);
1609 relocation
+= addend
;
1610 if (r_type
== R_MICROBLAZE_32
)
1611 bfd_put_32 (input_bfd
, relocation
, contents
+ offset
);
1614 if (r_type
== R_MICROBLAZE_64_PCREL
)
1615 relocation
-= (input_section
->output_section
->vma
1616 + input_section
->output_offset
1617 + offset
+ INST_WORD_SIZE
);
1618 else if (r_type
== R_MICROBLAZE_TEXTREL_64
1619 || r_type
== R_MICROBLAZE_TEXTREL_32_LO
)
1620 relocation
-= input_section
->output_section
->vma
;
1622 if (r_type
== R_MICROBLAZE_TEXTREL_32_LO
)
1624 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1625 contents
+ offset
+ endian
);
1629 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1630 contents
+ offset
+ endian
);
1631 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1632 contents
+ offset
+ endian
1641 r
= _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
1643 relocation
, addend
);
1650 if (r
!= bfd_reloc_ok
)
1652 /* FIXME: This should be generic enough to go in a utility. */
1656 name
= h
->root
.root
.string
;
1659 name
= (bfd_elf_string_from_elf_section
1660 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
1661 if (name
== NULL
|| *name
== '\0')
1662 name
= bfd_section_name (sec
);
1670 case bfd_reloc_overflow
:
1671 (*info
->callbacks
->reloc_overflow
)
1672 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
,
1673 (bfd_vma
) 0, input_bfd
, input_section
, offset
);
1676 case bfd_reloc_undefined
:
1677 (*info
->callbacks
->undefined_symbol
)
1678 (info
, name
, input_bfd
, input_section
, offset
, true);
1681 case bfd_reloc_outofrange
:
1682 errmsg
= _("internal error: out of range error");
1685 case bfd_reloc_notsupported
:
1686 errmsg
= _("internal error: unsupported relocation error");
1689 case bfd_reloc_dangerous
:
1690 errmsg
= _("internal error: dangerous error");
1694 errmsg
= _("internal error: unknown error");
1697 (*info
->callbacks
->warning
) (info
, errmsg
, name
, input_bfd
,
1698 input_section
, offset
);
1707 /* Calculate fixup value for reference. */
1710 calc_fixup (bfd_vma start
, bfd_vma size
, asection
*sec
)
1712 bfd_vma end
= start
+ size
;
1713 size_t i
, fixup
= 0;
1714 struct _microblaze_elf_section_data
*sdata
;
1716 if (sec
== NULL
|| (sdata
= microblaze_elf_section_data (sec
)) == NULL
)
1719 /* Look for addr in relax table, total fixup value. */
1720 for (i
= 0; i
< sdata
->relax_count
; i
++)
1722 if (end
<= sdata
->relax
[i
].addr
)
1724 if (end
!= start
&& start
> sdata
->relax
[i
].addr
)
1726 fixup
+= sdata
->relax
[i
].size
;
1731 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1732 a 32-bit instruction. */
1734 microblaze_bfd_write_imm_value_32 (bfd
*abfd
, bfd_byte
*bfd_addr
, bfd_vma val
)
1736 unsigned long instr
= bfd_get_32 (abfd
, bfd_addr
);
1737 instr
&= ~0x0000ffff;
1738 instr
|= (val
& 0x0000ffff);
1739 bfd_put_32 (abfd
, instr
, bfd_addr
);
1742 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1743 two consecutive 32-bit instructions. */
1745 microblaze_bfd_write_imm_value_64 (bfd
*abfd
, bfd_byte
*bfd_addr
, bfd_vma val
)
1747 unsigned long instr_hi
;
1748 unsigned long instr_lo
;
1750 instr_hi
= bfd_get_32 (abfd
, bfd_addr
);
1751 instr_hi
&= ~0x0000ffff;
1752 instr_hi
|= ((val
>> 16) & 0x0000ffff);
1753 bfd_put_32 (abfd
, instr_hi
, bfd_addr
);
1755 instr_lo
= bfd_get_32 (abfd
, bfd_addr
+ INST_WORD_SIZE
);
1756 instr_lo
&= ~0x0000ffff;
1757 instr_lo
|= (val
& 0x0000ffff);
1758 bfd_put_32 (abfd
, instr_lo
, bfd_addr
+ INST_WORD_SIZE
);
1762 microblaze_elf_relax_section (bfd
*abfd
,
1764 struct bfd_link_info
*link_info
,
1767 Elf_Internal_Shdr
*symtab_hdr
;
1768 Elf_Internal_Rela
*internal_relocs
;
1769 Elf_Internal_Rela
*free_relocs
= NULL
;
1770 Elf_Internal_Rela
*irel
, *irelend
;
1771 bfd_byte
*contents
= NULL
;
1772 bfd_byte
*free_contents
= NULL
;
1775 size_t i
, sym_index
;
1777 struct elf_link_hash_entry
*sym_hash
;
1778 Elf_Internal_Sym
*isymbuf
, *isymend
;
1779 Elf_Internal_Sym
*isym
;
1783 struct _microblaze_elf_section_data
*sdata
;
1785 /* We only do this once per section. We may be able to delete some code
1786 by running multiple passes, but it is not worth it. */
1789 /* Only do this for a text section. */
1790 if (bfd_link_relocatable (link_info
)
1791 || (sec
->flags
& SEC_RELOC
) == 0
1792 || (sec
->flags
& SEC_CODE
) == 0
1793 || sec
->reloc_count
== 0
1794 || (sdata
= microblaze_elf_section_data (sec
)) == NULL
)
1797 BFD_ASSERT ((sec
->size
> 0) || (sec
->rawsize
> 0));
1799 /* If this is the first time we have been called for this section,
1800 initialize the cooked size. */
1802 sec
->size
= sec
->rawsize
;
1804 /* Get symbols for this section. */
1805 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1806 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1807 symcount
= symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
);
1808 if (isymbuf
== NULL
)
1809 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
, symcount
,
1810 0, NULL
, NULL
, NULL
);
1811 BFD_ASSERT (isymbuf
!= NULL
);
1813 internal_relocs
= _bfd_elf_link_read_relocs (abfd
, sec
, NULL
, NULL
, link_info
->keep_memory
);
1814 if (internal_relocs
== NULL
)
1816 if (! link_info
->keep_memory
)
1817 free_relocs
= internal_relocs
;
1819 sdata
->relax_count
= 0;
1820 sdata
->relax
= (struct relax_table
*) bfd_malloc ((sec
->reloc_count
+ 1)
1821 * sizeof (*sdata
->relax
));
1822 if (sdata
->relax
== NULL
)
1825 irelend
= internal_relocs
+ sec
->reloc_count
;
1827 for (irel
= internal_relocs
; irel
< irelend
; irel
++, rel_count
++)
1830 if ((ELF32_R_TYPE (irel
->r_info
) != (int) R_MICROBLAZE_64_PCREL
)
1831 && (ELF32_R_TYPE (irel
->r_info
) != (int) R_MICROBLAZE_64
)
1832 && (ELF32_R_TYPE (irel
->r_info
) != (int) R_MICROBLAZE_TEXTREL_64
))
1833 continue; /* Can't delete this reloc. */
1835 /* Get the section contents. */
1836 if (contents
== NULL
)
1838 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
1839 contents
= elf_section_data (sec
)->this_hdr
.contents
;
1842 contents
= (bfd_byte
*) bfd_malloc (sec
->size
);
1843 if (contents
== NULL
)
1845 free_contents
= contents
;
1847 if (!bfd_get_section_contents (abfd
, sec
, contents
,
1848 (file_ptr
) 0, sec
->size
))
1850 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1854 /* Get the value of the symbol referred to by the reloc. */
1855 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
1857 /* A local symbol. */
1860 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
1861 if (isym
->st_shndx
== SHN_UNDEF
)
1862 sym_sec
= bfd_und_section_ptr
;
1863 else if (isym
->st_shndx
== SHN_ABS
)
1864 sym_sec
= bfd_abs_section_ptr
;
1865 else if (isym
->st_shndx
== SHN_COMMON
)
1866 sym_sec
= bfd_com_section_ptr
;
1868 sym_sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
1870 symval
= _bfd_elf_rela_local_sym (abfd
, isym
, &sym_sec
, irel
);
1875 struct elf_link_hash_entry
*h
;
1877 indx
= ELF32_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
1878 h
= elf_sym_hashes (abfd
)[indx
];
1879 BFD_ASSERT (h
!= NULL
);
1881 if (h
->root
.type
!= bfd_link_hash_defined
1882 && h
->root
.type
!= bfd_link_hash_defweak
)
1883 /* This appears to be a reference to an undefined
1884 symbol. Just ignore it--it will be caught by the
1885 regular reloc processing. */
1888 symval
= (h
->root
.u
.def
.value
1889 + h
->root
.u
.def
.section
->output_section
->vma
1890 + h
->root
.u
.def
.section
->output_offset
);
1893 /* If this is a PC-relative reloc, subtract the instr offset from
1894 the symbol value. */
1895 if (ELF32_R_TYPE (irel
->r_info
) == (int) R_MICROBLAZE_64_PCREL
)
1897 symval
= symval
+ irel
->r_addend
1899 + sec
->output_section
->vma
1900 + sec
->output_offset
);
1902 else if (ELF32_R_TYPE (irel
->r_info
) == (int) R_MICROBLAZE_TEXTREL_64
)
1904 symval
= symval
+ irel
->r_addend
- (sec
->output_section
->vma
);
1907 symval
+= irel
->r_addend
;
1909 if ((symval
& 0xffff8000) == 0
1910 || (symval
& 0xffff8000) == 0xffff8000)
1912 /* We can delete this instruction. */
1913 sdata
->relax
[sdata
->relax_count
].addr
= irel
->r_offset
;
1914 sdata
->relax
[sdata
->relax_count
].size
= INST_WORD_SIZE
;
1915 sdata
->relax_count
++;
1917 /* Rewrite relocation type. */
1918 switch ((enum elf_microblaze_reloc_type
) ELF32_R_TYPE (irel
->r_info
))
1920 case R_MICROBLAZE_64_PCREL
:
1921 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1922 (int) R_MICROBLAZE_32_PCREL_LO
);
1924 case R_MICROBLAZE_64
:
1925 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1926 (int) R_MICROBLAZE_32_LO
);
1928 case R_MICROBLAZE_TEXTREL_64
:
1929 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1930 (int) R_MICROBLAZE_TEXTREL_32_LO
);
1933 /* Cannot happen. */
1937 } /* Loop through all relocations. */
1939 /* Loop through the relocs again, and see if anything needs to change. */
1940 if (sdata
->relax_count
> 0)
1942 shndx
= _bfd_elf_section_from_bfd_section (abfd
, sec
);
1944 sdata
->relax
[sdata
->relax_count
].addr
= sec
->size
;
1946 for (irel
= internal_relocs
; irel
< irelend
; irel
++, rel_count
++)
1950 /* Get the new reloc address. */
1951 nraddr
= irel
->r_offset
- calc_fixup (irel
->r_offset
, 0, sec
);
1952 switch ((enum elf_microblaze_reloc_type
) ELF32_R_TYPE (irel
->r_info
))
1956 case R_MICROBLAZE_64_PCREL
:
1958 case R_MICROBLAZE_TEXTREL_64
:
1959 case R_MICROBLAZE_TEXTREL_32_LO
:
1960 case R_MICROBLAZE_64
:
1961 case R_MICROBLAZE_32_LO
:
1962 /* If this reloc is against a symbol defined in this
1963 section, we must check the addend to see it will put the value in
1964 range to be adjusted, and hence must be changed. */
1965 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
1967 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
1968 /* Only handle relocs against .text. */
1969 if (isym
->st_shndx
== shndx
1970 && ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
)
1971 irel
->r_addend
-= calc_fixup (irel
->r_addend
, 0, sec
);
1974 case R_MICROBLAZE_NONE
:
1975 case R_MICROBLAZE_32_NONE
:
1977 /* This was a PC-relative instruction that was
1978 completely resolved. */
1980 bfd_vma target_address
;
1981 target_address
= irel
->r_addend
+ irel
->r_offset
;
1982 sfix
= calc_fixup (irel
->r_offset
, 0, sec
);
1983 efix
= calc_fixup (target_address
, 0, sec
);
1984 irel
->r_addend
-= (efix
- sfix
);
1985 /* Should use HOWTO. */
1986 microblaze_bfd_write_imm_value_32 (abfd
, contents
+ irel
->r_offset
,
1990 case R_MICROBLAZE_64_NONE
:
1992 /* This was a PC-relative 64-bit instruction that was
1993 completely resolved. */
1995 bfd_vma target_address
;
1996 target_address
= irel
->r_addend
+ irel
->r_offset
+ INST_WORD_SIZE
;
1997 sfix
= calc_fixup (irel
->r_offset
+ INST_WORD_SIZE
, 0, sec
);
1998 efix
= calc_fixup (target_address
, 0, sec
);
1999 irel
->r_addend
-= (efix
- sfix
);
2000 microblaze_bfd_write_imm_value_32 (abfd
, contents
+ irel
->r_offset
2001 + INST_WORD_SIZE
, irel
->r_addend
);
2005 irel
->r_offset
= nraddr
;
2006 } /* Change all relocs in this section. */
2008 /* Look through all other sections. */
2009 for (o
= abfd
->sections
; o
!= NULL
; o
= o
->next
)
2011 Elf_Internal_Rela
*irelocs
;
2012 Elf_Internal_Rela
*irelscan
, *irelscanend
;
2013 bfd_byte
*ocontents
;
2016 || (o
->flags
& SEC_RELOC
) == 0
2017 || o
->reloc_count
== 0)
2020 /* We always cache the relocs. Perhaps, if info->keep_memory is
2021 FALSE, we should free them, if we are permitted to. */
2023 irelocs
= _bfd_elf_link_read_relocs (abfd
, o
, NULL
, NULL
, true);
2024 if (irelocs
== NULL
)
2028 irelscanend
= irelocs
+ o
->reloc_count
;
2029 for (irelscan
= irelocs
; irelscan
< irelscanend
; irelscan
++)
2031 if ((ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32
)
2032 || (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32_NONE
))
2034 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2036 /* Look at the reloc only if the value has been resolved. */
2037 if (isym
->st_shndx
== shndx
2038 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2040 if (ocontents
== NULL
)
2042 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2043 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2046 /* We always cache the section contents.
2047 Perhaps, if info->keep_memory is FALSE, we
2048 should free them, if we are permitted to. */
2049 if (o
->rawsize
== 0)
2050 o
->rawsize
= o
->size
;
2051 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2052 if (ocontents
== NULL
)
2054 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2058 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2062 irelscan
->r_addend
-= calc_fixup (irelscan
->r_addend
, 0, sec
);
2064 else if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32_SYM_OP_SYM
)
2066 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2068 /* Look at the reloc only if the value has been resolved. */
2069 if (ocontents
== NULL
)
2071 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2072 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2075 /* We always cache the section contents.
2076 Perhaps, if info->keep_memory is FALSE, we
2077 should free them, if we are permitted to. */
2079 if (o
->rawsize
== 0)
2080 o
->rawsize
= o
->size
;
2081 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2082 if (ocontents
== NULL
)
2084 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2088 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2091 irelscan
->r_addend
-= calc_fixup (irelscan
->r_addend
2097 else if ((ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32_PCREL_LO
)
2098 || (ELF32_R_TYPE (irelscan
->r_info
)
2099 == (int) R_MICROBLAZE_32_LO
)
2100 || (ELF32_R_TYPE (irelscan
->r_info
)
2101 == (int) R_MICROBLAZE_TEXTREL_32_LO
))
2103 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2105 /* Look at the reloc only if the value has been resolved. */
2106 if (isym
->st_shndx
== shndx
2107 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2110 bfd_vma target_address
;
2112 if (ocontents
== NULL
)
2114 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2115 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2118 /* We always cache the section contents.
2119 Perhaps, if info->keep_memory is FALSE, we
2120 should free them, if we are permitted to. */
2121 if (o
->rawsize
== 0)
2122 o
->rawsize
= o
->size
;
2123 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2124 if (ocontents
== NULL
)
2126 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2130 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2134 unsigned long instr
= bfd_get_32 (abfd
, ocontents
+ irelscan
->r_offset
);
2135 immediate
= instr
& 0x0000ffff;
2136 target_address
= immediate
;
2137 offset
= calc_fixup (target_address
, 0, sec
);
2138 immediate
-= offset
;
2139 irelscan
->r_addend
-= offset
;
2140 microblaze_bfd_write_imm_value_32 (abfd
, ocontents
+ irelscan
->r_offset
,
2141 irelscan
->r_addend
);
2145 if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_64
2146 || (ELF32_R_TYPE (irelscan
->r_info
)
2147 == (int) R_MICROBLAZE_TEXTREL_64
))
2149 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2151 /* Look at the reloc only if the value has been resolved. */
2152 if (isym
->st_shndx
== shndx
2153 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2155 if (ocontents
== NULL
)
2157 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2158 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2161 /* We always cache the section contents.
2162 Perhaps, if info->keep_memory is FALSE, we
2163 should free them, if we are permitted to. */
2165 if (o
->rawsize
== 0)
2166 o
->rawsize
= o
->size
;
2167 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2168 if (ocontents
== NULL
)
2170 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2174 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2177 offset
= calc_fixup (irelscan
->r_addend
, 0, sec
);
2178 irelscan
->r_addend
-= offset
;
2181 else if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_64_PCREL
)
2183 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2185 /* Look at the reloc only if the value has been resolved. */
2186 if (isym
->st_shndx
== shndx
2187 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2190 bfd_vma target_address
;
2192 if (ocontents
== NULL
)
2194 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2195 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2198 /* We always cache the section contents.
2199 Perhaps, if info->keep_memory is FALSE, we
2200 should free them, if we are permitted to. */
2201 if (o
->rawsize
== 0)
2202 o
->rawsize
= o
->size
;
2203 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2204 if (ocontents
== NULL
)
2206 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2210 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2213 unsigned long instr_hi
= bfd_get_32 (abfd
, ocontents
2214 + irelscan
->r_offset
);
2215 unsigned long instr_lo
= bfd_get_32 (abfd
, ocontents
2216 + irelscan
->r_offset
2218 immediate
= (instr_hi
& 0x0000ffff) << 16;
2219 immediate
|= (instr_lo
& 0x0000ffff);
2220 target_address
= immediate
;
2221 offset
= calc_fixup (target_address
, 0, sec
);
2222 immediate
-= offset
;
2223 irelscan
->r_addend
-= offset
;
2224 microblaze_bfd_write_imm_value_64 (abfd
, ocontents
2225 + irelscan
->r_offset
, immediate
);
2231 /* Adjust the local symbols defined in this section. */
2232 isymend
= isymbuf
+ symtab_hdr
->sh_info
;
2233 for (isym
= isymbuf
; isym
< isymend
; isym
++)
2235 if (isym
->st_shndx
== shndx
)
2237 isym
->st_value
-= calc_fixup (isym
->st_value
, 0, sec
);
2239 isym
->st_size
-= calc_fixup (isym
->st_value
, isym
->st_size
, sec
);
2243 /* Now adjust the global symbols defined in this section. */
2244 isym
= isymbuf
+ symtab_hdr
->sh_info
;
2245 symcount
= (symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
)) - symtab_hdr
->sh_info
;
2246 for (sym_index
= 0; sym_index
< symcount
; sym_index
++)
2248 sym_hash
= elf_sym_hashes (abfd
)[sym_index
];
2249 if ((sym_hash
->root
.type
== bfd_link_hash_defined
2250 || sym_hash
->root
.type
== bfd_link_hash_defweak
)
2251 && sym_hash
->root
.u
.def
.section
== sec
)
2253 sym_hash
->root
.u
.def
.value
-= calc_fixup (sym_hash
->root
.u
.def
.value
,
2256 sym_hash
->size
-= calc_fixup (sym_hash
->root
.u
.def
.value
,
2257 sym_hash
->size
, sec
);
2261 /* Physically move the code and change the cooked size. */
2262 dest
= sdata
->relax
[0].addr
;
2263 for (i
= 0; i
< sdata
->relax_count
; i
++)
2266 src
= sdata
->relax
[i
].addr
+ sdata
->relax
[i
].size
;
2267 len
= (sdata
->relax
[i
+1].addr
- sdata
->relax
[i
].addr
2268 - sdata
->relax
[i
].size
);
2270 memmove (contents
+ dest
, contents
+ src
, len
);
2271 sec
->size
-= sdata
->relax
[i
].size
;
2275 elf_section_data (sec
)->relocs
= internal_relocs
;
2278 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2279 free_contents
= NULL
;
2281 symtab_hdr
->contents
= (bfd_byte
*) isymbuf
;
2287 if (free_contents
!= NULL
)
2289 if (!link_info
->keep_memory
)
2290 free (free_contents
);
2292 /* Cache the section contents for elf_link_input_bfd. */
2293 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2294 free_contents
= NULL
;
2297 if (sdata
->relax_count
== 0)
2300 free (sdata
->relax
);
2301 sdata
->relax
= NULL
;
2309 free (free_contents
);
2310 free (sdata
->relax
);
2311 sdata
->relax
= NULL
;
2312 sdata
->relax_count
= 0;
2316 /* Return the section that should be marked against GC for a given
2320 microblaze_elf_gc_mark_hook (asection
*sec
,
2321 struct bfd_link_info
* info
,
2322 Elf_Internal_Rela
* rel
,
2323 struct elf_link_hash_entry
* h
,
2324 Elf_Internal_Sym
* sym
)
2327 switch (ELF32_R_TYPE (rel
->r_info
))
2329 case R_MICROBLAZE_GNU_VTINHERIT
:
2330 case R_MICROBLAZE_GNU_VTENTRY
:
2334 return _bfd_elf_gc_mark_hook (sec
, info
, rel
, h
, sym
);
2339 #define PLT_ENTRY_SIZE 16
2341 #define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
2342 #define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
2343 #define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
2344 #define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
2345 #define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
2348 update_local_sym_info (bfd
*abfd
,
2349 Elf_Internal_Shdr
*symtab_hdr
,
2350 unsigned long r_symndx
,
2351 unsigned int tls_type
)
2353 bfd_signed_vma
*local_got_refcounts
= elf_local_got_refcounts (abfd
);
2354 unsigned char *local_got_tls_masks
;
2356 if (local_got_refcounts
== NULL
)
2358 bfd_size_type size
= symtab_hdr
->sh_info
;
2360 size
*= (sizeof (*local_got_refcounts
) + sizeof (*local_got_tls_masks
));
2361 local_got_refcounts
= bfd_zalloc (abfd
, size
);
2362 if (local_got_refcounts
== NULL
)
2364 elf_local_got_refcounts (abfd
) = local_got_refcounts
;
2367 local_got_tls_masks
=
2368 (unsigned char *) (local_got_refcounts
+ symtab_hdr
->sh_info
);
2369 local_got_tls_masks
[r_symndx
] |= tls_type
;
2370 local_got_refcounts
[r_symndx
] += 1;
2374 /* Look through the relocs for a section during the first phase. */
2377 microblaze_elf_check_relocs (bfd
* abfd
,
2378 struct bfd_link_info
* info
,
2380 const Elf_Internal_Rela
* relocs
)
2382 Elf_Internal_Shdr
* symtab_hdr
;
2383 struct elf_link_hash_entry
** sym_hashes
;
2384 const Elf_Internal_Rela
* rel
;
2385 const Elf_Internal_Rela
* rel_end
;
2386 struct elf32_mb_link_hash_table
*htab
;
2387 asection
*sreloc
= NULL
;
2389 if (bfd_link_relocatable (info
))
2392 htab
= elf32_mb_hash_table (info
);
2396 symtab_hdr
= & elf_tdata (abfd
)->symtab_hdr
;
2397 sym_hashes
= elf_sym_hashes (abfd
);
2399 rel_end
= relocs
+ sec
->reloc_count
;
2401 for (rel
= relocs
; rel
< rel_end
; rel
++)
2403 unsigned int r_type
;
2404 struct elf_link_hash_entry
* h
;
2405 unsigned long r_symndx
;
2406 unsigned char tls_type
= 0;
2408 r_symndx
= ELF32_R_SYM (rel
->r_info
);
2409 r_type
= ELF32_R_TYPE (rel
->r_info
);
2411 if (r_symndx
< symtab_hdr
->sh_info
)
2415 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
2416 while (h
->root
.type
== bfd_link_hash_indirect
2417 || h
->root
.type
== bfd_link_hash_warning
)
2418 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2423 /* This relocation describes the C++ object vtable hierarchy.
2424 Reconstruct it for later use during GC. */
2425 case R_MICROBLAZE_GNU_VTINHERIT
:
2426 if (!bfd_elf_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
2430 /* This relocation describes which C++ vtable entries are actually
2431 used. Record for later use during GC. */
2432 case R_MICROBLAZE_GNU_VTENTRY
:
2433 if (!bfd_elf_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
2437 /* This relocation requires .plt entry. */
2438 case R_MICROBLAZE_PLT_64
:
2442 h
->plt
.refcount
+= 1;
2446 /* This relocation requires .got entry. */
2447 case R_MICROBLAZE_TLSGD
:
2448 tls_type
|= (TLS_TLS
| TLS_GD
);
2450 case R_MICROBLAZE_TLSLD
:
2451 tls_type
|= (TLS_TLS
| TLS_LD
);
2454 sec
->has_tls_reloc
= 1;
2456 case R_MICROBLAZE_GOT_64
:
2457 if (htab
->elf
.sgot
== NULL
)
2459 if (htab
->elf
.dynobj
== NULL
)
2460 htab
->elf
.dynobj
= abfd
;
2461 if (!_bfd_elf_create_got_section (htab
->elf
.dynobj
, info
))
2466 h
->got
.refcount
+= 1;
2467 elf32_mb_hash_entry (h
)->tls_mask
|= tls_type
;
2471 if (! update_local_sym_info(abfd
, symtab_hdr
, r_symndx
, tls_type
) )
2476 case R_MICROBLAZE_GOTOFF_64
:
2477 case R_MICROBLAZE_GOTOFF_32
:
2478 if (htab
->elf
.sgot
== NULL
)
2480 if (htab
->elf
.dynobj
== NULL
)
2481 htab
->elf
.dynobj
= abfd
;
2482 if (!_bfd_elf_create_got_section (htab
->elf
.dynobj
, info
))
2487 case R_MICROBLAZE_64
:
2488 case R_MICROBLAZE_64_PCREL
:
2489 case R_MICROBLAZE_32
:
2491 if (h
!= NULL
&& !bfd_link_pic (info
))
2493 /* we may need a copy reloc. */
2496 /* we may also need a .plt entry. */
2497 h
->plt
.refcount
+= 1;
2498 if (ELF32_R_TYPE (rel
->r_info
) != R_MICROBLAZE_64_PCREL
)
2499 h
->pointer_equality_needed
= 1;
2503 /* If we are creating a shared library, and this is a reloc
2504 against a global symbol, or a non PC relative reloc
2505 against a local symbol, then we need to copy the reloc
2506 into the shared library. However, if we are linking with
2507 -Bsymbolic, we do not need to copy a reloc against a
2508 global symbol which is defined in an object we are
2509 including in the link (i.e., DEF_REGULAR is set). At
2510 this point we have not seen all the input files, so it is
2511 possible that DEF_REGULAR is not set now but will be set
2512 later (it is never cleared). In case of a weak definition,
2513 DEF_REGULAR may be cleared later by a strong definition in
2514 a shared library. We account for that possibility below by
2515 storing information in the relocs_copied field of the hash
2516 table entry. A similar situation occurs when creating
2517 shared libraries and symbol visibility changes render the
2520 If on the other hand, we are creating an executable, we
2521 may need to keep relocations for symbols satisfied by a
2522 dynamic library if we manage to avoid copy relocs for the
2525 if ((bfd_link_pic (info
)
2526 && (sec
->flags
& SEC_ALLOC
) != 0
2527 && (r_type
!= R_MICROBLAZE_64_PCREL
2529 && (! info
->symbolic
2530 || h
->root
.type
== bfd_link_hash_defweak
2531 || !h
->def_regular
))))
2532 || (!bfd_link_pic (info
)
2533 && (sec
->flags
& SEC_ALLOC
) != 0
2535 && (h
->root
.type
== bfd_link_hash_defweak
2536 || !h
->def_regular
)))
2538 struct elf_dyn_relocs
*p
;
2539 struct elf_dyn_relocs
**head
;
2541 /* When creating a shared object, we must copy these
2542 relocs into the output file. We create a reloc
2543 section in dynobj and make room for the reloc. */
2549 if (htab
->elf
.dynobj
== NULL
)
2550 htab
->elf
.dynobj
= abfd
;
2551 dynobj
= htab
->elf
.dynobj
;
2553 sreloc
= _bfd_elf_make_dynamic_reloc_section (sec
, dynobj
,
2559 /* If this is a global symbol, we count the number of
2560 relocations we need for this symbol. */
2562 head
= &h
->dyn_relocs
;
2565 /* Track dynamic relocs needed for local syms too.
2566 We really need local syms available to do this
2570 Elf_Internal_Sym
*isym
;
2573 isym
= bfd_sym_from_r_symndx (&htab
->elf
.sym_cache
,
2578 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
2582 vpp
= &elf_section_data (s
)->local_dynrel
;
2583 head
= (struct elf_dyn_relocs
**) vpp
;
2587 if (p
== NULL
|| p
->sec
!= sec
)
2589 size_t amt
= sizeof *p
;
2590 p
= ((struct elf_dyn_relocs
*)
2591 bfd_alloc (htab
->elf
.dynobj
, amt
));
2602 if (r_type
== R_MICROBLAZE_64_PCREL
)
2613 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2616 microblaze_elf_copy_indirect_symbol (struct bfd_link_info
*info
,
2617 struct elf_link_hash_entry
*dir
,
2618 struct elf_link_hash_entry
*ind
)
2620 struct elf32_mb_link_hash_entry
*edir
, *eind
;
2622 edir
= (struct elf32_mb_link_hash_entry
*) dir
;
2623 eind
= (struct elf32_mb_link_hash_entry
*) ind
;
2625 edir
->tls_mask
|= eind
->tls_mask
;
2627 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
2631 microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info
*info
,
2632 struct elf_link_hash_entry
*h
)
2634 struct elf32_mb_link_hash_table
*htab
;
2636 unsigned int power_of_two
;
2638 htab
= elf32_mb_hash_table (info
);
2642 /* If this is a function, put it in the procedure linkage table. We
2643 will fill in the contents of the procedure linkage table later,
2644 when we know the address of the .got section. */
2645 if (h
->type
== STT_FUNC
2648 if (h
->plt
.refcount
<= 0
2649 || SYMBOL_CALLS_LOCAL (info
, h
)
2650 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
2651 && h
->root
.type
== bfd_link_hash_undefweak
))
2653 /* This case can occur if we saw a PLT reloc in an input
2654 file, but the symbol was never referred to by a dynamic
2655 object, or if all references were garbage collected. In
2656 such a case, we don't actually need to build a procedure
2657 linkage table, and we can just do a PC32 reloc instead. */
2658 h
->plt
.offset
= (bfd_vma
) -1;
2665 /* It's possible that we incorrectly decided a .plt reloc was
2666 needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
2667 check_relocs. We can't decide accurately between function and
2668 non-function syms in check-relocs; Objects loaded later in
2669 the link may change h->type. So fix it now. */
2670 h
->plt
.offset
= (bfd_vma
) -1;
2672 /* If this is a weak symbol, and there is a real definition, the
2673 processor independent code will have arranged for us to see the
2674 real definition first, and we can just use the same value. */
2675 if (h
->is_weakalias
)
2677 struct elf_link_hash_entry
*def
= weakdef (h
);
2678 BFD_ASSERT (def
->root
.type
== bfd_link_hash_defined
);
2679 h
->root
.u
.def
.section
= def
->root
.u
.def
.section
;
2680 h
->root
.u
.def
.value
= def
->root
.u
.def
.value
;
2684 /* This is a reference to a symbol defined by a dynamic object which
2685 is not a function. */
2687 /* If we are creating a shared library, we must presume that the
2688 only references to the symbol are via the global offset table.
2689 For such cases we need not do anything here; the relocations will
2690 be handled correctly by relocate_section. */
2691 if (bfd_link_pic (info
))
2694 /* If there are no references to this symbol that do not use the
2695 GOT, we don't need to generate a copy reloc. */
2696 if (!h
->non_got_ref
)
2699 /* If -z nocopyreloc was given, we won't generate them either. */
2700 if (info
->nocopyreloc
)
2706 /* If we don't find any dynamic relocs in read-only sections, then
2707 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
2708 if (!_bfd_elf_readonly_dynrelocs (h
))
2714 /* We must allocate the symbol in our .dynbss section, which will
2715 become part of the .bss section of the executable. There will be
2716 an entry for this symbol in the .dynsym section. The dynamic
2717 object will contain position independent code, so all references
2718 from the dynamic object to this symbol will go through the global
2719 offset table. The dynamic linker will use the .dynsym entry to
2720 determine the address it must put in the global offset table, so
2721 both the dynamic object and the regular object will refer to the
2722 same memory location for the variable. */
2724 /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
2725 to copy the initial value out of the dynamic object and into the
2726 runtime process image. */
2727 if ((h
->root
.u
.def
.section
->flags
& SEC_READONLY
) != 0)
2729 s
= htab
->elf
.sdynrelro
;
2730 srel
= htab
->elf
.sreldynrelro
;
2734 s
= htab
->elf
.sdynbss
;
2735 srel
= htab
->elf
.srelbss
;
2737 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0)
2739 srel
->size
+= sizeof (Elf32_External_Rela
);
2743 /* We need to figure out the alignment required for this symbol. I
2744 have no idea how ELF linkers handle this. */
2745 power_of_two
= bfd_log2 (h
->size
);
2746 if (power_of_two
> 3)
2749 /* Apply the required alignment. */
2750 s
->size
= BFD_ALIGN (s
->size
, (bfd_size_type
) (1 << power_of_two
));
2751 if (power_of_two
> s
->alignment_power
)
2753 if (!bfd_set_section_alignment (s
, power_of_two
))
2757 /* Define the symbol as being at this point in the section. */
2758 h
->root
.u
.def
.section
= s
;
2759 h
->root
.u
.def
.value
= s
->size
;
2761 /* Increment the section size to make room for the symbol. */
2766 /* Allocate space in .plt, .got and associated reloc sections for
2770 allocate_dynrelocs (struct elf_link_hash_entry
*h
, void * dat
)
2772 struct bfd_link_info
*info
;
2773 struct elf32_mb_link_hash_table
*htab
;
2774 struct elf32_mb_link_hash_entry
*eh
;
2775 struct elf_dyn_relocs
*p
;
2777 if (h
->root
.type
== bfd_link_hash_indirect
)
2780 info
= (struct bfd_link_info
*) dat
;
2781 htab
= elf32_mb_hash_table (info
);
2785 if (htab
->elf
.dynamic_sections_created
2786 && h
->plt
.refcount
> 0)
2788 /* Make sure this symbol is output as a dynamic symbol.
2789 Undefined weak syms won't yet be marked as dynamic. */
2790 if (h
->dynindx
== -1
2791 && !h
->forced_local
)
2793 if (! bfd_elf_link_record_dynamic_symbol (info
, h
))
2797 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info
), h
))
2799 asection
*s
= htab
->elf
.splt
;
2801 /* The first entry in .plt is reserved. */
2803 s
->size
= PLT_ENTRY_SIZE
;
2805 h
->plt
.offset
= s
->size
;
2807 /* If this symbol is not defined in a regular file, and we are
2808 not generating a shared library, then set the symbol to this
2809 location in the .plt. This is required to make function
2810 pointers compare as equal between the normal executable and
2811 the shared library. */
2812 if (! bfd_link_pic (info
)
2815 h
->root
.u
.def
.section
= s
;
2816 h
->root
.u
.def
.value
= h
->plt
.offset
;
2819 /* Make room for this entry. */
2820 s
->size
+= PLT_ENTRY_SIZE
;
2822 /* We also need to make an entry in the .got.plt section, which
2823 will be placed in the .got section by the linker script. */
2824 htab
->elf
.sgotplt
->size
+= 4;
2826 /* We also need to make an entry in the .rel.plt section. */
2827 htab
->elf
.srelplt
->size
+= sizeof (Elf32_External_Rela
);
2831 h
->plt
.offset
= (bfd_vma
) -1;
2837 h
->plt
.offset
= (bfd_vma
) -1;
2841 eh
= (struct elf32_mb_link_hash_entry
*) h
;
2842 if (h
->got
.refcount
> 0)
2847 /* Make sure this symbol is output as a dynamic symbol.
2848 Undefined weak syms won't yet be marked as dynamic. */
2849 if (h
->dynindx
== -1
2850 && !h
->forced_local
)
2852 if (! bfd_elf_link_record_dynamic_symbol (info
, h
))
2857 if ((eh
->tls_mask
& TLS_TLS
) != 0)
2859 /* Handle TLS Symbol */
2860 if ((eh
->tls_mask
& TLS_LD
) != 0)
2862 if (!eh
->elf
.def_dynamic
)
2863 /* We'll just use htab->tlsld_got.offset. This should
2864 always be the case. It's a little odd if we have
2865 a local dynamic reloc against a non-local symbol. */
2866 htab
->tlsld_got
.refcount
+= 1;
2870 if ((eh
->tls_mask
& TLS_GD
) != 0)
2875 /* Regular (non-TLS) symbol */
2880 h
->got
.offset
= (bfd_vma
) -1;
2885 h
->got
.offset
= s
->size
;
2887 htab
->elf
.srelgot
->size
+= need
* (sizeof (Elf32_External_Rela
) / 4);
2891 h
->got
.offset
= (bfd_vma
) -1;
2893 if (h
->dyn_relocs
== NULL
)
2896 /* In the shared -Bsymbolic case, discard space allocated for
2897 dynamic pc-relative relocs against symbols which turn out to be
2898 defined in regular objects. For the normal shared case, discard
2899 space for pc-relative relocs that have become local due to symbol
2900 visibility changes. */
2902 if (bfd_link_pic (info
))
2908 struct elf_dyn_relocs
**pp
;
2910 for (pp
= &h
->dyn_relocs
; (p
= *pp
) != NULL
; )
2912 p
->count
-= p
->pc_count
;
2920 else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
2921 h
->dyn_relocs
= NULL
;
2925 /* For the non-shared case, discard space for relocs against
2926 symbols which turn out to need copy relocs or are not
2932 || (htab
->elf
.dynamic_sections_created
2933 && (h
->root
.type
== bfd_link_hash_undefweak
2934 || h
->root
.type
== bfd_link_hash_undefined
))))
2936 /* Make sure this symbol is output as a dynamic symbol.
2937 Undefined weak syms won't yet be marked as dynamic. */
2938 if (h
->dynindx
== -1
2939 && !h
->forced_local
)
2941 if (! bfd_elf_link_record_dynamic_symbol (info
, h
))
2945 /* If that succeeded, we know we'll be keeping all the
2947 if (h
->dynindx
!= -1)
2951 h
->dyn_relocs
= NULL
;
2956 /* Finally, allocate space. */
2957 for (p
= h
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
2959 asection
*sreloc
= elf_section_data (p
->sec
)->sreloc
;
2960 sreloc
->size
+= p
->count
* sizeof (Elf32_External_Rela
);
2966 /* Set the sizes of the dynamic sections. */
2969 microblaze_elf_late_size_sections (bfd
*output_bfd ATTRIBUTE_UNUSED
,
2970 struct bfd_link_info
*info
)
2972 struct elf32_mb_link_hash_table
*htab
;
2977 htab
= elf32_mb_hash_table (info
);
2981 dynobj
= htab
->elf
.dynobj
;
2985 /* Set up .got offsets for local syms, and space for local dynamic
2987 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
2989 bfd_signed_vma
*local_got
;
2990 bfd_signed_vma
*end_local_got
;
2991 bfd_size_type locsymcount
;
2992 Elf_Internal_Shdr
*symtab_hdr
;
2993 unsigned char *lgot_masks
;
2996 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
)
2999 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
3001 struct elf_dyn_relocs
*p
;
3003 for (p
= ((struct elf_dyn_relocs
*)
3004 elf_section_data (s
)->local_dynrel
);
3008 if (!bfd_is_abs_section (p
->sec
)
3009 && bfd_is_abs_section (p
->sec
->output_section
))
3011 /* Input section has been discarded, either because
3012 it is a copy of a linkonce section or due to
3013 linker script /DISCARD/, so we'll be discarding
3016 else if (p
->count
!= 0)
3018 srel
= elf_section_data (p
->sec
)->sreloc
;
3019 srel
->size
+= p
->count
* sizeof (Elf32_External_Rela
);
3020 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
3021 info
->flags
|= DF_TEXTREL
;
3026 local_got
= elf_local_got_refcounts (ibfd
);
3030 symtab_hdr
= &elf_tdata (ibfd
)->symtab_hdr
;
3031 locsymcount
= symtab_hdr
->sh_info
;
3032 end_local_got
= local_got
+ locsymcount
;
3033 lgot_masks
= (unsigned char *) end_local_got
;
3035 srel
= htab
->elf
.srelgot
;
3037 for (; local_got
< end_local_got
; ++local_got
, ++lgot_masks
)
3041 unsigned int need
= 0;
3042 if ((*lgot_masks
& TLS_TLS
) != 0)
3044 if ((*lgot_masks
& TLS_GD
) != 0)
3046 if ((*lgot_masks
& TLS_LD
) != 0)
3047 htab
->tlsld_got
.refcount
+= 1;
3054 *local_got
= (bfd_vma
) -1;
3058 *local_got
= s
->size
;
3060 if (bfd_link_pic (info
))
3061 srel
->size
+= need
* (sizeof (Elf32_External_Rela
) / 4);
3065 *local_got
= (bfd_vma
) -1;
3069 /* Allocate global sym .plt and .got entries, and space for global
3070 sym dynamic relocs. */
3071 elf_link_hash_traverse (elf_hash_table (info
), allocate_dynrelocs
, info
);
3073 if (htab
->tlsld_got
.refcount
> 0)
3075 htab
->tlsld_got
.offset
= htab
->elf
.sgot
->size
;
3076 htab
->elf
.sgot
->size
+= 8;
3077 if (bfd_link_pic (info
))
3078 htab
->elf
.srelgot
->size
+= sizeof (Elf32_External_Rela
);
3081 htab
->tlsld_got
.offset
= (bfd_vma
) -1;
3083 if (elf_hash_table (info
)->dynamic_sections_created
)
3085 /* Make space for the trailing nop in .plt. */
3086 if (htab
->elf
.splt
->size
> 0)
3087 htab
->elf
.splt
->size
+= 4;
3090 /* The check_relocs and adjust_dynamic_symbol entry points have
3091 determined the sizes of the various dynamic sections. Allocate
3093 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
3098 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
3101 /* It's OK to base decisions on the section name, because none
3102 of the dynobj section names depend upon the input files. */
3103 name
= bfd_section_name (s
);
3105 if (startswith (name
, ".rela"))
3109 /* If we don't need this section, strip it from the
3110 output file. This is to handle .rela.bss and
3111 .rela.plt. We must create it in
3112 create_dynamic_sections, because it must be created
3113 before the linker maps input sections to output
3114 sections. The linker does that before
3115 adjust_dynamic_symbol is called, and it is that
3116 function which decides whether anything needs to go
3117 into these sections. */
3122 /* We use the reloc_count field as a counter if we need
3123 to copy relocs into the output file. */
3127 else if (s
!= htab
->elf
.splt
3128 && s
!= htab
->elf
.sgot
3129 && s
!= htab
->elf
.sgotplt
3130 && s
!= htab
->elf
.sdynbss
3131 && s
!= htab
->elf
.sdynrelro
)
3133 /* It's not one of our sections, so don't allocate space. */
3139 s
->flags
|= SEC_EXCLUDE
;
3143 /* Allocate memory for the section contents. */
3144 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
3145 Unused entries should be reclaimed before the section's contents
3146 are written out, but at the moment this does not happen. Thus in
3147 order to prevent writing out garbage, we initialise the section's
3148 contents to zero. */
3149 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
3150 if (s
->contents
== NULL
&& s
->size
!= 0)
3154 /* ??? Force DF_BIND_NOW? */
3155 info
->flags
|= DF_BIND_NOW
;
3156 return _bfd_elf_add_dynamic_tags (output_bfd
, info
, true);
3159 /* Finish up dynamic symbol handling. We set the contents of various
3160 dynamic sections here. */
3163 microblaze_elf_finish_dynamic_symbol (bfd
*output_bfd
,
3164 struct bfd_link_info
*info
,
3165 struct elf_link_hash_entry
*h
,
3166 Elf_Internal_Sym
*sym
)
3168 struct elf32_mb_link_hash_table
*htab
;
3169 struct elf32_mb_link_hash_entry
*eh
= elf32_mb_hash_entry(h
);
3171 htab
= elf32_mb_hash_table (info
);
3173 if (h
->plt
.offset
!= (bfd_vma
) -1)
3178 Elf_Internal_Rela rela
;
3184 /* This symbol has an entry in the procedure linkage table. Set
3186 BFD_ASSERT (h
->dynindx
!= -1);
3188 splt
= htab
->elf
.splt
;
3189 srela
= htab
->elf
.srelplt
;
3190 sgotplt
= htab
->elf
.sgotplt
;
3191 BFD_ASSERT (splt
!= NULL
&& srela
!= NULL
&& sgotplt
!= NULL
);
3193 plt_index
= h
->plt
.offset
/ PLT_ENTRY_SIZE
- 1; /* first entry reserved. */
3194 got_offset
= (plt_index
+ 3) * 4; /* 3 reserved ??? */
3195 got_addr
= got_offset
;
3197 /* For non-PIC objects we need absolute address of the GOT entry. */
3198 if (!bfd_link_pic (info
))
3199 got_addr
+= sgotplt
->output_section
->vma
+ sgotplt
->output_offset
;
3201 /* Fill in the entry in the procedure linkage table. */
3202 bfd_put_32 (output_bfd
, PLT_ENTRY_WORD_0
+ ((got_addr
>> 16) & 0xffff),
3203 splt
->contents
+ h
->plt
.offset
);
3204 if (bfd_link_pic (info
))
3205 bfd_put_32 (output_bfd
, PLT_ENTRY_WORD_1
+ (got_addr
& 0xffff),
3206 splt
->contents
+ h
->plt
.offset
+ 4);
3208 bfd_put_32 (output_bfd
, PLT_ENTRY_WORD_1_NOPIC
+ (got_addr
& 0xffff),
3209 splt
->contents
+ h
->plt
.offset
+ 4);
3210 bfd_put_32 (output_bfd
, (bfd_vma
) PLT_ENTRY_WORD_2
,
3211 splt
->contents
+ h
->plt
.offset
+ 8);
3212 bfd_put_32 (output_bfd
, (bfd_vma
) PLT_ENTRY_WORD_3
,
3213 splt
->contents
+ h
->plt
.offset
+ 12);
3215 /* Any additions to the .got section??? */
3216 /* bfd_put_32 (output_bfd,
3217 splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
3218 sgotplt->contents + got_offset); */
3220 /* Fill in the entry in the .rela.plt section. */
3221 rela
.r_offset
= (sgotplt
->output_section
->vma
3222 + sgotplt
->output_offset
3224 rela
.r_info
= ELF32_R_INFO (h
->dynindx
, R_MICROBLAZE_JUMP_SLOT
);
3226 loc
= srela
->contents
;
3227 loc
+= plt_index
* sizeof (Elf32_External_Rela
);
3228 bfd_elf32_swap_reloca_out (output_bfd
, &rela
, loc
);
3230 if (!h
->def_regular
)
3232 /* Mark the symbol as undefined, rather than as defined in
3233 the .plt section. Zero the value. */
3234 sym
->st_shndx
= SHN_UNDEF
;
3239 /* h->got.refcount to be checked ? */
3240 if ((h
->got
.offset
!= (bfd_vma
) -1)
3241 && ! ((h
->got
.offset
& 1)
3242 || IS_TLS_LD(eh
->tls_mask
) || IS_TLS_GD(eh
->tls_mask
)))
3248 /* This symbol has an entry in the global offset table. Set it
3251 sgot
= htab
->elf
.sgot
;
3252 srela
= htab
->elf
.srelgot
;
3253 BFD_ASSERT (sgot
!= NULL
&& srela
!= NULL
);
3255 offset
= (sgot
->output_section
->vma
+ sgot
->output_offset
3256 + (h
->got
.offset
&~ (bfd_vma
) 1));
3258 /* If this is a -Bsymbolic link, and the symbol is defined
3259 locally, we just want to emit a RELATIVE reloc. Likewise if
3260 the symbol was forced to be local because of a version file.
3261 The entry in the global offset table will already have been
3262 initialized in the relocate_section function. */
3263 if (bfd_link_pic (info
)
3264 && ((info
->symbolic
&& h
->def_regular
)
3265 || h
->dynindx
== -1))
3267 asection
*sec
= h
->root
.u
.def
.section
;
3270 value
= h
->root
.u
.def
.value
;
3271 if (sec
->output_section
!= NULL
)
3272 /* PR 21180: If the output section is NULL, then the symbol is no
3273 longer needed, and in theory the GOT entry is redundant. But
3274 it is too late to change our minds now... */
3275 value
+= sec
->output_section
->vma
+ sec
->output_offset
;
3277 microblaze_elf_output_dynamic_relocation (output_bfd
,
3278 srela
, srela
->reloc_count
++,
3280 R_MICROBLAZE_REL
, offset
,
3285 microblaze_elf_output_dynamic_relocation (output_bfd
,
3286 srela
, srela
->reloc_count
++,
3288 R_MICROBLAZE_GLOB_DAT
,
3292 bfd_put_32 (output_bfd
, (bfd_vma
) 0,
3293 sgot
->contents
+ (h
->got
.offset
&~ (bfd_vma
) 1));
3299 Elf_Internal_Rela rela
;
3302 /* This symbols needs a copy reloc. Set it up. */
3304 BFD_ASSERT (h
->dynindx
!= -1);
3306 rela
.r_offset
= (h
->root
.u
.def
.value
3307 + h
->root
.u
.def
.section
->output_section
->vma
3308 + h
->root
.u
.def
.section
->output_offset
);
3309 rela
.r_info
= ELF32_R_INFO (h
->dynindx
, R_MICROBLAZE_COPY
);
3311 if (h
->root
.u
.def
.section
== htab
->elf
.sdynrelro
)
3312 s
= htab
->elf
.sreldynrelro
;
3314 s
= htab
->elf
.srelbss
;
3315 loc
= s
->contents
+ s
->reloc_count
++ * sizeof (Elf32_External_Rela
);
3316 bfd_elf32_swap_reloca_out (output_bfd
, &rela
, loc
);
3319 /* Mark some specially defined symbols as absolute. */
3320 if (h
== htab
->elf
.hdynamic
3321 || h
== htab
->elf
.hgot
3322 || h
== htab
->elf
.hplt
)
3323 sym
->st_shndx
= SHN_ABS
;
3329 /* Finish up the dynamic sections. */
3332 microblaze_elf_finish_dynamic_sections (bfd
*output_bfd
,
3333 struct bfd_link_info
*info
)
3336 asection
*sdyn
, *sgot
;
3337 struct elf32_mb_link_hash_table
*htab
;
3339 htab
= elf32_mb_hash_table (info
);
3343 dynobj
= htab
->elf
.dynobj
;
3345 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
3347 if (htab
->elf
.dynamic_sections_created
)
3350 Elf32_External_Dyn
*dyncon
, *dynconend
;
3352 dyncon
= (Elf32_External_Dyn
*) sdyn
->contents
;
3353 dynconend
= (Elf32_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
3354 for (; dyncon
< dynconend
; dyncon
++)
3356 Elf_Internal_Dyn dyn
;
3360 bfd_elf32_swap_dyn_in (dynobj
, dyncon
, &dyn
);
3365 s
= htab
->elf
.sgotplt
;
3370 s
= htab
->elf
.srelplt
;
3375 s
= htab
->elf
.srelplt
;
3388 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
3390 dyn
.d_un
.d_val
= s
->size
;
3392 bfd_elf32_swap_dyn_out (output_bfd
, &dyn
, dyncon
);
3395 splt
= htab
->elf
.splt
;
3396 BFD_ASSERT (splt
!= NULL
&& sdyn
!= NULL
);
3398 /* Clear the first entry in the procedure linkage table,
3399 and put a nop in the last four bytes. */
3402 memset (splt
->contents
, 0, PLT_ENTRY_SIZE
);
3403 bfd_put_32 (output_bfd
, (bfd_vma
) 0x80000000 /* nop. */,
3404 splt
->contents
+ splt
->size
- 4);
3406 if (splt
->output_section
!= bfd_abs_section_ptr
)
3407 elf_section_data (splt
->output_section
)->this_hdr
.sh_entsize
= 4;
3411 /* Set the first entry in the global offset table to the address of
3412 the dynamic section. */
3413 sgot
= htab
->elf
.sgotplt
;
3414 if (sgot
&& sgot
->size
> 0)
3417 bfd_put_32 (output_bfd
, (bfd_vma
) 0, sgot
->contents
);
3419 bfd_put_32 (output_bfd
,
3420 sdyn
->output_section
->vma
+ sdyn
->output_offset
,
3422 elf_section_data (sgot
->output_section
)->this_hdr
.sh_entsize
= 4;
3425 if (htab
->elf
.sgot
&& htab
->elf
.sgot
->size
> 0)
3426 elf_section_data (htab
->elf
.sgot
->output_section
)->this_hdr
.sh_entsize
= 4;
3431 /* Hook called by the linker routine which adds symbols from an object
3432 file. We use it to put .comm items in .sbss, and not .bss. */
3435 microblaze_elf_add_symbol_hook (bfd
*abfd
,
3436 struct bfd_link_info
*info
,
3437 Elf_Internal_Sym
*sym
,
3438 const char **namep ATTRIBUTE_UNUSED
,
3439 flagword
*flagsp ATTRIBUTE_UNUSED
,
3443 if (sym
->st_shndx
== SHN_COMMON
3444 && !bfd_link_relocatable (info
)
3445 && sym
->st_size
<= elf_gp_size (abfd
))
3447 /* Common symbols less than or equal to -G nn bytes are automatically
3449 *secp
= bfd_make_section_old_way (abfd
, ".sbss");
3451 || !bfd_set_section_flags (*secp
, SEC_IS_COMMON
| SEC_SMALL_DATA
))
3454 *valp
= sym
->st_size
;
3460 #define TARGET_LITTLE_SYM microblaze_elf32_le_vec
3461 #define TARGET_LITTLE_NAME "elf32-microblazeel"
3463 #define TARGET_BIG_SYM microblaze_elf32_vec
3464 #define TARGET_BIG_NAME "elf32-microblaze"
3466 #define ELF_ARCH bfd_arch_microblaze
3467 #define ELF_TARGET_ID MICROBLAZE_ELF_DATA
3468 #define ELF_MACHINE_CODE EM_MICROBLAZE
3469 #define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
3470 #define ELF_MAXPAGESIZE 0x1000
3471 #define elf_info_to_howto microblaze_elf_info_to_howto
3472 #define elf_info_to_howto_rel NULL
3474 #define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
3475 #define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name
3476 #define bfd_elf32_new_section_hook microblaze_elf_new_section_hook
3477 #define elf_backend_relocate_section microblaze_elf_relocate_section
3478 #define bfd_elf32_bfd_relax_section microblaze_elf_relax_section
3479 #define bfd_elf32_bfd_merge_private_bfd_data _bfd_generic_verify_endian_match
3480 #define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
3482 #define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
3483 #define elf_backend_check_relocs microblaze_elf_check_relocs
3484 #define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
3485 #define bfd_elf32_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
3486 #define elf_backend_can_gc_sections 1
3487 #define elf_backend_can_refcount 1
3488 #define elf_backend_want_got_plt 1
3489 #define elf_backend_plt_readonly 1
3490 #define elf_backend_got_header_size 12
3491 #define elf_backend_want_dynrelro 1
3492 #define elf_backend_rela_normal 1
3493 #define elf_backend_dtrel_excludes_plt 1
3495 #define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
3496 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
3497 #define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
3498 #define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
3499 #define elf_backend_late_size_sections microblaze_elf_late_size_sections
3500 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
3502 #include "elf32-target.h"