1 /* Xilinx MicroBlaze-specific support for 32-bit ELF
3 Copyright (C) 2009-2016 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 Boston, MA 02110-1301, USA. */
30 #include "elf/microblaze.h"
33 #define USE_RELA /* Only USE_REL is actually significant, but this is
34 here are a reminder... */
35 #define INST_WORD_SIZE 4
37 static int ro_small_data_pointer
= 0;
38 static int rw_small_data_pointer
= 0;
40 static reloc_howto_type
* microblaze_elf_howto_table
[(int) R_MICROBLAZE_max
];
42 static reloc_howto_type microblaze_elf_howto_raw
[] =
44 /* This reloc does nothing. */
45 HOWTO (R_MICROBLAZE_NONE
, /* Type. */
47 3, /* Size (0 = byte, 1 = short, 2 = long). */
49 FALSE
, /* PC_relative. */
51 complain_overflow_dont
, /* Complain on overflow. */
52 NULL
, /* Special Function. */
53 "R_MICROBLAZE_NONE", /* Name. */
54 FALSE
, /* Partial Inplace. */
57 FALSE
), /* PC relative offset? */
59 /* A standard 32 bit relocation. */
60 HOWTO (R_MICROBLAZE_32
, /* Type. */
62 2, /* Size (0 = byte, 1 = short, 2 = long). */
64 FALSE
, /* PC_relative. */
66 complain_overflow_bitfield
, /* Complain on overflow. */
67 bfd_elf_generic_reloc
,/* Special Function. */
68 "R_MICROBLAZE_32", /* Name. */
69 FALSE
, /* Partial Inplace. */
71 0xffffffff, /* Dest Mask. */
72 FALSE
), /* PC relative offset? */
74 /* A standard PCREL 32 bit relocation. */
75 HOWTO (R_MICROBLAZE_32_PCREL
,/* Type. */
77 2, /* Size (0 = byte, 1 = short, 2 = long). */
79 TRUE
, /* PC_relative. */
81 complain_overflow_bitfield
, /* Complain on overflow. */
82 bfd_elf_generic_reloc
,/* Special Function. */
83 "R_MICROBLAZE_32_PCREL", /* Name. */
84 TRUE
, /* Partial Inplace. */
86 0xffffffff, /* Dest Mask. */
87 TRUE
), /* PC relative offset? */
89 /* A 64 bit PCREL relocation. Table-entry not really used. */
90 HOWTO (R_MICROBLAZE_64_PCREL
,/* Type. */
92 2, /* Size (0 = byte, 1 = short, 2 = long). */
94 TRUE
, /* PC_relative. */
96 complain_overflow_dont
, /* Complain on overflow. */
97 bfd_elf_generic_reloc
,/* Special Function. */
98 "R_MICROBLAZE_64_PCREL", /* Name. */
99 FALSE
, /* Partial Inplace. */
100 0, /* Source Mask. */
101 0x0000ffff, /* Dest Mask. */
102 TRUE
), /* PC relative offset? */
104 /* The low half of a PCREL 32 bit relocation. */
105 HOWTO (R_MICROBLAZE_32_PCREL_LO
, /* Type. */
107 2, /* Size (0 = byte, 1 = short, 2 = long). */
109 TRUE
, /* PC_relative. */
111 complain_overflow_signed
, /* Complain on overflow. */
112 bfd_elf_generic_reloc
, /* Special Function. */
113 "R_MICROBLAZE_32_PCREL_LO", /* Name. */
114 FALSE
, /* Partial Inplace. */
115 0, /* Source Mask. */
116 0x0000ffff, /* Dest Mask. */
117 TRUE
), /* PC relative offset? */
119 /* A 64 bit relocation. Table entry not really used. */
120 HOWTO (R_MICROBLAZE_64
, /* Type. */
122 2, /* Size (0 = byte, 1 = short, 2 = long). */
124 FALSE
, /* PC_relative. */
126 complain_overflow_dont
, /* Complain on overflow. */
127 bfd_elf_generic_reloc
,/* Special Function. */
128 "R_MICROBLAZE_64", /* Name. */
129 FALSE
, /* Partial Inplace. */
130 0, /* Source Mask. */
131 0x0000ffff, /* Dest Mask. */
132 FALSE
), /* PC relative offset? */
134 /* The low half of a 32 bit relocation. */
135 HOWTO (R_MICROBLAZE_32_LO
, /* Type. */
137 2, /* Size (0 = byte, 1 = short, 2 = long). */
139 FALSE
, /* PC_relative. */
141 complain_overflow_signed
, /* Complain on overflow. */
142 bfd_elf_generic_reloc
,/* Special Function. */
143 "R_MICROBLAZE_32_LO", /* Name. */
144 FALSE
, /* Partial Inplace. */
145 0, /* Source Mask. */
146 0x0000ffff, /* Dest Mask. */
147 FALSE
), /* PC relative offset? */
149 /* Read-only small data section relocation. */
150 HOWTO (R_MICROBLAZE_SRO32
, /* Type. */
152 2, /* Size (0 = byte, 1 = short, 2 = long). */
154 FALSE
, /* PC_relative. */
156 complain_overflow_bitfield
, /* Complain on overflow. */
157 bfd_elf_generic_reloc
,/* Special Function. */
158 "R_MICROBLAZE_SRO32", /* Name. */
159 FALSE
, /* Partial Inplace. */
160 0, /* Source Mask. */
161 0x0000ffff, /* Dest Mask. */
162 FALSE
), /* PC relative offset? */
164 /* Read-write small data area relocation. */
165 HOWTO (R_MICROBLAZE_SRW32
, /* Type. */
167 2, /* Size (0 = byte, 1 = short, 2 = long). */
169 FALSE
, /* PC_relative. */
171 complain_overflow_bitfield
, /* Complain on overflow. */
172 bfd_elf_generic_reloc
,/* Special Function. */
173 "R_MICROBLAZE_SRW32", /* Name. */
174 FALSE
, /* Partial Inplace. */
175 0, /* Source Mask. */
176 0x0000ffff, /* Dest Mask. */
177 FALSE
), /* PC relative offset? */
179 /* This reloc does nothing. Used for relaxation. */
180 HOWTO (R_MICROBLAZE_64_NONE
, /* Type. */
182 3, /* Size (0 = byte, 1 = short, 2 = long). */
184 TRUE
, /* PC_relative. */
186 complain_overflow_dont
, /* Complain on overflow. */
187 NULL
, /* Special Function. */
188 "R_MICROBLAZE_64_NONE",/* Name. */
189 FALSE
, /* Partial Inplace. */
190 0, /* Source Mask. */
192 FALSE
), /* PC relative offset? */
194 /* Symbol Op Symbol relocation. */
195 HOWTO (R_MICROBLAZE_32_SYM_OP_SYM
, /* Type. */
197 2, /* Size (0 = byte, 1 = short, 2 = long). */
199 FALSE
, /* PC_relative. */
201 complain_overflow_bitfield
, /* Complain on overflow. */
202 bfd_elf_generic_reloc
,/* Special Function. */
203 "R_MICROBLAZE_32_SYM_OP_SYM", /* Name. */
204 FALSE
, /* Partial Inplace. */
205 0, /* Source Mask. */
206 0xffffffff, /* Dest Mask. */
207 FALSE
), /* PC relative offset? */
209 /* GNU extension to record C++ vtable hierarchy. */
210 HOWTO (R_MICROBLAZE_GNU_VTINHERIT
, /* Type. */
212 2, /* Size (0 = byte, 1 = short, 2 = long). */
214 FALSE
, /* PC_relative. */
216 complain_overflow_dont
,/* Complain on overflow. */
217 NULL
, /* Special Function. */
218 "R_MICROBLAZE_GNU_VTINHERIT", /* Name. */
219 FALSE
, /* Partial Inplace. */
220 0, /* Source Mask. */
222 FALSE
), /* PC relative offset? */
224 /* GNU extension to record C++ vtable member usage. */
225 HOWTO (R_MICROBLAZE_GNU_VTENTRY
, /* Type. */
227 2, /* Size (0 = byte, 1 = short, 2 = long). */
229 FALSE
, /* PC_relative. */
231 complain_overflow_dont
,/* Complain on overflow. */
232 _bfd_elf_rel_vtable_reloc_fn
, /* Special Function. */
233 "R_MICROBLAZE_GNU_VTENTRY", /* Name. */
234 FALSE
, /* Partial Inplace. */
235 0, /* Source Mask. */
237 FALSE
), /* PC relative offset? */
239 /* A 64 bit GOTPC relocation. Table-entry not really used. */
240 HOWTO (R_MICROBLAZE_GOTPC_64
, /* Type. */
242 2, /* Size (0 = byte, 1 = short, 2 = long). */
244 TRUE
, /* PC_relative. */
246 complain_overflow_dont
, /* Complain on overflow. */
247 bfd_elf_generic_reloc
, /* Special Function. */
248 "R_MICROBLAZE_GOTPC_64", /* Name. */
249 FALSE
, /* Partial Inplace. */
250 0, /* Source Mask. */
251 0x0000ffff, /* Dest Mask. */
252 TRUE
), /* PC relative offset? */
254 /* A 64 bit GOT relocation. Table-entry not really used. */
255 HOWTO (R_MICROBLAZE_GOT_64
, /* Type. */
257 2, /* Size (0 = byte, 1 = short, 2 = long). */
259 FALSE
, /* PC_relative. */
261 complain_overflow_dont
, /* Complain on overflow. */
262 bfd_elf_generic_reloc
,/* Special Function. */
263 "R_MICROBLAZE_GOT_64",/* Name. */
264 FALSE
, /* Partial Inplace. */
265 0, /* Source Mask. */
266 0x0000ffff, /* Dest Mask. */
267 FALSE
), /* PC relative offset? */
269 /* A 64 bit PLT relocation. Table-entry not really used. */
270 HOWTO (R_MICROBLAZE_PLT_64
, /* Type. */
272 2, /* Size (0 = byte, 1 = short, 2 = long). */
274 TRUE
, /* PC_relative. */
276 complain_overflow_dont
, /* Complain on overflow. */
277 bfd_elf_generic_reloc
,/* Special Function. */
278 "R_MICROBLAZE_PLT_64",/* Name. */
279 FALSE
, /* Partial Inplace. */
280 0, /* Source Mask. */
281 0x0000ffff, /* Dest Mask. */
282 TRUE
), /* PC relative offset? */
284 /* Table-entry not really used. */
285 HOWTO (R_MICROBLAZE_REL
, /* Type. */
287 2, /* Size (0 = byte, 1 = short, 2 = long). */
289 TRUE
, /* PC_relative. */
291 complain_overflow_dont
, /* Complain on overflow. */
292 bfd_elf_generic_reloc
,/* Special Function. */
293 "R_MICROBLAZE_REL", /* Name. */
294 FALSE
, /* Partial Inplace. */
295 0, /* Source Mask. */
296 0x0000ffff, /* Dest Mask. */
297 TRUE
), /* PC relative offset? */
299 /* Table-entry not really used. */
300 HOWTO (R_MICROBLAZE_JUMP_SLOT
,/* Type. */
302 2, /* Size (0 = byte, 1 = short, 2 = long). */
304 TRUE
, /* PC_relative. */
306 complain_overflow_dont
, /* Complain on overflow. */
307 bfd_elf_generic_reloc
,/* Special Function. */
308 "R_MICROBLAZE_JUMP_SLOT", /* Name. */
309 FALSE
, /* Partial Inplace. */
310 0, /* Source Mask. */
311 0x0000ffff, /* Dest Mask. */
312 TRUE
), /* PC relative offset? */
314 /* Table-entry not really used. */
315 HOWTO (R_MICROBLAZE_GLOB_DAT
,/* Type. */
317 2, /* Size (0 = byte, 1 = short, 2 = long). */
319 TRUE
, /* PC_relative. */
321 complain_overflow_dont
, /* Complain on overflow. */
322 bfd_elf_generic_reloc
,/* Special Function. */
323 "R_MICROBLAZE_GLOB_DAT", /* Name. */
324 FALSE
, /* Partial Inplace. */
325 0, /* Source Mask. */
326 0x0000ffff, /* Dest Mask. */
327 TRUE
), /* PC relative offset? */
329 /* A 64 bit GOT relative relocation. Table-entry not really used. */
330 HOWTO (R_MICROBLAZE_GOTOFF_64
, /* Type. */
332 2, /* Size (0 = byte, 1 = short, 2 = long). */
334 FALSE
, /* PC_relative. */
336 complain_overflow_dont
, /* Complain on overflow. */
337 bfd_elf_generic_reloc
,/* Special Function. */
338 "R_MICROBLAZE_GOTOFF_64", /* Name. */
339 FALSE
, /* Partial Inplace. */
340 0, /* Source Mask. */
341 0x0000ffff, /* Dest Mask. */
342 FALSE
), /* PC relative offset? */
344 /* A 32 bit GOT relative relocation. Table-entry not really used. */
345 HOWTO (R_MICROBLAZE_GOTOFF_32
, /* Type. */
347 2, /* Size (0 = byte, 1 = short, 2 = long). */
349 FALSE
, /* PC_relative. */
351 complain_overflow_dont
, /* Complain on overflow. */
352 bfd_elf_generic_reloc
, /* Special Function. */
353 "R_MICROBLAZE_GOTOFF_32", /* Name. */
354 FALSE
, /* Partial Inplace. */
355 0, /* Source Mask. */
356 0x0000ffff, /* Dest Mask. */
357 FALSE
), /* PC relative offset? */
359 /* COPY relocation. Table-entry not really used. */
360 HOWTO (R_MICROBLAZE_COPY
, /* Type. */
362 2, /* Size (0 = byte, 1 = short, 2 = long). */
364 FALSE
, /* PC_relative. */
366 complain_overflow_dont
, /* Complain on overflow. */
367 bfd_elf_generic_reloc
,/* Special Function. */
368 "R_MICROBLAZE_COPY", /* Name. */
369 FALSE
, /* Partial Inplace. */
370 0, /* Source Mask. */
371 0x0000ffff, /* Dest Mask. */
372 FALSE
), /* PC relative offset? */
374 /* Marker relocs for TLS. */
375 HOWTO (R_MICROBLAZE_TLS
,
377 2, /* size (0 = byte, 1 = short, 2 = long) */
379 FALSE
, /* pc_relative */
381 complain_overflow_dont
, /* complain_on_overflow */
382 bfd_elf_generic_reloc
, /* special_function */
383 "R_MICROBLAZE_TLS", /* name */
384 FALSE
, /* partial_inplace */
386 0x0000ffff, /* dst_mask */
387 FALSE
), /* pcrel_offset */
389 HOWTO (R_MICROBLAZE_TLSGD
,
391 2, /* size (0 = byte, 1 = short, 2 = long) */
393 FALSE
, /* pc_relative */
395 complain_overflow_dont
, /* complain_on_overflow */
396 bfd_elf_generic_reloc
, /* special_function */
397 "R_MICROBLAZE_TLSGD", /* name */
398 FALSE
, /* partial_inplace */
400 0x0000ffff, /* dst_mask */
401 FALSE
), /* pcrel_offset */
403 HOWTO (R_MICROBLAZE_TLSLD
,
405 2, /* size (0 = byte, 1 = short, 2 = long) */
407 FALSE
, /* pc_relative */
409 complain_overflow_dont
, /* complain_on_overflow */
410 bfd_elf_generic_reloc
, /* special_function */
411 "R_MICROBLAZE_TLSLD", /* name */
412 FALSE
, /* partial_inplace */
414 0x0000ffff, /* dst_mask */
415 FALSE
), /* pcrel_offset */
417 /* Computes the load module index of the load module that contains the
418 definition of its TLS sym. */
419 HOWTO (R_MICROBLAZE_TLSDTPMOD32
,
421 2, /* size (0 = byte, 1 = short, 2 = long) */
423 FALSE
, /* pc_relative */
425 complain_overflow_dont
, /* complain_on_overflow */
426 bfd_elf_generic_reloc
, /* special_function */
427 "R_MICROBLAZE_TLSDTPMOD32", /* name */
428 FALSE
, /* partial_inplace */
430 0x0000ffff, /* dst_mask */
431 FALSE
), /* pcrel_offset */
433 /* Computes a dtv-relative displacement, the difference between the value
434 of sym+add and the base address of the thread-local storage block that
435 contains the definition of sym, minus 0x8000. Used for initializing GOT */
436 HOWTO (R_MICROBLAZE_TLSDTPREL32
,
438 2, /* size (0 = byte, 1 = short, 2 = long) */
440 FALSE
, /* pc_relative */
442 complain_overflow_dont
, /* complain_on_overflow */
443 bfd_elf_generic_reloc
, /* special_function */
444 "R_MICROBLAZE_TLSDTPREL32", /* name */
445 FALSE
, /* partial_inplace */
447 0x0000ffff, /* dst_mask */
448 FALSE
), /* pcrel_offset */
450 /* Computes a dtv-relative displacement, the difference between the value
451 of sym+add and the base address of the thread-local storage block that
452 contains the definition of sym, minus 0x8000. */
453 HOWTO (R_MICROBLAZE_TLSDTPREL64
,
455 2, /* size (0 = byte, 1 = short, 2 = long) */
457 FALSE
, /* pc_relative */
459 complain_overflow_dont
, /* complain_on_overflow */
460 bfd_elf_generic_reloc
, /* special_function */
461 "R_MICROBLAZE_TLSDTPREL64", /* name */
462 FALSE
, /* partial_inplace */
464 0x0000ffff, /* dst_mask */
465 FALSE
), /* pcrel_offset */
467 /* Computes a tp-relative displacement, the difference between the value of
468 sym+add and the value of the thread pointer (r13). */
469 HOWTO (R_MICROBLAZE_TLSGOTTPREL32
,
471 2, /* size (0 = byte, 1 = short, 2 = long) */
473 FALSE
, /* pc_relative */
475 complain_overflow_dont
, /* complain_on_overflow */
476 bfd_elf_generic_reloc
, /* special_function */
477 "R_MICROBLAZE_TLSGOTTPREL32", /* name */
478 FALSE
, /* partial_inplace */
480 0x0000ffff, /* dst_mask */
481 FALSE
), /* pcrel_offset */
483 /* Computes a tp-relative displacement, the difference between the value of
484 sym+add and the value of the thread pointer (r13). */
485 HOWTO (R_MICROBLAZE_TLSTPREL32
,
487 2, /* size (0 = byte, 1 = short, 2 = long) */
489 FALSE
, /* pc_relative */
491 complain_overflow_dont
, /* complain_on_overflow */
492 bfd_elf_generic_reloc
, /* special_function */
493 "R_MICROBLAZE_TLSTPREL32", /* name */
494 FALSE
, /* partial_inplace */
496 0x0000ffff, /* dst_mask */
497 FALSE
), /* pcrel_offset */
502 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
505 /* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */
508 microblaze_elf_howto_init (void)
512 for (i
= NUM_ELEM (microblaze_elf_howto_raw
); i
--;)
516 type
= microblaze_elf_howto_raw
[i
].type
;
518 BFD_ASSERT (type
< NUM_ELEM (microblaze_elf_howto_table
));
520 microblaze_elf_howto_table
[type
] = & microblaze_elf_howto_raw
[i
];
524 static reloc_howto_type
*
525 microblaze_elf_reloc_type_lookup (bfd
* abfd ATTRIBUTE_UNUSED
,
526 bfd_reloc_code_real_type code
)
528 enum elf_microblaze_reloc_type microblaze_reloc
= R_MICROBLAZE_NONE
;
533 microblaze_reloc
= R_MICROBLAZE_NONE
;
535 case BFD_RELOC_MICROBLAZE_64_NONE
:
536 microblaze_reloc
= R_MICROBLAZE_64_NONE
;
539 microblaze_reloc
= R_MICROBLAZE_32
;
541 /* RVA is treated the same as 32 */
543 microblaze_reloc
= R_MICROBLAZE_32
;
545 case BFD_RELOC_32_PCREL
:
546 microblaze_reloc
= R_MICROBLAZE_32_PCREL
;
548 case BFD_RELOC_64_PCREL
:
549 microblaze_reloc
= R_MICROBLAZE_64_PCREL
;
551 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
552 microblaze_reloc
= R_MICROBLAZE_32_PCREL_LO
;
555 microblaze_reloc
= R_MICROBLAZE_64
;
557 case BFD_RELOC_MICROBLAZE_32_LO
:
558 microblaze_reloc
= R_MICROBLAZE_32_LO
;
560 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
561 microblaze_reloc
= R_MICROBLAZE_SRO32
;
563 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
564 microblaze_reloc
= R_MICROBLAZE_SRW32
;
566 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
567 microblaze_reloc
= R_MICROBLAZE_32_SYM_OP_SYM
;
569 case BFD_RELOC_VTABLE_INHERIT
:
570 microblaze_reloc
= R_MICROBLAZE_GNU_VTINHERIT
;
572 case BFD_RELOC_VTABLE_ENTRY
:
573 microblaze_reloc
= R_MICROBLAZE_GNU_VTENTRY
;
575 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
576 microblaze_reloc
= R_MICROBLAZE_GOTPC_64
;
578 case BFD_RELOC_MICROBLAZE_64_GOT
:
579 microblaze_reloc
= R_MICROBLAZE_GOT_64
;
581 case BFD_RELOC_MICROBLAZE_64_PLT
:
582 microblaze_reloc
= R_MICROBLAZE_PLT_64
;
584 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
585 microblaze_reloc
= R_MICROBLAZE_GOTOFF_64
;
587 case BFD_RELOC_MICROBLAZE_32_GOTOFF
:
588 microblaze_reloc
= R_MICROBLAZE_GOTOFF_32
;
590 case BFD_RELOC_MICROBLAZE_64_TLSGD
:
591 microblaze_reloc
= R_MICROBLAZE_TLSGD
;
593 case BFD_RELOC_MICROBLAZE_64_TLSLD
:
594 microblaze_reloc
= R_MICROBLAZE_TLSLD
;
596 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL
:
597 microblaze_reloc
= R_MICROBLAZE_TLSDTPREL32
;
599 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL
:
600 microblaze_reloc
= R_MICROBLAZE_TLSDTPREL64
;
602 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
:
603 microblaze_reloc
= R_MICROBLAZE_TLSDTPMOD32
;
605 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
:
606 microblaze_reloc
= R_MICROBLAZE_TLSGOTTPREL32
;
608 case BFD_RELOC_MICROBLAZE_64_TLSTPREL
:
609 microblaze_reloc
= R_MICROBLAZE_TLSTPREL32
;
611 case BFD_RELOC_MICROBLAZE_COPY
:
612 microblaze_reloc
= R_MICROBLAZE_COPY
;
615 return (reloc_howto_type
*) NULL
;
618 if (!microblaze_elf_howto_table
[R_MICROBLAZE_32
])
619 /* Initialize howto table if needed. */
620 microblaze_elf_howto_init ();
622 return microblaze_elf_howto_table
[(int) microblaze_reloc
];
625 static reloc_howto_type
*
626 microblaze_elf_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
631 for (i
= 0; i
< NUM_ELEM (microblaze_elf_howto_raw
); i
++)
632 if (microblaze_elf_howto_raw
[i
].name
!= NULL
633 && strcasecmp (microblaze_elf_howto_raw
[i
].name
, r_name
) == 0)
634 return µblaze_elf_howto_raw
[i
];
639 /* Set the howto pointer for a RCE ELF reloc. */
642 microblaze_elf_info_to_howto (bfd
* abfd ATTRIBUTE_UNUSED
,
644 Elf_Internal_Rela
* dst
)
648 if (!microblaze_elf_howto_table
[R_MICROBLAZE_32
])
649 /* Initialize howto table if needed. */
650 microblaze_elf_howto_init ();
652 r_type
= ELF32_R_TYPE (dst
->r_info
);
653 if (r_type
>= R_MICROBLAZE_max
)
655 /* xgettext:c-format */
656 _bfd_error_handler (_("%B: unrecognised MicroBlaze reloc number: %d"),
658 bfd_set_error (bfd_error_bad_value
);
659 r_type
= R_MICROBLAZE_NONE
;
662 cache_ptr
->howto
= microblaze_elf_howto_table
[r_type
];
665 /* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
668 microblaze_elf_is_local_label_name (bfd
*abfd
, const char *name
)
670 if (name
[0] == 'L' && name
[1] == '.')
673 if (name
[0] == '$' && name
[1] == 'L')
676 /* With gcc, the labels go back to starting with '.', so we accept
677 the generic ELF local label syntax as well. */
678 return _bfd_elf_is_local_label_name (abfd
, name
);
681 /* The microblaze linker (like many others) needs to keep track of
682 the number of relocs that it decides to copy as dynamic relocs in
683 check_relocs for each symbol. This is so that it can later discard
684 them if they are found to be unnecessary. We store the information
685 in a field extending the regular ELF linker hash table. */
687 struct elf32_mb_dyn_relocs
689 struct elf32_mb_dyn_relocs
*next
;
691 /* The input section of the reloc. */
694 /* Total number of relocs copied for the input section. */
697 /* Number of pc-relative relocs copied for the input section. */
698 bfd_size_type pc_count
;
701 /* ELF linker hash entry. */
703 struct elf32_mb_link_hash_entry
705 struct elf_link_hash_entry elf
;
707 /* Track dynamic relocs copied for this symbol. */
708 struct elf32_mb_dyn_relocs
*dyn_relocs
;
710 /* TLS Reference Types for the symbol; Updated by check_relocs */
711 #define TLS_GD 1 /* GD reloc. */
712 #define TLS_LD 2 /* LD reloc. */
713 #define TLS_TPREL 4 /* TPREL reloc, => IE. */
714 #define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
715 #define TLS_TLS 16 /* Any TLS reloc. */
716 unsigned char tls_mask
;
720 #define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD))
721 #define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD))
722 #define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL))
723 #define IS_TLS_NONE(x) (x == 0)
725 #define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent))
727 /* ELF linker hash table. */
729 struct elf32_mb_link_hash_table
731 struct elf_link_hash_table elf
;
733 /* Short-cuts to get to dynamic linker sections. */
742 /* Small local sym to section mapping cache. */
743 struct sym_cache sym_sec
;
745 /* TLS Local Dynamic GOT Entry */
747 bfd_signed_vma refcount
;
752 /* Nonzero if this section has TLS related relocations. */
753 #define has_tls_reloc sec_flg0
755 /* Get the ELF linker hash table from a link_info structure. */
757 #define elf32_mb_hash_table(p) \
758 (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
759 == MICROBLAZE_ELF_DATA ? ((struct elf32_mb_link_hash_table *) ((p)->hash)) : NULL)
761 /* Create an entry in a microblaze ELF linker hash table. */
763 static struct bfd_hash_entry
*
764 link_hash_newfunc (struct bfd_hash_entry
*entry
,
765 struct bfd_hash_table
*table
,
768 /* Allocate the structure if it has not already been allocated by a
772 entry
= bfd_hash_allocate (table
,
773 sizeof (struct elf32_mb_link_hash_entry
));
778 /* Call the allocation method of the superclass. */
779 entry
= _bfd_elf_link_hash_newfunc (entry
, table
, string
);
782 struct elf32_mb_link_hash_entry
*eh
;
784 eh
= (struct elf32_mb_link_hash_entry
*) entry
;
785 eh
->dyn_relocs
= NULL
;
792 /* Create a mb ELF linker hash table. */
794 static struct bfd_link_hash_table
*
795 microblaze_elf_link_hash_table_create (bfd
*abfd
)
797 struct elf32_mb_link_hash_table
*ret
;
798 bfd_size_type amt
= sizeof (struct elf32_mb_link_hash_table
);
800 ret
= (struct elf32_mb_link_hash_table
*) bfd_zmalloc (amt
);
804 if (!_bfd_elf_link_hash_table_init (&ret
->elf
, abfd
, link_hash_newfunc
,
805 sizeof (struct elf32_mb_link_hash_entry
),
806 MICROBLAZE_ELF_DATA
))
812 return &ret
->elf
.root
;
815 /* Set the values of the small data pointers. */
818 microblaze_elf_final_sdp (struct bfd_link_info
*info
)
820 struct bfd_link_hash_entry
*h
;
822 h
= bfd_link_hash_lookup (info
->hash
, RO_SDA_ANCHOR_NAME
, FALSE
, FALSE
, TRUE
);
823 if (h
!= (struct bfd_link_hash_entry
*) NULL
824 && h
->type
== bfd_link_hash_defined
)
825 ro_small_data_pointer
= (h
->u
.def
.value
826 + h
->u
.def
.section
->output_section
->vma
827 + h
->u
.def
.section
->output_offset
);
829 h
= bfd_link_hash_lookup (info
->hash
, RW_SDA_ANCHOR_NAME
, FALSE
, FALSE
, TRUE
);
830 if (h
!= (struct bfd_link_hash_entry
*) NULL
831 && h
->type
== bfd_link_hash_defined
)
832 rw_small_data_pointer
= (h
->u
.def
.value
833 + h
->u
.def
.section
->output_section
->vma
834 + h
->u
.def
.section
->output_offset
);
838 dtprel_base (struct bfd_link_info
*info
)
840 /* If tls_sec is NULL, we should have signalled an error already. */
841 if (elf_hash_table (info
)->tls_sec
== NULL
)
843 return elf_hash_table (info
)->tls_sec
->vma
;
846 /* The size of the thread control block. */
849 /* Output a simple dynamic relocation into SRELOC. */
852 microblaze_elf_output_dynamic_relocation (bfd
*output_bfd
,
854 unsigned long reloc_index
,
861 Elf_Internal_Rela rel
;
863 rel
.r_info
= ELF32_R_INFO (indx
, r_type
);
864 rel
.r_offset
= offset
;
865 rel
.r_addend
= addend
;
867 bfd_elf32_swap_reloca_out (output_bfd
, &rel
,
868 (sreloc
->contents
+ reloc_index
* sizeof (Elf32_External_Rela
)));
871 /* This code is taken from elf32-m32r.c
872 There is some attempt to make this function usable for many architectures,
873 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
874 if only to serve as a learning tool.
876 The RELOCATE_SECTION function is called by the new ELF backend linker
877 to handle the relocations for a section.
879 The relocs are always passed as Rela structures; if the section
880 actually uses Rel structures, the r_addend field will always be
883 This function is responsible for adjust the section contents as
884 necessary, and (if using Rela relocs and generating a
885 relocatable output file) adjusting the reloc addend as
888 This function does not have to worry about setting the reloc
889 address or the reloc symbol index.
891 LOCAL_SYMS is a pointer to the swapped in local symbols.
893 LOCAL_SECTIONS is an array giving the section in the input file
894 corresponding to the st_shndx field of each local symbol.
896 The global hash table entry for the global symbols can be found
897 via elf_sym_hashes (input_bfd).
899 When generating relocatable output, this function must handle
900 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
901 going to be the section symbol corresponding to the output
902 section, which means that the addend must be adjusted
906 microblaze_elf_relocate_section (bfd
*output_bfd
,
907 struct bfd_link_info
*info
,
909 asection
*input_section
,
911 Elf_Internal_Rela
*relocs
,
912 Elf_Internal_Sym
*local_syms
,
913 asection
**local_sections
)
915 struct elf32_mb_link_hash_table
*htab
;
916 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
917 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
918 Elf_Internal_Rela
*rel
, *relend
;
919 int endian
= (bfd_little_endian (output_bfd
)) ? 0 : 2;
920 /* Assume success. */
921 bfd_boolean ret
= TRUE
;
923 bfd_vma
*local_got_offsets
;
924 unsigned int tls_type
;
926 if (!microblaze_elf_howto_table
[R_MICROBLAZE_max
-1])
927 microblaze_elf_howto_init ();
929 htab
= elf32_mb_hash_table (info
);
933 local_got_offsets
= elf_local_got_offsets (input_bfd
);
935 sreloc
= elf_section_data (input_section
)->sreloc
;
938 relend
= relocs
+ input_section
->reloc_count
;
939 for (; rel
< relend
; rel
++)
942 reloc_howto_type
*howto
;
943 unsigned long r_symndx
;
944 bfd_vma addend
= rel
->r_addend
;
945 bfd_vma offset
= rel
->r_offset
;
946 struct elf_link_hash_entry
*h
;
947 Elf_Internal_Sym
*sym
;
949 const char *sym_name
;
950 bfd_reloc_status_type r
= bfd_reloc_ok
;
951 const char *errmsg
= NULL
;
952 bfd_boolean unresolved_reloc
= FALSE
;
955 r_type
= ELF32_R_TYPE (rel
->r_info
);
958 if (r_type
< 0 || r_type
>= (int) R_MICROBLAZE_max
)
960 /* xgettext:c-format */
961 _bfd_error_handler (_("%s: unknown relocation type %d"),
962 bfd_get_filename (input_bfd
), (int) r_type
);
963 bfd_set_error (bfd_error_bad_value
);
968 howto
= microblaze_elf_howto_table
[r_type
];
969 r_symndx
= ELF32_R_SYM (rel
->r_info
);
971 if (bfd_link_relocatable (info
))
973 /* This is a relocatable link. We don't have to change
974 anything, unless the reloc is against a section symbol,
975 in which case we have to adjust according to where the
976 section symbol winds up in the output section. */
978 if (r_symndx
>= symtab_hdr
->sh_info
)
979 /* External symbol. */
983 sym
= local_syms
+ r_symndx
;
984 sym_name
= "<local symbol>";
985 /* STT_SECTION: symbol is associated with a section. */
986 if (ELF_ST_TYPE (sym
->st_info
) != STT_SECTION
)
987 /* Symbol isn't associated with a section. Nothing to do. */
990 sec
= local_sections
[r_symndx
];
991 addend
+= sec
->output_offset
+ sym
->st_value
;
993 /* This can't be done for USE_REL because it doesn't mean anything
994 and elf_link_input_bfd asserts this stays zero. */
995 /* rel->r_addend = addend; */
999 /* Addends are stored with relocs. We're done. */
1002 /* If partial_inplace, we need to store any additional addend
1003 back in the section. */
1004 if (!howto
->partial_inplace
)
1006 /* ??? Here is a nice place to call a special_function like handler. */
1007 r
= _bfd_relocate_contents (howto
, input_bfd
, addend
,
1009 #endif /* USE_REL */
1015 /* This is a final link. */
1018 unresolved_reloc
= FALSE
;
1020 if (r_symndx
< symtab_hdr
->sh_info
)
1023 sym
= local_syms
+ r_symndx
;
1024 sec
= local_sections
[r_symndx
];
1027 sym_name
= "<local symbol>";
1028 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
1029 /* r_addend may have changed if the reference section was
1031 addend
= rel
->r_addend
;
1035 /* External symbol. */
1036 bfd_boolean warned ATTRIBUTE_UNUSED
;
1037 bfd_boolean ignored ATTRIBUTE_UNUSED
;
1039 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
1040 r_symndx
, symtab_hdr
, sym_hashes
,
1042 unresolved_reloc
, warned
, ignored
);
1043 sym_name
= h
->root
.root
.string
;
1046 /* Sanity check the address. */
1047 if (offset
> bfd_get_section_limit (input_bfd
, input_section
))
1049 r
= bfd_reloc_outofrange
;
1053 switch ((int) r_type
)
1055 case (int) R_MICROBLAZE_SRO32
:
1059 /* Only relocate if the symbol is defined. */
1062 name
= bfd_get_section_name (sec
->owner
, sec
);
1064 if (strcmp (name
, ".sdata2") == 0
1065 || strcmp (name
, ".sbss2") == 0)
1067 if (ro_small_data_pointer
== 0)
1068 microblaze_elf_final_sdp (info
);
1069 if (ro_small_data_pointer
== 0)
1072 r
= bfd_reloc_undefined
;
1076 /* At this point `relocation' contains the object's
1078 relocation
-= ro_small_data_pointer
;
1079 /* Now it contains the offset from _SDA2_BASE_. */
1080 r
= _bfd_final_link_relocate (howto
, input_bfd
,
1083 relocation
, addend
);
1088 /* xgettext:c-format */
1089 (_("%s: The target (%s) of an %s relocation "
1090 "is in the wrong section (%s)"),
1091 bfd_get_filename (input_bfd
),
1093 microblaze_elf_howto_table
[(int) r_type
]->name
,
1094 bfd_get_section_name (sec
->owner
, sec
));
1095 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1103 case (int) R_MICROBLAZE_SRW32
:
1107 /* Only relocate if the symbol is defined. */
1110 name
= bfd_get_section_name (sec
->owner
, sec
);
1112 if (strcmp (name
, ".sdata") == 0
1113 || strcmp (name
, ".sbss") == 0)
1115 if (rw_small_data_pointer
== 0)
1116 microblaze_elf_final_sdp (info
);
1117 if (rw_small_data_pointer
== 0)
1120 r
= bfd_reloc_undefined
;
1124 /* At this point `relocation' contains the object's
1126 relocation
-= rw_small_data_pointer
;
1127 /* Now it contains the offset from _SDA_BASE_. */
1128 r
= _bfd_final_link_relocate (howto
, input_bfd
,
1131 relocation
, addend
);
1136 /* xgettext:c-format */
1137 (_("%s: The target (%s) of an %s relocation "
1138 "is in the wrong section (%s)"),
1139 bfd_get_filename (input_bfd
),
1141 microblaze_elf_howto_table
[(int) r_type
]->name
,
1142 bfd_get_section_name (sec
->owner
, sec
));
1143 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1151 case (int) R_MICROBLAZE_32_SYM_OP_SYM
:
1152 break; /* Do nothing. */
1154 case (int) R_MICROBLAZE_GOTPC_64
:
1155 relocation
= htab
->sgotplt
->output_section
->vma
1156 + htab
->sgotplt
->output_offset
;
1157 relocation
-= (input_section
->output_section
->vma
1158 + input_section
->output_offset
1159 + offset
+ INST_WORD_SIZE
);
1160 relocation
+= addend
;
1161 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1162 contents
+ offset
+ endian
);
1163 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1164 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1167 case (int) R_MICROBLAZE_PLT_64
:
1170 if (htab
->splt
!= NULL
&& h
!= NULL
1171 && h
->plt
.offset
!= (bfd_vma
) -1)
1173 relocation
= (htab
->splt
->output_section
->vma
1174 + htab
->splt
->output_offset
1176 unresolved_reloc
= FALSE
;
1177 immediate
= relocation
- (input_section
->output_section
->vma
1178 + input_section
->output_offset
1179 + offset
+ INST_WORD_SIZE
);
1180 bfd_put_16 (input_bfd
, (immediate
>> 16) & 0xffff,
1181 contents
+ offset
+ endian
);
1182 bfd_put_16 (input_bfd
, immediate
& 0xffff,
1183 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1187 relocation
-= (input_section
->output_section
->vma
1188 + input_section
->output_offset
1189 + offset
+ INST_WORD_SIZE
);
1190 immediate
= relocation
;
1191 bfd_put_16 (input_bfd
, (immediate
>> 16) & 0xffff,
1192 contents
+ offset
+ endian
);
1193 bfd_put_16 (input_bfd
, immediate
& 0xffff,
1194 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1199 case (int) R_MICROBLAZE_TLSGD
:
1200 tls_type
= (TLS_TLS
| TLS_GD
);
1202 case (int) R_MICROBLAZE_TLSLD
:
1203 tls_type
= (TLS_TLS
| TLS_LD
);
1206 case (int) R_MICROBLAZE_GOT_64
:
1211 bfd_vma static_value
;
1213 bfd_boolean need_relocs
= FALSE
;
1214 if (htab
->sgot
== NULL
)
1220 /* 1. Identify GOT Offset;
1221 2. Compute Static Values
1222 3. Process Module Id, Process Offset
1223 4. Fixup Relocation with GOT offset value. */
1225 /* 1. Determine GOT Offset to use : TLS_LD, global, local */
1226 if (IS_TLS_LD (tls_type
))
1227 offp
= &htab
->tlsld_got
.offset
;
1230 if (htab
->sgotplt
!= NULL
&& h
->got
.offset
!= (bfd_vma
) -1)
1231 offp
= &h
->got
.offset
;
1237 if (local_got_offsets
== NULL
)
1239 offp
= &local_got_offsets
[r_symndx
];
1248 if (IS_TLS_LD(tls_type
) || IS_TLS_GD(tls_type
))
1251 /* Symbol index to use for relocs */
1255 elf_hash_table (info
)->dynamic_sections_created
;
1257 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
,
1258 bfd_link_pic (info
),
1260 && (!bfd_link_pic (info
)
1261 || !SYMBOL_REFERENCES_LOCAL (info
, h
)))
1265 /* Need to generate relocs ? */
1266 if ((bfd_link_pic (info
) || indx
!= 0)
1268 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
1269 || h
->root
.type
!= bfd_link_hash_undefweak
))
1272 /* 2. Compute/Emit Static value of r-expression */
1273 static_value
= relocation
+ addend
;
1275 /* 3. Process module-id and offset */
1276 if (! ((*offp
) & 1) )
1280 got_offset
= (htab
->sgot
->output_section
->vma
1281 + htab
->sgot
->output_offset
1284 /* Process module-id */
1285 if (IS_TLS_LD(tls_type
))
1287 if (! bfd_link_pic (info
))
1289 bfd_put_32 (output_bfd
, 1, htab
->sgot
->contents
+ off
);
1293 microblaze_elf_output_dynamic_relocation (output_bfd
,
1294 htab
->srelgot
, htab
->srelgot
->reloc_count
++,
1295 /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32
,
1299 else if (IS_TLS_GD(tls_type
))
1303 bfd_put_32 (output_bfd
, 1, htab
->sgot
->contents
+ off
);
1307 microblaze_elf_output_dynamic_relocation (output_bfd
,
1309 htab
->srelgot
->reloc_count
++,
1310 /* symindex= */ indx
, R_MICROBLAZE_TLSDTPMOD32
,
1311 got_offset
, indx
? 0 : static_value
);
1315 /* Process Offset */
1316 if (htab
->srelgot
== NULL
)
1319 got_offset
= (htab
->sgot
->output_section
->vma
1320 + htab
->sgot
->output_offset
1322 if (IS_TLS_LD(tls_type
))
1324 /* For LD, offset should be 0 */
1326 bfd_put_32 (output_bfd
, 0, htab
->sgot
->contents
+ off2
);
1328 else if (IS_TLS_GD(tls_type
))
1331 static_value
-= dtprel_base(info
);
1334 microblaze_elf_output_dynamic_relocation (output_bfd
,
1335 htab
->srelgot
, htab
->srelgot
->reloc_count
++,
1336 /* symindex= */ indx
, R_MICROBLAZE_TLSDTPREL32
,
1337 got_offset
, indx
? 0 : static_value
);
1341 bfd_put_32 (output_bfd
, static_value
,
1342 htab
->sgot
->contents
+ off2
);
1347 bfd_put_32 (output_bfd
, static_value
,
1348 htab
->sgot
->contents
+ off2
);
1350 /* Relocs for dyn symbols generated by
1351 finish_dynamic_symbols */
1352 if (bfd_link_pic (info
) && h
== NULL
)
1355 microblaze_elf_output_dynamic_relocation (output_bfd
,
1356 htab
->srelgot
, htab
->srelgot
->reloc_count
++,
1357 /* symindex= */ indx
, R_MICROBLAZE_REL
,
1358 got_offset
, static_value
);
1363 /* 4. Fixup Relocation with GOT offset value
1364 Compute relative address of GOT entry for applying
1365 the current relocation */
1366 relocation
= htab
->sgot
->output_section
->vma
1367 + htab
->sgot
->output_offset
1369 - htab
->sgotplt
->output_section
->vma
1370 - htab
->sgotplt
->output_offset
;
1372 /* Apply Current Relocation */
1373 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1374 contents
+ offset
+ endian
);
1375 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1376 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1378 unresolved_reloc
= FALSE
;
1382 case (int) R_MICROBLAZE_GOTOFF_64
:
1385 unsigned short lo
, high
;
1386 relocation
+= addend
;
1387 relocation
-= htab
->sgotplt
->output_section
->vma
1388 + htab
->sgotplt
->output_offset
;
1389 /* Write this value into correct location. */
1390 immediate
= relocation
;
1391 lo
= immediate
& 0x0000ffff;
1392 high
= (immediate
>> 16) & 0x0000ffff;
1393 bfd_put_16 (input_bfd
, high
, contents
+ offset
+ endian
);
1394 bfd_put_16 (input_bfd
, lo
, contents
+ offset
+ INST_WORD_SIZE
+ endian
);
1398 case (int) R_MICROBLAZE_GOTOFF_32
:
1400 relocation
+= addend
;
1401 relocation
-= htab
->sgotplt
->output_section
->vma
1402 + htab
->sgotplt
->output_offset
;
1403 /* Write this value into correct location. */
1404 bfd_put_32 (input_bfd
, relocation
, contents
+ offset
);
1408 case (int) R_MICROBLAZE_TLSDTPREL64
:
1409 relocation
+= addend
;
1410 relocation
-= dtprel_base(info
);
1411 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1412 contents
+ offset
+ 2);
1413 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1414 contents
+ offset
+ 2 + INST_WORD_SIZE
);
1416 case (int) R_MICROBLAZE_64_PCREL
:
1417 case (int) R_MICROBLAZE_64
:
1418 case (int) R_MICROBLAZE_32
:
1420 /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
1421 from removed linkonce sections, or sections discarded by
1423 if (r_symndx
== STN_UNDEF
|| (input_section
->flags
& SEC_ALLOC
) == 0)
1425 relocation
+= addend
;
1426 if (r_type
== R_MICROBLAZE_32
)
1427 bfd_put_32 (input_bfd
, relocation
, contents
+ offset
);
1430 if (r_type
== R_MICROBLAZE_64_PCREL
)
1431 relocation
-= (input_section
->output_section
->vma
1432 + input_section
->output_offset
1433 + offset
+ INST_WORD_SIZE
);
1434 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1435 contents
+ offset
+ endian
);
1436 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1437 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1442 if ((bfd_link_pic (info
)
1444 || ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
1445 || h
->root
.type
!= bfd_link_hash_undefweak
)
1446 && (!howto
->pc_relative
1450 || !h
->def_regular
))))
1451 || (!bfd_link_pic (info
)
1457 || h
->root
.type
== bfd_link_hash_undefweak
1458 || h
->root
.type
== bfd_link_hash_undefined
)))
1460 Elf_Internal_Rela outrel
;
1464 /* When generating a shared object, these relocations
1465 are copied into the output file to be resolved at run
1468 BFD_ASSERT (sreloc
!= NULL
);
1473 _bfd_elf_section_offset (output_bfd
, info
, input_section
,
1475 if (outrel
.r_offset
== (bfd_vma
) -1)
1477 else if (outrel
.r_offset
== (bfd_vma
) -2)
1479 outrel
.r_offset
+= (input_section
->output_section
->vma
1480 + input_section
->output_offset
);
1483 memset (&outrel
, 0, sizeof outrel
);
1484 /* h->dynindx may be -1 if the symbol was marked to
1487 && ((! info
->symbolic
&& h
->dynindx
!= -1)
1488 || !h
->def_regular
))
1490 BFD_ASSERT (h
->dynindx
!= -1);
1491 outrel
.r_info
= ELF32_R_INFO (h
->dynindx
, r_type
);
1492 outrel
.r_addend
= addend
;
1496 if (r_type
== R_MICROBLAZE_32
)
1498 outrel
.r_info
= ELF32_R_INFO (0, R_MICROBLAZE_REL
);
1499 outrel
.r_addend
= relocation
+ addend
;
1505 (_("%B: probably compiled without -fPIC?"),
1507 bfd_set_error (bfd_error_bad_value
);
1512 loc
= sreloc
->contents
;
1513 loc
+= sreloc
->reloc_count
++ * sizeof (Elf32_External_Rela
);
1514 bfd_elf32_swap_reloca_out (output_bfd
, &outrel
, loc
);
1519 relocation
+= addend
;
1520 if (r_type
== R_MICROBLAZE_32
)
1521 bfd_put_32 (input_bfd
, relocation
, contents
+ offset
);
1524 if (r_type
== R_MICROBLAZE_64_PCREL
)
1525 relocation
-= (input_section
->output_section
->vma
1526 + input_section
->output_offset
1527 + offset
+ INST_WORD_SIZE
);
1528 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1529 contents
+ offset
+ endian
);
1530 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1531 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1538 r
= _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
1540 relocation
, addend
);
1547 if (r
!= bfd_reloc_ok
)
1549 /* FIXME: This should be generic enough to go in a utility. */
1553 name
= h
->root
.root
.string
;
1556 name
= (bfd_elf_string_from_elf_section
1557 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
1558 if (name
== NULL
|| *name
== '\0')
1559 name
= bfd_section_name (input_bfd
, sec
);
1567 case bfd_reloc_overflow
:
1568 (*info
->callbacks
->reloc_overflow
)
1569 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
,
1570 (bfd_vma
) 0, input_bfd
, input_section
, offset
);
1573 case bfd_reloc_undefined
:
1574 (*info
->callbacks
->undefined_symbol
)
1575 (info
, name
, input_bfd
, input_section
, offset
, TRUE
);
1578 case bfd_reloc_outofrange
:
1579 errmsg
= _("internal error: out of range error");
1582 case bfd_reloc_notsupported
:
1583 errmsg
= _("internal error: unsupported relocation error");
1586 case bfd_reloc_dangerous
:
1587 errmsg
= _("internal error: dangerous error");
1591 errmsg
= _("internal error: unknown error");
1594 (*info
->callbacks
->warning
) (info
, errmsg
, name
, input_bfd
,
1595 input_section
, offset
);
1604 /* Calculate fixup value for reference. */
1607 calc_fixup (bfd_vma start
, bfd_vma size
, asection
*sec
)
1609 bfd_vma end
= start
+ size
;
1612 if (sec
== NULL
|| sec
->relax
== NULL
)
1615 /* Look for addr in relax table, total fixup value. */
1616 for (i
= 0; i
< sec
->relax_count
; i
++)
1618 if (end
<= sec
->relax
[i
].addr
)
1620 if ((end
!= start
) && (start
> sec
->relax
[i
].addr
))
1622 fixup
+= sec
->relax
[i
].size
;
1627 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1628 a 32-bit instruction. */
1630 microblaze_bfd_write_imm_value_32 (bfd
*abfd
, bfd_byte
*bfd_addr
, bfd_vma val
)
1632 unsigned long instr
= bfd_get_32 (abfd
, bfd_addr
);
1633 instr
&= ~0x0000ffff;
1634 instr
|= (val
& 0x0000ffff);
1635 bfd_put_32 (abfd
, instr
, bfd_addr
);
1638 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1639 two consecutive 32-bit instructions. */
1641 microblaze_bfd_write_imm_value_64 (bfd
*abfd
, bfd_byte
*bfd_addr
, bfd_vma val
)
1643 unsigned long instr_hi
;
1644 unsigned long instr_lo
;
1646 instr_hi
= bfd_get_32 (abfd
, bfd_addr
);
1647 instr_hi
&= ~0x0000ffff;
1648 instr_hi
|= ((val
>> 16) & 0x0000ffff);
1649 bfd_put_32 (abfd
, instr_hi
, bfd_addr
);
1651 instr_lo
= bfd_get_32 (abfd
, bfd_addr
+ INST_WORD_SIZE
);
1652 instr_lo
&= ~0x0000ffff;
1653 instr_lo
|= (val
& 0x0000ffff);
1654 bfd_put_32 (abfd
, instr_lo
, bfd_addr
+ INST_WORD_SIZE
);
1658 microblaze_elf_relax_section (bfd
*abfd
,
1660 struct bfd_link_info
*link_info
,
1663 Elf_Internal_Shdr
*symtab_hdr
;
1664 Elf_Internal_Rela
*internal_relocs
;
1665 Elf_Internal_Rela
*free_relocs
= NULL
;
1666 Elf_Internal_Rela
*irel
, *irelend
;
1667 bfd_byte
*contents
= NULL
;
1668 bfd_byte
*free_contents
= NULL
;
1673 struct elf_link_hash_entry
*sym_hash
;
1674 Elf_Internal_Sym
*isymbuf
, *isymend
;
1675 Elf_Internal_Sym
*isym
;
1680 /* We only do this once per section. We may be able to delete some code
1681 by running multiple passes, but it is not worth it. */
1684 /* Only do this for a text section. */
1685 if (bfd_link_relocatable (link_info
)
1686 || (sec
->flags
& SEC_RELOC
) == 0
1687 || (sec
->reloc_count
== 0)
1688 || (sec
->flags
& SEC_CODE
) == 0)
1691 BFD_ASSERT ((sec
->size
> 0) || (sec
->rawsize
> 0));
1693 /* If this is the first time we have been called for this section,
1694 initialize the cooked size. */
1696 sec
->size
= sec
->rawsize
;
1698 /* Get symbols for this section. */
1699 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1700 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1701 symcount
= symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
);
1702 if (isymbuf
== NULL
)
1703 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
, symcount
,
1704 0, NULL
, NULL
, NULL
);
1705 BFD_ASSERT (isymbuf
!= NULL
);
1707 internal_relocs
= _bfd_elf_link_read_relocs (abfd
, sec
, NULL
, NULL
, link_info
->keep_memory
);
1708 if (internal_relocs
== NULL
)
1710 if (! link_info
->keep_memory
)
1711 free_relocs
= internal_relocs
;
1713 sec
->relax
= (struct relax_table
*) bfd_malloc ((sec
->reloc_count
+ 1)
1714 * sizeof (struct relax_table
));
1715 if (sec
->relax
== NULL
)
1717 sec
->relax_count
= 0;
1719 irelend
= internal_relocs
+ sec
->reloc_count
;
1721 for (irel
= internal_relocs
; irel
< irelend
; irel
++, rel_count
++)
1724 if ((ELF32_R_TYPE (irel
->r_info
) != (int) R_MICROBLAZE_64_PCREL
)
1725 && (ELF32_R_TYPE (irel
->r_info
) != (int) R_MICROBLAZE_64
))
1726 continue; /* Can't delete this reloc. */
1728 /* Get the section contents. */
1729 if (contents
== NULL
)
1731 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
1732 contents
= elf_section_data (sec
)->this_hdr
.contents
;
1735 contents
= (bfd_byte
*) bfd_malloc (sec
->size
);
1736 if (contents
== NULL
)
1738 free_contents
= contents
;
1740 if (!bfd_get_section_contents (abfd
, sec
, contents
,
1741 (file_ptr
) 0, sec
->size
))
1743 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1747 /* Get the value of the symbol referred to by the reloc. */
1748 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
1750 /* A local symbol. */
1753 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
1754 if (isym
->st_shndx
== SHN_UNDEF
)
1755 sym_sec
= bfd_und_section_ptr
;
1756 else if (isym
->st_shndx
== SHN_ABS
)
1757 sym_sec
= bfd_abs_section_ptr
;
1758 else if (isym
->st_shndx
== SHN_COMMON
)
1759 sym_sec
= bfd_com_section_ptr
;
1761 sym_sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
1763 symval
= _bfd_elf_rela_local_sym (abfd
, isym
, &sym_sec
, irel
);
1768 struct elf_link_hash_entry
*h
;
1770 indx
= ELF32_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
1771 h
= elf_sym_hashes (abfd
)[indx
];
1772 BFD_ASSERT (h
!= NULL
);
1774 if (h
->root
.type
!= bfd_link_hash_defined
1775 && h
->root
.type
!= bfd_link_hash_defweak
)
1776 /* This appears to be a reference to an undefined
1777 symbol. Just ignore it--it will be caught by the
1778 regular reloc processing. */
1781 symval
= (h
->root
.u
.def
.value
1782 + h
->root
.u
.def
.section
->output_section
->vma
1783 + h
->root
.u
.def
.section
->output_offset
);
1786 /* If this is a PC-relative reloc, subtract the instr offset from
1787 the symbol value. */
1788 if (ELF32_R_TYPE (irel
->r_info
) == (int) R_MICROBLAZE_64_PCREL
)
1790 symval
= symval
+ irel
->r_addend
1792 + sec
->output_section
->vma
1793 + sec
->output_offset
);
1796 symval
+= irel
->r_addend
;
1798 if ((symval
& 0xffff8000) == 0
1799 || (symval
& 0xffff8000) == 0xffff8000)
1801 /* We can delete this instruction. */
1802 sec
->relax
[sec
->relax_count
].addr
= irel
->r_offset
;
1803 sec
->relax
[sec
->relax_count
].size
= INST_WORD_SIZE
;
1806 /* Rewrite relocation type. */
1807 switch ((enum elf_microblaze_reloc_type
) ELF32_R_TYPE (irel
->r_info
))
1809 case R_MICROBLAZE_64_PCREL
:
1810 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1811 (int) R_MICROBLAZE_32_PCREL_LO
);
1813 case R_MICROBLAZE_64
:
1814 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1815 (int) R_MICROBLAZE_32_LO
);
1818 /* Cannot happen. */
1822 } /* Loop through all relocations. */
1824 /* Loop through the relocs again, and see if anything needs to change. */
1825 if (sec
->relax_count
> 0)
1827 shndx
= _bfd_elf_section_from_bfd_section (abfd
, sec
);
1829 sec
->relax
[sec
->relax_count
].addr
= sec
->size
;
1831 for (irel
= internal_relocs
; irel
< irelend
; irel
++, rel_count
++)
1835 /* Get the new reloc address. */
1836 nraddr
= irel
->r_offset
- calc_fixup (irel
->r_offset
, 0, sec
);
1837 switch ((enum elf_microblaze_reloc_type
) ELF32_R_TYPE (irel
->r_info
))
1841 case R_MICROBLAZE_64_PCREL
:
1843 case R_MICROBLAZE_64
:
1844 case R_MICROBLAZE_32_LO
:
1845 /* If this reloc is against a symbol defined in this
1846 section, we must check the addend to see it will put the value in
1847 range to be adjusted, and hence must be changed. */
1848 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
1850 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
1851 /* Only handle relocs against .text. */
1852 if (isym
->st_shndx
== shndx
1853 && ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
)
1854 irel
->r_addend
-= calc_fixup (irel
->r_addend
, 0, sec
);
1857 case R_MICROBLAZE_NONE
:
1859 /* This was a PC-relative instruction that was
1860 completely resolved. */
1862 bfd_vma target_address
;
1863 target_address
= irel
->r_addend
+ irel
->r_offset
;
1864 sfix
= calc_fixup (irel
->r_offset
, 0, sec
);
1865 efix
= calc_fixup (target_address
, 0, sec
);
1866 irel
->r_addend
-= (efix
- sfix
);
1867 /* Should use HOWTO. */
1868 microblaze_bfd_write_imm_value_32 (abfd
, contents
+ irel
->r_offset
,
1872 case R_MICROBLAZE_64_NONE
:
1874 /* This was a PC-relative 64-bit instruction that was
1875 completely resolved. */
1877 bfd_vma target_address
;
1878 target_address
= irel
->r_addend
+ irel
->r_offset
+ INST_WORD_SIZE
;
1879 sfix
= calc_fixup (irel
->r_offset
+ INST_WORD_SIZE
, 0, sec
);
1880 efix
= calc_fixup (target_address
, 0, sec
);
1881 irel
->r_addend
-= (efix
- sfix
);
1882 microblaze_bfd_write_imm_value_32 (abfd
, contents
+ irel
->r_offset
1883 + INST_WORD_SIZE
, irel
->r_addend
);
1887 irel
->r_offset
= nraddr
;
1888 } /* Change all relocs in this section. */
1890 /* Look through all other sections. */
1891 for (o
= abfd
->sections
; o
!= NULL
; o
= o
->next
)
1893 Elf_Internal_Rela
*irelocs
;
1894 Elf_Internal_Rela
*irelscan
, *irelscanend
;
1895 bfd_byte
*ocontents
;
1898 || (o
->flags
& SEC_RELOC
) == 0
1899 || o
->reloc_count
== 0)
1902 /* We always cache the relocs. Perhaps, if info->keep_memory is
1903 FALSE, we should free them, if we are permitted to. */
1905 irelocs
= _bfd_elf_link_read_relocs (abfd
, o
, NULL
, NULL
, TRUE
);
1906 if (irelocs
== NULL
)
1910 irelscanend
= irelocs
+ o
->reloc_count
;
1911 for (irelscan
= irelocs
; irelscan
< irelscanend
; irelscan
++)
1913 if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32
)
1915 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
1917 /* Look at the reloc only if the value has been resolved. */
1918 if (isym
->st_shndx
== shndx
1919 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
1921 if (ocontents
== NULL
)
1923 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
1924 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
1927 /* We always cache the section contents.
1928 Perhaps, if info->keep_memory is FALSE, we
1929 should free them, if we are permitted to. */
1930 if (o
->rawsize
== 0)
1931 o
->rawsize
= o
->size
;
1932 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
1933 if (ocontents
== NULL
)
1935 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
1939 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
1943 irelscan
->r_addend
-= calc_fixup (irelscan
->r_addend
, 0, sec
);
1945 else if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32_SYM_OP_SYM
)
1947 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
1949 /* Look at the reloc only if the value has been resolved. */
1950 if (ocontents
== NULL
)
1952 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
1953 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
1956 /* We always cache the section contents.
1957 Perhaps, if info->keep_memory is FALSE, we
1958 should free them, if we are permitted to. */
1960 if (o
->rawsize
== 0)
1961 o
->rawsize
= o
->size
;
1962 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
1963 if (ocontents
== NULL
)
1965 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
1969 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
1972 irelscan
->r_addend
-= calc_fixup (irel
->r_addend
1978 else if ((ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32_PCREL_LO
)
1979 || (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32_LO
))
1981 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
1983 /* Look at the reloc only if the value has been resolved. */
1984 if (isym
->st_shndx
== shndx
1985 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
1988 bfd_vma target_address
;
1990 if (ocontents
== NULL
)
1992 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
1993 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
1996 /* We always cache the section contents.
1997 Perhaps, if info->keep_memory is FALSE, we
1998 should free them, if we are permitted to. */
1999 if (o
->rawsize
== 0)
2000 o
->rawsize
= o
->size
;
2001 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2002 if (ocontents
== NULL
)
2004 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2008 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2012 unsigned long instr
= bfd_get_32 (abfd
, ocontents
+ irelscan
->r_offset
);
2013 immediate
= instr
& 0x0000ffff;
2014 target_address
= immediate
;
2015 offset
= calc_fixup (target_address
, 0, sec
);
2016 immediate
-= offset
;
2017 irelscan
->r_addend
-= offset
;
2018 microblaze_bfd_write_imm_value_32 (abfd
, ocontents
+ irelscan
->r_offset
,
2019 irelscan
->r_addend
);
2023 if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_64
)
2025 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2027 /* Look at the reloc only if the value has been resolved. */
2028 if (isym
->st_shndx
== shndx
2029 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2033 if (ocontents
== NULL
)
2035 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2036 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2039 /* We always cache the section contents.
2040 Perhaps, if info->keep_memory is FALSE, we
2041 should free them, if we are permitted to. */
2043 if (o
->rawsize
== 0)
2044 o
->rawsize
= o
->size
;
2045 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2046 if (ocontents
== NULL
)
2048 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2052 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2055 unsigned long instr_hi
= bfd_get_32 (abfd
, ocontents
2056 + irelscan
->r_offset
);
2057 unsigned long instr_lo
= bfd_get_32 (abfd
, ocontents
2058 + irelscan
->r_offset
2060 immediate
= (instr_hi
& 0x0000ffff) << 16;
2061 immediate
|= (instr_lo
& 0x0000ffff);
2062 offset
= calc_fixup (irelscan
->r_addend
, 0, sec
);
2063 immediate
-= offset
;
2064 irelscan
->r_addend
-= offset
;
2067 else if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_64_PCREL
)
2069 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2071 /* Look at the reloc only if the value has been resolved. */
2072 if (isym
->st_shndx
== shndx
2073 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2076 bfd_vma target_address
;
2078 if (ocontents
== NULL
)
2080 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2081 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2084 /* We always cache the section contents.
2085 Perhaps, if info->keep_memory is FALSE, we
2086 should free them, if we are permitted to. */
2087 if (o
->rawsize
== 0)
2088 o
->rawsize
= o
->size
;
2089 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2090 if (ocontents
== NULL
)
2092 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2096 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2099 unsigned long instr_hi
= bfd_get_32 (abfd
, ocontents
2100 + irelscan
->r_offset
);
2101 unsigned long instr_lo
= bfd_get_32 (abfd
, ocontents
2102 + irelscan
->r_offset
2104 immediate
= (instr_hi
& 0x0000ffff) << 16;
2105 immediate
|= (instr_lo
& 0x0000ffff);
2106 target_address
= immediate
;
2107 offset
= calc_fixup (target_address
, 0, sec
);
2108 immediate
-= offset
;
2109 irelscan
->r_addend
-= offset
;
2110 microblaze_bfd_write_imm_value_64 (abfd
, ocontents
2111 + irelscan
->r_offset
, immediate
);
2117 /* Adjust the local symbols defined in this section. */
2118 isymend
= isymbuf
+ symtab_hdr
->sh_info
;
2119 for (isym
= isymbuf
; isym
< isymend
; isym
++)
2121 if (isym
->st_shndx
== shndx
)
2123 isym
->st_value
-= calc_fixup (isym
->st_value
, 0, sec
);
2125 isym
->st_size
-= calc_fixup (isym
->st_value
, isym
->st_size
, sec
);
2129 /* Now adjust the global symbols defined in this section. */
2130 isym
= isymbuf
+ symtab_hdr
->sh_info
;
2131 symcount
= (symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
)) - symtab_hdr
->sh_info
;
2132 for (sym_index
= 0; sym_index
< symcount
; sym_index
++)
2134 sym_hash
= elf_sym_hashes (abfd
)[sym_index
];
2135 if ((sym_hash
->root
.type
== bfd_link_hash_defined
2136 || sym_hash
->root
.type
== bfd_link_hash_defweak
)
2137 && sym_hash
->root
.u
.def
.section
== sec
)
2139 sym_hash
->root
.u
.def
.value
-= calc_fixup (sym_hash
->root
.u
.def
.value
,
2142 sym_hash
->size
-= calc_fixup (sym_hash
->root
.u
.def
.value
,
2143 sym_hash
->size
, sec
);
2147 /* Physically move the code and change the cooked size. */
2148 dest
= sec
->relax
[0].addr
;
2149 for (i
= 0; i
< sec
->relax_count
; i
++)
2152 src
= sec
->relax
[i
].addr
+ sec
->relax
[i
].size
;
2153 len
= sec
->relax
[i
+1].addr
- sec
->relax
[i
].addr
- sec
->relax
[i
].size
;
2155 memmove (contents
+ dest
, contents
+ src
, len
);
2156 sec
->size
-= sec
->relax
[i
].size
;
2160 elf_section_data (sec
)->relocs
= internal_relocs
;
2163 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2164 free_contents
= NULL
;
2166 symtab_hdr
->contents
= (bfd_byte
*) isymbuf
;
2169 if (free_relocs
!= NULL
)
2175 if (free_contents
!= NULL
)
2177 if (!link_info
->keep_memory
)
2178 free (free_contents
);
2180 /* Cache the section contents for elf_link_input_bfd. */
2181 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2182 free_contents
= NULL
;
2185 if (sec
->relax_count
== 0)
2196 if (free_relocs
!= NULL
)
2198 if (free_contents
!= NULL
)
2199 free (free_contents
);
2200 if (sec
->relax
!= NULL
)
2204 sec
->relax_count
= 0;
2209 /* Return the section that should be marked against GC for a given
2213 microblaze_elf_gc_mark_hook (asection
*sec
,
2214 struct bfd_link_info
* info
,
2215 Elf_Internal_Rela
* rel
,
2216 struct elf_link_hash_entry
* h
,
2217 Elf_Internal_Sym
* sym
)
2220 switch (ELF32_R_TYPE (rel
->r_info
))
2222 case R_MICROBLAZE_GNU_VTINHERIT
:
2223 case R_MICROBLAZE_GNU_VTENTRY
:
2227 return _bfd_elf_gc_mark_hook (sec
, info
, rel
, h
, sym
);
2230 /* Update the got entry reference counts for the section being removed. */
2233 microblaze_elf_gc_sweep_hook (bfd
* abfd ATTRIBUTE_UNUSED
,
2234 struct bfd_link_info
* info ATTRIBUTE_UNUSED
,
2235 asection
* sec ATTRIBUTE_UNUSED
,
2236 const Elf_Internal_Rela
* relocs ATTRIBUTE_UNUSED
)
2243 #define PLT_ENTRY_SIZE 16
2245 #define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
2246 #define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
2247 #define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
2248 #define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
2249 #define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
2251 /* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
2252 shortcuts to them in our hash table. */
2255 create_got_section (bfd
*dynobj
, struct bfd_link_info
*info
)
2257 struct elf32_mb_link_hash_table
*htab
;
2259 if (! _bfd_elf_create_got_section (dynobj
, info
))
2261 htab
= elf32_mb_hash_table (info
);
2265 htab
->sgot
= bfd_get_linker_section (dynobj
, ".got");
2266 htab
->sgotplt
= bfd_get_linker_section (dynobj
, ".got.plt");
2267 if (!htab
->sgot
|| !htab
->sgotplt
)
2270 if ((htab
->srelgot
= bfd_get_linker_section (dynobj
, ".rela.got")) == NULL
)
2271 htab
->srelgot
= bfd_make_section_anyway (dynobj
, ".rela.got");
2272 if (htab
->srelgot
== NULL
2273 || ! bfd_set_section_flags (dynobj
, htab
->srelgot
, SEC_ALLOC
2277 | SEC_LINKER_CREATED
2279 || ! bfd_set_section_alignment (dynobj
, htab
->srelgot
, 2))
2285 update_local_sym_info (bfd
*abfd
,
2286 Elf_Internal_Shdr
*symtab_hdr
,
2287 unsigned long r_symndx
,
2288 unsigned int tls_type
)
2290 bfd_signed_vma
*local_got_refcounts
= elf_local_got_refcounts (abfd
);
2291 unsigned char *local_got_tls_masks
;
2293 if (local_got_refcounts
== NULL
)
2295 bfd_size_type size
= symtab_hdr
->sh_info
;
2297 size
*= (sizeof (*local_got_refcounts
) + sizeof (*local_got_tls_masks
));
2298 local_got_refcounts
= bfd_zalloc (abfd
, size
);
2299 if (local_got_refcounts
== NULL
)
2301 elf_local_got_refcounts (abfd
) = local_got_refcounts
;
2304 local_got_tls_masks
=
2305 (unsigned char *) (local_got_refcounts
+ symtab_hdr
->sh_info
);
2306 local_got_tls_masks
[r_symndx
] |= tls_type
;
2307 local_got_refcounts
[r_symndx
] += 1;
2311 /* Look through the relocs for a section during the first phase. */
2314 microblaze_elf_check_relocs (bfd
* abfd
,
2315 struct bfd_link_info
* info
,
2317 const Elf_Internal_Rela
* relocs
)
2319 Elf_Internal_Shdr
* symtab_hdr
;
2320 struct elf_link_hash_entry
** sym_hashes
;
2321 struct elf_link_hash_entry
** sym_hashes_end
;
2322 const Elf_Internal_Rela
* rel
;
2323 const Elf_Internal_Rela
* rel_end
;
2324 struct elf32_mb_link_hash_table
*htab
;
2325 asection
*sreloc
= NULL
;
2327 if (bfd_link_relocatable (info
))
2330 htab
= elf32_mb_hash_table (info
);
2334 symtab_hdr
= & elf_tdata (abfd
)->symtab_hdr
;
2335 sym_hashes
= elf_sym_hashes (abfd
);
2336 sym_hashes_end
= sym_hashes
+ symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
);
2337 if (!elf_bad_symtab (abfd
))
2338 sym_hashes_end
-= symtab_hdr
->sh_info
;
2340 rel_end
= relocs
+ sec
->reloc_count
;
2342 for (rel
= relocs
; rel
< rel_end
; rel
++)
2344 unsigned int r_type
;
2345 struct elf_link_hash_entry
* h
;
2346 unsigned long r_symndx
;
2347 unsigned char tls_type
= 0;
2349 r_symndx
= ELF32_R_SYM (rel
->r_info
);
2350 r_type
= ELF32_R_TYPE (rel
->r_info
);
2352 if (r_symndx
< symtab_hdr
->sh_info
)
2356 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
2358 /* PR15323, ref flags aren't set for references in the same
2360 h
->root
.non_ir_ref
= 1;
2365 /* This relocation describes the C++ object vtable hierarchy.
2366 Reconstruct it for later use during GC. */
2367 case R_MICROBLAZE_GNU_VTINHERIT
:
2368 if (!bfd_elf_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
2372 /* This relocation describes which C++ vtable entries are actually
2373 used. Record for later use during GC. */
2374 case R_MICROBLAZE_GNU_VTENTRY
:
2375 if (!bfd_elf_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
2379 /* This relocation requires .plt entry. */
2380 case R_MICROBLAZE_PLT_64
:
2384 h
->plt
.refcount
+= 1;
2388 /* This relocation requires .got entry. */
2389 case R_MICROBLAZE_TLSGD
:
2390 tls_type
|= (TLS_TLS
| TLS_GD
);
2392 case R_MICROBLAZE_TLSLD
:
2393 tls_type
|= (TLS_TLS
| TLS_LD
);
2396 sec
->has_tls_reloc
= 1;
2398 case R_MICROBLAZE_GOT_64
:
2399 if (htab
->sgot
== NULL
)
2401 if (htab
->elf
.dynobj
== NULL
)
2402 htab
->elf
.dynobj
= abfd
;
2403 if (!create_got_section (htab
->elf
.dynobj
, info
))
2408 h
->got
.refcount
+= 1;
2409 elf32_mb_hash_entry (h
)->tls_mask
|= tls_type
;
2413 if (! update_local_sym_info(abfd
, symtab_hdr
, r_symndx
, tls_type
) )
2418 case R_MICROBLAZE_64
:
2419 case R_MICROBLAZE_64_PCREL
:
2420 case R_MICROBLAZE_32
:
2422 if (h
!= NULL
&& !bfd_link_pic (info
))
2424 /* we may need a copy reloc. */
2427 /* we may also need a .plt entry. */
2428 h
->plt
.refcount
+= 1;
2429 if (ELF32_R_TYPE (rel
->r_info
) != R_MICROBLAZE_64_PCREL
)
2430 h
->pointer_equality_needed
= 1;
2434 /* If we are creating a shared library, and this is a reloc
2435 against a global symbol, or a non PC relative reloc
2436 against a local symbol, then we need to copy the reloc
2437 into the shared library. However, if we are linking with
2438 -Bsymbolic, we do not need to copy a reloc against a
2439 global symbol which is defined in an object we are
2440 including in the link (i.e., DEF_REGULAR is set). At
2441 this point we have not seen all the input files, so it is
2442 possible that DEF_REGULAR is not set now but will be set
2443 later (it is never cleared). In case of a weak definition,
2444 DEF_REGULAR may be cleared later by a strong definition in
2445 a shared library. We account for that possibility below by
2446 storing information in the relocs_copied field of the hash
2447 table entry. A similar situation occurs when creating
2448 shared libraries and symbol visibility changes render the
2451 If on the other hand, we are creating an executable, we
2452 may need to keep relocations for symbols satisfied by a
2453 dynamic library if we manage to avoid copy relocs for the
2456 if ((bfd_link_pic (info
)
2457 && (sec
->flags
& SEC_ALLOC
) != 0
2458 && (r_type
!= R_MICROBLAZE_64_PCREL
2460 && (! info
->symbolic
2461 || h
->root
.type
== bfd_link_hash_defweak
2462 || !h
->def_regular
))))
2463 || (!bfd_link_pic (info
)
2464 && (sec
->flags
& SEC_ALLOC
) != 0
2466 && (h
->root
.type
== bfd_link_hash_defweak
2467 || !h
->def_regular
)))
2469 struct elf32_mb_dyn_relocs
*p
;
2470 struct elf32_mb_dyn_relocs
**head
;
2472 /* When creating a shared object, we must copy these
2473 relocs into the output file. We create a reloc
2474 section in dynobj and make room for the reloc. */
2480 if (htab
->elf
.dynobj
== NULL
)
2481 htab
->elf
.dynobj
= abfd
;
2482 dynobj
= htab
->elf
.dynobj
;
2484 sreloc
= _bfd_elf_make_dynamic_reloc_section (sec
, dynobj
,
2490 /* If this is a global symbol, we count the number of
2491 relocations we need for this symbol. */
2493 head
= &((struct elf32_mb_link_hash_entry
*) h
)->dyn_relocs
;
2496 /* Track dynamic relocs needed for local syms too.
2497 We really need local syms available to do this
2501 Elf_Internal_Sym
*isym
;
2504 isym
= bfd_sym_from_r_symndx (&htab
->sym_sec
,
2509 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
2513 vpp
= &elf_section_data (s
)->local_dynrel
;
2514 head
= (struct elf32_mb_dyn_relocs
**) vpp
;
2518 if (p
== NULL
|| p
->sec
!= sec
)
2520 bfd_size_type amt
= sizeof *p
;
2521 p
= ((struct elf32_mb_dyn_relocs
*)
2522 bfd_alloc (htab
->elf
.dynobj
, amt
));
2533 if (r_type
== R_MICROBLAZE_64_PCREL
)
2545 microblaze_elf_create_dynamic_sections (bfd
*dynobj
, struct bfd_link_info
*info
)
2547 struct elf32_mb_link_hash_table
*htab
;
2549 htab
= elf32_mb_hash_table (info
);
2553 if (!htab
->sgot
&& !create_got_section (dynobj
, info
))
2556 if (!_bfd_elf_create_dynamic_sections (dynobj
, info
))
2559 htab
->splt
= bfd_get_linker_section (dynobj
, ".plt");
2560 htab
->srelplt
= bfd_get_linker_section (dynobj
, ".rela.plt");
2561 htab
->sdynbss
= bfd_get_linker_section (dynobj
, ".dynbss");
2562 if (!bfd_link_pic (info
))
2563 htab
->srelbss
= bfd_get_linker_section (dynobj
, ".rela.bss");
2565 if (!htab
->splt
|| !htab
->srelplt
|| !htab
->sdynbss
2566 || (!bfd_link_pic (info
) && !htab
->srelbss
))
2572 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2575 microblaze_elf_copy_indirect_symbol (struct bfd_link_info
*info
,
2576 struct elf_link_hash_entry
*dir
,
2577 struct elf_link_hash_entry
*ind
)
2579 struct elf32_mb_link_hash_entry
*edir
, *eind
;
2581 edir
= (struct elf32_mb_link_hash_entry
*) dir
;
2582 eind
= (struct elf32_mb_link_hash_entry
*) ind
;
2584 if (eind
->dyn_relocs
!= NULL
)
2586 if (edir
->dyn_relocs
!= NULL
)
2588 struct elf32_mb_dyn_relocs
**pp
;
2589 struct elf32_mb_dyn_relocs
*p
;
2591 if (ind
->root
.type
== bfd_link_hash_indirect
)
2594 /* Add reloc counts against the weak sym to the strong sym
2595 list. Merge any entries against the same section. */
2596 for (pp
= &eind
->dyn_relocs
; (p
= *pp
) != NULL
; )
2598 struct elf32_mb_dyn_relocs
*q
;
2600 for (q
= edir
->dyn_relocs
; q
!= NULL
; q
= q
->next
)
2601 if (q
->sec
== p
->sec
)
2603 q
->pc_count
+= p
->pc_count
;
2604 q
->count
+= p
->count
;
2611 *pp
= edir
->dyn_relocs
;
2614 edir
->dyn_relocs
= eind
->dyn_relocs
;
2615 eind
->dyn_relocs
= NULL
;
2618 edir
->tls_mask
|= eind
->tls_mask
;
2620 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
2624 microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info
*info
,
2625 struct elf_link_hash_entry
*h
)
2627 struct elf32_mb_link_hash_table
*htab
;
2628 struct elf32_mb_link_hash_entry
* eh
;
2629 struct elf32_mb_dyn_relocs
*p
;
2630 asection
*sdynbss
, *s
;
2631 unsigned int power_of_two
;
2634 htab
= elf32_mb_hash_table (info
);
2638 /* If this is a function, put it in the procedure linkage table. We
2639 will fill in the contents of the procedure linkage table later,
2640 when we know the address of the .got section. */
2641 if (h
->type
== STT_FUNC
2644 if (h
->plt
.refcount
<= 0
2645 || SYMBOL_CALLS_LOCAL (info
, h
)
2646 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
2647 && h
->root
.type
== bfd_link_hash_undefweak
))
2649 /* This case can occur if we saw a PLT reloc in an input
2650 file, but the symbol was never referred to by a dynamic
2651 object, or if all references were garbage collected. In
2652 such a case, we don't actually need to build a procedure
2653 linkage table, and we can just do a PC32 reloc instead. */
2654 h
->plt
.offset
= (bfd_vma
) -1;
2661 /* It's possible that we incorrectly decided a .plt reloc was
2662 needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
2663 check_relocs. We can't decide accurately between function and
2664 non-function syms in check-relocs; Objects loaded later in
2665 the link may change h->type. So fix it now. */
2666 h
->plt
.offset
= (bfd_vma
) -1;
2668 /* If this is a weak symbol, and there is a real definition, the
2669 processor independent code will have arranged for us to see the
2670 real definition first, and we can just use the same value. */
2671 if (h
->u
.weakdef
!= NULL
)
2673 BFD_ASSERT (h
->u
.weakdef
->root
.type
== bfd_link_hash_defined
2674 || h
->u
.weakdef
->root
.type
== bfd_link_hash_defweak
);
2675 h
->root
.u
.def
.section
= h
->u
.weakdef
->root
.u
.def
.section
;
2676 h
->root
.u
.def
.value
= h
->u
.weakdef
->root
.u
.def
.value
;
2680 /* This is a reference to a symbol defined by a dynamic object which
2681 is not a function. */
2683 /* If we are creating a shared library, we must presume that the
2684 only references to the symbol are via the global offset table.
2685 For such cases we need not do anything here; the relocations will
2686 be handled correctly by relocate_section. */
2687 if (bfd_link_pic (info
))
2690 /* If there are no references to this symbol that do not use the
2691 GOT, we don't need to generate a copy reloc. */
2692 if (!h
->non_got_ref
)
2695 /* If -z nocopyreloc was given, we won't generate them either. */
2696 if (info
->nocopyreloc
)
2702 eh
= (struct elf32_mb_link_hash_entry
*) h
;
2703 for (p
= eh
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
2705 s
= p
->sec
->output_section
;
2706 if (s
!= NULL
&& (s
->flags
& SEC_READONLY
) != 0)
2710 /* If we didn't find any dynamic relocs in read-only sections, then
2711 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
2718 /* We must allocate the symbol in our .dynbss section, which will
2719 become part of the .bss section of the executable. There will be
2720 an entry for this symbol in the .dynsym section. The dynamic
2721 object will contain position independent code, so all references
2722 from the dynamic object to this symbol will go through the global
2723 offset table. The dynamic linker will use the .dynsym entry to
2724 determine the address it must put in the global offset table, so
2725 both the dynamic object and the regular object will refer to the
2726 same memory location for the variable. */
2728 /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
2729 to copy the initial value out of the dynamic object and into the
2730 runtime process image. */
2731 dynobj
= elf_hash_table (info
)->dynobj
;
2732 BFD_ASSERT (dynobj
!= NULL
);
2733 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0)
2735 htab
->srelbss
->size
+= sizeof (Elf32_External_Rela
);
2739 /* We need to figure out the alignment required for this symbol. I
2740 have no idea how ELF linkers handle this. */
2741 power_of_two
= bfd_log2 (h
->size
);
2742 if (power_of_two
> 3)
2745 sdynbss
= htab
->sdynbss
;
2746 /* Apply the required alignment. */
2747 sdynbss
->size
= BFD_ALIGN (sdynbss
->size
, (bfd_size_type
) (1 << power_of_two
));
2748 if (power_of_two
> bfd_get_section_alignment (dynobj
, sdynbss
))
2750 if (! bfd_set_section_alignment (dynobj
, sdynbss
, power_of_two
))
2754 /* Define the symbol as being at this point in the section. */
2755 h
->root
.u
.def
.section
= sdynbss
;
2756 h
->root
.u
.def
.value
= sdynbss
->size
;
2758 /* Increment the section size to make room for the symbol. */
2759 sdynbss
->size
+= h
->size
;
2763 /* Allocate space in .plt, .got and associated reloc sections for
2767 allocate_dynrelocs (struct elf_link_hash_entry
*h
, void * dat
)
2769 struct bfd_link_info
*info
;
2770 struct elf32_mb_link_hash_table
*htab
;
2771 struct elf32_mb_link_hash_entry
*eh
;
2772 struct elf32_mb_dyn_relocs
*p
;
2774 if (h
->root
.type
== bfd_link_hash_indirect
)
2777 info
= (struct bfd_link_info
*) dat
;
2778 htab
= elf32_mb_hash_table (info
);
2782 if (htab
->elf
.dynamic_sections_created
2783 && h
->plt
.refcount
> 0)
2785 /* Make sure this symbol is output as a dynamic symbol.
2786 Undefined weak syms won't yet be marked as dynamic. */
2787 if (h
->dynindx
== -1
2788 && !h
->forced_local
)
2790 if (! bfd_elf_link_record_dynamic_symbol (info
, h
))
2794 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info
), h
))
2796 asection
*s
= htab
->splt
;
2798 /* The first entry in .plt is reserved. */
2800 s
->size
= PLT_ENTRY_SIZE
;
2802 h
->plt
.offset
= s
->size
;
2804 /* If this symbol is not defined in a regular file, and we are
2805 not generating a shared library, then set the symbol to this
2806 location in the .plt. This is required to make function
2807 pointers compare as equal between the normal executable and
2808 the shared library. */
2809 if (! bfd_link_pic (info
)
2812 h
->root
.u
.def
.section
= s
;
2813 h
->root
.u
.def
.value
= h
->plt
.offset
;
2816 /* Make room for this entry. */
2817 s
->size
+= PLT_ENTRY_SIZE
;
2819 /* We also need to make an entry in the .got.plt section, which
2820 will be placed in the .got section by the linker script. */
2821 htab
->sgotplt
->size
+= 4;
2823 /* We also need to make an entry in the .rel.plt section. */
2824 htab
->srelplt
->size
+= sizeof (Elf32_External_Rela
);
2828 h
->plt
.offset
= (bfd_vma
) -1;
2834 h
->plt
.offset
= (bfd_vma
) -1;
2838 eh
= (struct elf32_mb_link_hash_entry
*) h
;
2839 if (h
->got
.refcount
> 0)
2844 /* Make sure this symbol is output as a dynamic symbol.
2845 Undefined weak syms won't yet be marked as dynamic. */
2846 if (h
->dynindx
== -1
2847 && !h
->forced_local
)
2849 if (! bfd_elf_link_record_dynamic_symbol (info
, h
))
2854 if ((eh
->tls_mask
& TLS_TLS
) != 0)
2856 /* Handle TLS Symbol */
2857 if ((eh
->tls_mask
& TLS_LD
) != 0)
2859 if (!eh
->elf
.def_dynamic
)
2860 /* We'll just use htab->tlsld_got.offset. This should
2861 always be the case. It's a little odd if we have
2862 a local dynamic reloc against a non-local symbol. */
2863 htab
->tlsld_got
.refcount
+= 1;
2867 if ((eh
->tls_mask
& TLS_GD
) != 0)
2872 /* Regular (non-TLS) symbol */
2877 h
->got
.offset
= (bfd_vma
) -1;
2882 h
->got
.offset
= s
->size
;
2884 htab
->srelgot
->size
+= need
* (sizeof (Elf32_External_Rela
) / 4);
2888 h
->got
.offset
= (bfd_vma
) -1;
2890 if (eh
->dyn_relocs
== NULL
)
2893 /* In the shared -Bsymbolic case, discard space allocated for
2894 dynamic pc-relative relocs against symbols which turn out to be
2895 defined in regular objects. For the normal shared case, discard
2896 space for pc-relative relocs that have become local due to symbol
2897 visibility changes. */
2899 if (bfd_link_pic (info
))
2905 struct elf32_mb_dyn_relocs
**pp
;
2907 for (pp
= &eh
->dyn_relocs
; (p
= *pp
) != NULL
; )
2909 p
->count
-= p
->pc_count
;
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 eh
->dyn_relocs
= NULL
;
2951 /* Finally, allocate space. */
2952 for (p
= eh
->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_size_dynamic_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
;
2977 BFD_ASSERT (dynobj
!= NULL
);
2979 /* Set up .got offsets for local syms, and space for local dynamic
2981 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
2983 bfd_signed_vma
*local_got
;
2984 bfd_signed_vma
*end_local_got
;
2985 bfd_size_type locsymcount
;
2986 Elf_Internal_Shdr
*symtab_hdr
;
2987 unsigned char *lgot_masks
;
2990 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
)
2993 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
2995 struct elf32_mb_dyn_relocs
*p
;
2997 for (p
= ((struct elf32_mb_dyn_relocs
*)
2998 elf_section_data (s
)->local_dynrel
);
3002 if (!bfd_is_abs_section (p
->sec
)
3003 && bfd_is_abs_section (p
->sec
->output_section
))
3005 /* Input section has been discarded, either because
3006 it is a copy of a linkonce section or due to
3007 linker script /DISCARD/, so we'll be discarding
3010 else if (p
->count
!= 0)
3012 srel
= elf_section_data (p
->sec
)->sreloc
;
3013 srel
->size
+= p
->count
* sizeof (Elf32_External_Rela
);
3014 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
3015 info
->flags
|= DF_TEXTREL
;
3020 local_got
= elf_local_got_refcounts (ibfd
);
3024 symtab_hdr
= &elf_tdata (ibfd
)->symtab_hdr
;
3025 locsymcount
= symtab_hdr
->sh_info
;
3026 end_local_got
= local_got
+ locsymcount
;
3027 lgot_masks
= (unsigned char *) end_local_got
;
3029 srel
= htab
->srelgot
;
3031 for (; local_got
< end_local_got
; ++local_got
, ++lgot_masks
)
3035 unsigned int need
= 0;
3036 if ((*lgot_masks
& TLS_TLS
) != 0)
3038 if ((*lgot_masks
& TLS_GD
) != 0)
3040 if ((*lgot_masks
& TLS_LD
) != 0)
3041 htab
->tlsld_got
.refcount
+= 1;
3048 *local_got
= (bfd_vma
) -1;
3052 *local_got
= s
->size
;
3054 if (bfd_link_pic (info
))
3055 srel
->size
+= need
* (sizeof (Elf32_External_Rela
) / 4);
3059 *local_got
= (bfd_vma
) -1;
3063 /* Allocate global sym .plt and .got entries, and space for global
3064 sym dynamic relocs. */
3065 elf_link_hash_traverse (elf_hash_table (info
), allocate_dynrelocs
, info
);
3067 if (htab
->tlsld_got
.refcount
> 0)
3069 htab
->tlsld_got
.offset
= htab
->sgot
->size
;
3070 htab
->sgot
->size
+= 8;
3071 if (bfd_link_pic (info
))
3072 htab
->srelgot
->size
+= sizeof (Elf32_External_Rela
);
3075 htab
->tlsld_got
.offset
= (bfd_vma
) -1;
3077 if (elf_hash_table (info
)->dynamic_sections_created
)
3079 /* Make space for the trailing nop in .plt. */
3080 if (htab
->splt
->size
> 0)
3081 htab
->splt
->size
+= 4;
3084 /* The check_relocs and adjust_dynamic_symbol entry points have
3085 determined the sizes of the various dynamic sections. Allocate
3087 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
3090 bfd_boolean strip
= FALSE
;
3092 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
3095 /* It's OK to base decisions on the section name, because none
3096 of the dynobj section names depend upon the input files. */
3097 name
= bfd_get_section_name (dynobj
, s
);
3099 if (strncmp (name
, ".rela", 5) == 0)
3103 /* If we don't need this section, strip it from the
3104 output file. This is to handle .rela.bss and
3105 .rela.plt. We must create it in
3106 create_dynamic_sections, because it must be created
3107 before the linker maps input sections to output
3108 sections. The linker does that before
3109 adjust_dynamic_symbol is called, and it is that
3110 function which decides whether anything needs to go
3111 into these sections. */
3116 /* We use the reloc_count field as a counter if we need
3117 to copy relocs into the output file. */
3121 else if (s
!= htab
->splt
&& s
!= htab
->sgot
&& s
!= htab
->sgotplt
)
3123 /* It's not one of our sections, so don't allocate space. */
3129 s
->flags
|= SEC_EXCLUDE
;
3133 /* Allocate memory for the section contents. */
3134 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
3135 Unused entries should be reclaimed before the section's contents
3136 are written out, but at the moment this does not happen. Thus in
3137 order to prevent writing out garbage, we initialise the section's
3138 contents to zero. */
3139 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
3140 if (s
->contents
== NULL
&& s
->size
!= 0)
3144 if (elf_hash_table (info
)->dynamic_sections_created
)
3146 /* Add some entries to the .dynamic section. We fill in the
3147 values later, in microblaze_elf_finish_dynamic_sections, but we
3148 must add the entries now so that we get the correct size for
3149 the .dynamic section. The DT_DEBUG entry is filled in by the
3150 dynamic linker and used by the debugger. */
3151 #define add_dynamic_entry(TAG, VAL) \
3152 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3154 if (bfd_link_executable (info
))
3156 if (!add_dynamic_entry (DT_DEBUG
, 0))
3160 if (!add_dynamic_entry (DT_RELA
, 0)
3161 || !add_dynamic_entry (DT_RELASZ
, 0)
3162 || !add_dynamic_entry (DT_RELAENT
, sizeof (Elf32_External_Rela
)))
3165 if (htab
->splt
->size
!= 0)
3167 if (!add_dynamic_entry (DT_PLTGOT
, 0)
3168 || !add_dynamic_entry (DT_PLTRELSZ
, 0)
3169 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
3170 || !add_dynamic_entry (DT_JMPREL
, 0)
3171 || !add_dynamic_entry (DT_BIND_NOW
, 1))
3175 if (info
->flags
& DF_TEXTREL
)
3177 if (!add_dynamic_entry (DT_TEXTREL
, 0))
3181 #undef add_dynamic_entry
3185 /* Finish up dynamic symbol handling. We set the contents of various
3186 dynamic sections here. */
3189 microblaze_elf_finish_dynamic_symbol (bfd
*output_bfd
,
3190 struct bfd_link_info
*info
,
3191 struct elf_link_hash_entry
*h
,
3192 Elf_Internal_Sym
*sym
)
3194 struct elf32_mb_link_hash_table
*htab
;
3195 struct elf32_mb_link_hash_entry
*eh
= elf32_mb_hash_entry(h
);
3197 htab
= elf32_mb_hash_table (info
);
3201 if (h
->plt
.offset
!= (bfd_vma
) -1)
3206 Elf_Internal_Rela rela
;
3212 /* This symbol has an entry in the procedure linkage table. Set
3214 BFD_ASSERT (h
->dynindx
!= -1);
3217 srela
= htab
->srelplt
;
3218 sgotplt
= htab
->sgotplt
;
3219 BFD_ASSERT (splt
!= NULL
&& srela
!= NULL
&& sgotplt
!= NULL
);
3221 plt_index
= h
->plt
.offset
/ PLT_ENTRY_SIZE
- 1; /* first entry reserved. */
3222 got_offset
= (plt_index
+ 3) * 4; /* 3 reserved ??? */
3223 got_addr
= got_offset
;
3225 /* For non-PIC objects we need absolute address of the GOT entry. */
3226 if (!bfd_link_pic (info
))
3227 got_addr
+= htab
->sgotplt
->output_section
->vma
+ sgotplt
->output_offset
;
3229 /* Fill in the entry in the procedure linkage table. */
3230 bfd_put_32 (output_bfd
, PLT_ENTRY_WORD_0
+ ((got_addr
>> 16) & 0xffff),
3231 splt
->contents
+ h
->plt
.offset
);
3232 if (bfd_link_pic (info
))
3233 bfd_put_32 (output_bfd
, PLT_ENTRY_WORD_1
+ (got_addr
& 0xffff),
3234 splt
->contents
+ h
->plt
.offset
+ 4);
3236 bfd_put_32 (output_bfd
, PLT_ENTRY_WORD_1_NOPIC
+ (got_addr
& 0xffff),
3237 splt
->contents
+ h
->plt
.offset
+ 4);
3238 bfd_put_32 (output_bfd
, (bfd_vma
) PLT_ENTRY_WORD_2
,
3239 splt
->contents
+ h
->plt
.offset
+ 8);
3240 bfd_put_32 (output_bfd
, (bfd_vma
) PLT_ENTRY_WORD_3
,
3241 splt
->contents
+ h
->plt
.offset
+ 12);
3243 /* Any additions to the .got section??? */
3244 /* bfd_put_32 (output_bfd,
3245 splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
3246 sgotplt->contents + got_offset); */
3248 /* Fill in the entry in the .rela.plt section. */
3249 rela
.r_offset
= (sgotplt
->output_section
->vma
3250 + sgotplt
->output_offset
3252 rela
.r_info
= ELF32_R_INFO (h
->dynindx
, R_MICROBLAZE_JUMP_SLOT
);
3254 loc
= srela
->contents
;
3255 loc
+= plt_index
* sizeof (Elf32_External_Rela
);
3256 bfd_elf32_swap_reloca_out (output_bfd
, &rela
, loc
);
3258 if (!h
->def_regular
)
3260 /* Mark the symbol as undefined, rather than as defined in
3261 the .plt section. Zero the value. */
3262 sym
->st_shndx
= SHN_UNDEF
;
3267 /* h->got.refcount to be checked ? */
3268 if (h
->got
.offset
!= (bfd_vma
) -1 &&
3269 ! ((h
->got
.offset
& 1) ||
3270 IS_TLS_LD(eh
->tls_mask
) || IS_TLS_GD(eh
->tls_mask
)))
3276 /* This symbol has an entry in the global offset table. Set it
3280 srela
= htab
->srelgot
;
3281 BFD_ASSERT (sgot
!= NULL
&& srela
!= NULL
);
3283 offset
= (sgot
->output_section
->vma
+ sgot
->output_offset
3284 + (h
->got
.offset
&~ (bfd_vma
) 1));
3286 /* If this is a -Bsymbolic link, and the symbol is defined
3287 locally, we just want to emit a RELATIVE reloc. Likewise if
3288 the symbol was forced to be local because of a version file.
3289 The entry in the global offset table will already have been
3290 initialized in the relocate_section function. */
3291 if (bfd_link_pic (info
)
3292 && ((info
->symbolic
&& h
->def_regular
)
3293 || h
->dynindx
== -1))
3295 asection
*sec
= h
->root
.u
.def
.section
;
3296 microblaze_elf_output_dynamic_relocation (output_bfd
,
3297 srela
, srela
->reloc_count
++,
3299 R_MICROBLAZE_REL
, offset
,
3301 + sec
->output_section
->vma
3302 + sec
->output_offset
);
3306 microblaze_elf_output_dynamic_relocation (output_bfd
,
3307 srela
, srela
->reloc_count
++,
3309 R_MICROBLAZE_GLOB_DAT
,
3313 bfd_put_32 (output_bfd
, (bfd_vma
) 0,
3314 sgot
->contents
+ (h
->got
.offset
&~ (bfd_vma
) 1));
3320 Elf_Internal_Rela rela
;
3323 /* This symbols needs a copy reloc. Set it up. */
3325 BFD_ASSERT (h
->dynindx
!= -1);
3327 s
= bfd_get_linker_section (htab
->elf
.dynobj
, ".rela.bss");
3328 BFD_ASSERT (s
!= NULL
);
3330 rela
.r_offset
= (h
->root
.u
.def
.value
3331 + h
->root
.u
.def
.section
->output_section
->vma
3332 + h
->root
.u
.def
.section
->output_offset
);
3333 rela
.r_info
= ELF32_R_INFO (h
->dynindx
, R_MICROBLAZE_COPY
);
3335 loc
= s
->contents
+ s
->reloc_count
++ * sizeof (Elf32_External_Rela
);
3336 bfd_elf32_swap_reloca_out (output_bfd
, &rela
, loc
);
3339 /* Mark some specially defined symbols as absolute. */
3340 if (h
== htab
->elf
.hdynamic
3341 || h
== htab
->elf
.hgot
3342 || h
== htab
->elf
.hplt
)
3343 sym
->st_shndx
= SHN_ABS
;
3349 /* Finish up the dynamic sections. */
3352 microblaze_elf_finish_dynamic_sections (bfd
*output_bfd
,
3353 struct bfd_link_info
*info
)
3356 asection
*sdyn
, *sgot
;
3357 struct elf32_mb_link_hash_table
*htab
;
3359 htab
= elf32_mb_hash_table (info
);
3363 dynobj
= htab
->elf
.dynobj
;
3365 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
3367 if (htab
->elf
.dynamic_sections_created
)
3370 Elf32_External_Dyn
*dyncon
, *dynconend
;
3372 splt
= bfd_get_linker_section (dynobj
, ".plt");
3373 BFD_ASSERT (splt
!= NULL
&& sdyn
!= NULL
);
3375 dyncon
= (Elf32_External_Dyn
*) sdyn
->contents
;
3376 dynconend
= (Elf32_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
3377 for (; dyncon
< dynconend
; dyncon
++)
3379 Elf_Internal_Dyn dyn
;
3383 bfd_elf32_swap_dyn_in (dynobj
, dyncon
, &dyn
);
3387 case DT_PLTGOT
: name
= ".got.plt"; size
= FALSE
; break;
3388 case DT_PLTRELSZ
: name
= ".rela.plt"; size
= TRUE
; break;
3389 case DT_JMPREL
: name
= ".rela.plt"; size
= FALSE
; break;
3390 case DT_RELA
: name
= ".rela.dyn"; size
= FALSE
; break;
3391 case DT_RELASZ
: name
= ".rela.dyn"; size
= TRUE
; break;
3392 default: name
= NULL
; size
= FALSE
; break;
3399 s
= bfd_get_linker_section (dynobj
, name
);
3405 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
3407 dyn
.d_un
.d_val
= s
->size
;
3409 bfd_elf32_swap_dyn_out (output_bfd
, &dyn
, dyncon
);
3413 /* Clear the first entry in the procedure linkage table,
3414 and put a nop in the last four bytes. */
3417 memset (splt
->contents
, 0, PLT_ENTRY_SIZE
);
3418 bfd_put_32 (output_bfd
, (bfd_vma
) 0x80000000 /* nop. */,
3419 splt
->contents
+ splt
->size
- 4);
3422 elf_section_data (splt
->output_section
)->this_hdr
.sh_entsize
= 4;
3425 /* Set the first entry in the global offset table to the address of
3426 the dynamic section. */
3427 sgot
= bfd_get_linker_section (dynobj
, ".got.plt");
3428 if (sgot
&& sgot
->size
> 0)
3431 bfd_put_32 (output_bfd
, (bfd_vma
) 0, sgot
->contents
);
3433 bfd_put_32 (output_bfd
,
3434 sdyn
->output_section
->vma
+ sdyn
->output_offset
,
3436 elf_section_data (sgot
->output_section
)->this_hdr
.sh_entsize
= 4;
3439 if (htab
->sgot
&& htab
->sgot
->size
> 0)
3440 elf_section_data (htab
->sgot
->output_section
)->this_hdr
.sh_entsize
= 4;
3445 /* Hook called by the linker routine which adds symbols from an object
3446 file. We use it to put .comm items in .sbss, and not .bss. */
3449 microblaze_elf_add_symbol_hook (bfd
*abfd
,
3450 struct bfd_link_info
*info
,
3451 Elf_Internal_Sym
*sym
,
3452 const char **namep ATTRIBUTE_UNUSED
,
3453 flagword
*flagsp ATTRIBUTE_UNUSED
,
3457 if (sym
->st_shndx
== SHN_COMMON
3458 && !bfd_link_relocatable (info
)
3459 && sym
->st_size
<= elf_gp_size (abfd
))
3461 /* Common symbols less than or equal to -G nn bytes are automatically
3463 *secp
= bfd_make_section_old_way (abfd
, ".sbss");
3465 || ! bfd_set_section_flags (abfd
, *secp
, SEC_IS_COMMON
))
3468 *valp
= sym
->st_size
;
3474 #define TARGET_LITTLE_SYM microblaze_elf32_le_vec
3475 #define TARGET_LITTLE_NAME "elf32-microblazeel"
3477 #define TARGET_BIG_SYM microblaze_elf32_vec
3478 #define TARGET_BIG_NAME "elf32-microblaze"
3480 #define ELF_ARCH bfd_arch_microblaze
3481 #define ELF_TARGET_ID MICROBLAZE_ELF_DATA
3482 #define ELF_MACHINE_CODE EM_MICROBLAZE
3483 #define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
3484 #define ELF_MAXPAGESIZE 0x1000
3485 #define elf_info_to_howto microblaze_elf_info_to_howto
3486 #define elf_info_to_howto_rel NULL
3488 #define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
3489 #define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name
3490 #define elf_backend_relocate_section microblaze_elf_relocate_section
3491 #define bfd_elf32_bfd_relax_section microblaze_elf_relax_section
3492 #define bfd_elf32_bfd_merge_private_bfd_data _bfd_generic_verify_endian_match
3493 #define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
3495 #define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
3496 #define elf_backend_gc_sweep_hook microblaze_elf_gc_sweep_hook
3497 #define elf_backend_check_relocs microblaze_elf_check_relocs
3498 #define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
3499 #define bfd_elf32_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
3500 #define elf_backend_can_gc_sections 1
3501 #define elf_backend_can_refcount 1
3502 #define elf_backend_want_got_plt 1
3503 #define elf_backend_plt_readonly 1
3504 #define elf_backend_got_header_size 12
3505 #define elf_backend_rela_normal 1
3507 #define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
3508 #define elf_backend_create_dynamic_sections microblaze_elf_create_dynamic_sections
3509 #define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
3510 #define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
3511 #define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
3512 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
3514 #include "elf32-target.h"