1 /* Xilinx MicroBlaze-specific support for 32-bit ELF
3 Copyright (C) 2009-2020 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 TEXTPCREL relocation. Table-entry not really used. */
255 HOWTO (R_MICROBLAZE_TEXTPCREL_64
, /* Type. */
257 2, /* Size (0 = byte, 1 = short, 2 = long). */
259 TRUE
, /* PC_relative. */
261 complain_overflow_dont
, /* Complain on overflow. */
262 bfd_elf_generic_reloc
, /* Special Function. */
263 "R_MICROBLAZE_TEXTPCREL_64", /* Name. */
264 FALSE
, /* Partial Inplace. */
265 0, /* Source Mask. */
266 0x0000ffff, /* Dest Mask. */
267 TRUE
), /* PC relative offset? */
269 /* A 64 bit GOT relocation. Table-entry not really used. */
270 HOWTO (R_MICROBLAZE_GOT_64
, /* Type. */
272 2, /* Size (0 = byte, 1 = short, 2 = long). */
274 FALSE
, /* PC_relative. */
276 complain_overflow_dont
, /* Complain on overflow. */
277 bfd_elf_generic_reloc
,/* Special Function. */
278 "R_MICROBLAZE_GOT_64",/* Name. */
279 FALSE
, /* Partial Inplace. */
280 0, /* Source Mask. */
281 0x0000ffff, /* Dest Mask. */
282 FALSE
), /* PC relative offset? */
284 /* A 64 bit TEXTREL relocation. Table-entry not really used. */
285 HOWTO (R_MICROBLAZE_TEXTREL_64
, /* Type. */
287 2, /* Size (0 = byte, 1 = short, 2 = long). */
289 FALSE
, /* PC_relative. */
291 complain_overflow_dont
, /* Complain on overflow. */
292 bfd_elf_generic_reloc
,/* Special Function. */
293 "R_MICROBLAZE_TEXTREL_64",/* Name. */
294 FALSE
, /* Partial Inplace. */
295 0, /* Source Mask. */
296 0x0000ffff, /* Dest Mask. */
297 FALSE
), /* PC relative offset? */
299 /* A 64 bit PLT relocation. Table-entry not really used. */
300 HOWTO (R_MICROBLAZE_PLT_64
, /* 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_PLT_64",/* 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_REL
, /* 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_REL", /* Name. */
324 FALSE
, /* Partial Inplace. */
325 0, /* Source Mask. */
326 0x0000ffff, /* Dest Mask. */
327 TRUE
), /* PC relative offset? */
329 /* Table-entry not really used. */
330 HOWTO (R_MICROBLAZE_JUMP_SLOT
,/* Type. */
332 2, /* Size (0 = byte, 1 = short, 2 = long). */
334 TRUE
, /* PC_relative. */
336 complain_overflow_dont
, /* Complain on overflow. */
337 bfd_elf_generic_reloc
,/* Special Function. */
338 "R_MICROBLAZE_JUMP_SLOT", /* Name. */
339 FALSE
, /* Partial Inplace. */
340 0, /* Source Mask. */
341 0x0000ffff, /* Dest Mask. */
342 TRUE
), /* PC relative offset? */
344 /* Table-entry not really used. */
345 HOWTO (R_MICROBLAZE_GLOB_DAT
,/* Type. */
347 2, /* Size (0 = byte, 1 = short, 2 = long). */
349 TRUE
, /* PC_relative. */
351 complain_overflow_dont
, /* Complain on overflow. */
352 bfd_elf_generic_reloc
,/* Special Function. */
353 "R_MICROBLAZE_GLOB_DAT", /* Name. */
354 FALSE
, /* Partial Inplace. */
355 0, /* Source Mask. */
356 0x0000ffff, /* Dest Mask. */
357 TRUE
), /* PC relative offset? */
359 /* A 64 bit GOT relative relocation. Table-entry not really used. */
360 HOWTO (R_MICROBLAZE_GOTOFF_64
, /* 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_GOTOFF_64", /* Name. */
369 FALSE
, /* Partial Inplace. */
370 0, /* Source Mask. */
371 0x0000ffff, /* Dest Mask. */
372 FALSE
), /* PC relative offset? */
374 /* A 32 bit GOT relative relocation. Table-entry not really used. */
375 HOWTO (R_MICROBLAZE_GOTOFF_32
, /* Type. */
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_GOTOFF_32", /* Name. */
384 FALSE
, /* Partial Inplace. */
385 0, /* Source Mask. */
386 0x0000ffff, /* Dest Mask. */
387 FALSE
), /* PC relative offset? */
389 /* COPY relocation. Table-entry not really used. */
390 HOWTO (R_MICROBLAZE_COPY
, /* Type. */
392 2, /* Size (0 = byte, 1 = short, 2 = long). */
394 FALSE
, /* PC_relative. */
396 complain_overflow_dont
, /* Complain on overflow. */
397 bfd_elf_generic_reloc
,/* Special Function. */
398 "R_MICROBLAZE_COPY", /* Name. */
399 FALSE
, /* Partial Inplace. */
400 0, /* Source Mask. */
401 0x0000ffff, /* Dest Mask. */
402 FALSE
), /* PC relative offset? */
404 /* Marker relocs for TLS. */
405 HOWTO (R_MICROBLAZE_TLS
,
407 2, /* size (0 = byte, 1 = short, 2 = long) */
409 FALSE
, /* pc_relative */
411 complain_overflow_dont
, /* complain_on_overflow */
412 bfd_elf_generic_reloc
, /* special_function */
413 "R_MICROBLAZE_TLS", /* name */
414 FALSE
, /* partial_inplace */
416 0x0000ffff, /* dst_mask */
417 FALSE
), /* pcrel_offset */
419 HOWTO (R_MICROBLAZE_TLSGD
,
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_TLSGD", /* name */
428 FALSE
, /* partial_inplace */
430 0x0000ffff, /* dst_mask */
431 FALSE
), /* pcrel_offset */
433 HOWTO (R_MICROBLAZE_TLSLD
,
435 2, /* size (0 = byte, 1 = short, 2 = long) */
437 FALSE
, /* pc_relative */
439 complain_overflow_dont
, /* complain_on_overflow */
440 bfd_elf_generic_reloc
, /* special_function */
441 "R_MICROBLAZE_TLSLD", /* name */
442 FALSE
, /* partial_inplace */
444 0x0000ffff, /* dst_mask */
445 FALSE
), /* pcrel_offset */
447 /* Computes the load module index of the load module that contains the
448 definition of its TLS sym. */
449 HOWTO (R_MICROBLAZE_TLSDTPMOD32
,
451 2, /* size (0 = byte, 1 = short, 2 = long) */
453 FALSE
, /* pc_relative */
455 complain_overflow_dont
, /* complain_on_overflow */
456 bfd_elf_generic_reloc
, /* special_function */
457 "R_MICROBLAZE_TLSDTPMOD32", /* name */
458 FALSE
, /* partial_inplace */
460 0x0000ffff, /* dst_mask */
461 FALSE
), /* pcrel_offset */
463 /* Computes a dtv-relative displacement, the difference between the value
464 of sym+add and the base address of the thread-local storage block that
465 contains the definition of sym, minus 0x8000. Used for initializing GOT */
466 HOWTO (R_MICROBLAZE_TLSDTPREL32
,
468 2, /* size (0 = byte, 1 = short, 2 = long) */
470 FALSE
, /* pc_relative */
472 complain_overflow_dont
, /* complain_on_overflow */
473 bfd_elf_generic_reloc
, /* special_function */
474 "R_MICROBLAZE_TLSDTPREL32", /* name */
475 FALSE
, /* partial_inplace */
477 0x0000ffff, /* dst_mask */
478 FALSE
), /* pcrel_offset */
480 /* Computes a dtv-relative displacement, the difference between the value
481 of sym+add and the base address of the thread-local storage block that
482 contains the definition of sym, minus 0x8000. */
483 HOWTO (R_MICROBLAZE_TLSDTPREL64
,
485 2, /* size (0 = byte, 1 = short, 2 = long) */
487 FALSE
, /* pc_relative */
489 complain_overflow_dont
, /* complain_on_overflow */
490 bfd_elf_generic_reloc
, /* special_function */
491 "R_MICROBLAZE_TLSDTPREL64", /* name */
492 FALSE
, /* partial_inplace */
494 0x0000ffff, /* dst_mask */
495 FALSE
), /* pcrel_offset */
497 /* Computes a tp-relative displacement, the difference between the value of
498 sym+add and the value of the thread pointer (r13). */
499 HOWTO (R_MICROBLAZE_TLSGOTTPREL32
,
501 2, /* size (0 = byte, 1 = short, 2 = long) */
503 FALSE
, /* pc_relative */
505 complain_overflow_dont
, /* complain_on_overflow */
506 bfd_elf_generic_reloc
, /* special_function */
507 "R_MICROBLAZE_TLSGOTTPREL32", /* name */
508 FALSE
, /* partial_inplace */
510 0x0000ffff, /* dst_mask */
511 FALSE
), /* pcrel_offset */
513 /* Computes a tp-relative displacement, the difference between the value of
514 sym+add and the value of the thread pointer (r13). */
515 HOWTO (R_MICROBLAZE_TLSTPREL32
,
517 2, /* size (0 = byte, 1 = short, 2 = long) */
519 FALSE
, /* pc_relative */
521 complain_overflow_dont
, /* complain_on_overflow */
522 bfd_elf_generic_reloc
, /* special_function */
523 "R_MICROBLAZE_TLSTPREL32", /* name */
524 FALSE
, /* partial_inplace */
526 0x0000ffff, /* dst_mask */
527 FALSE
), /* pcrel_offset */
532 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
535 /* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */
538 microblaze_elf_howto_init (void)
542 for (i
= NUM_ELEM (microblaze_elf_howto_raw
); i
--;)
546 type
= microblaze_elf_howto_raw
[i
].type
;
548 BFD_ASSERT (type
< NUM_ELEM (microblaze_elf_howto_table
));
550 microblaze_elf_howto_table
[type
] = & microblaze_elf_howto_raw
[i
];
554 static reloc_howto_type
*
555 microblaze_elf_reloc_type_lookup (bfd
* abfd ATTRIBUTE_UNUSED
,
556 bfd_reloc_code_real_type code
)
558 enum elf_microblaze_reloc_type microblaze_reloc
= R_MICROBLAZE_NONE
;
563 microblaze_reloc
= R_MICROBLAZE_NONE
;
565 case BFD_RELOC_MICROBLAZE_64_NONE
:
566 microblaze_reloc
= R_MICROBLAZE_64_NONE
;
569 microblaze_reloc
= R_MICROBLAZE_32
;
571 /* RVA is treated the same as 32 */
573 microblaze_reloc
= R_MICROBLAZE_32
;
575 case BFD_RELOC_32_PCREL
:
576 microblaze_reloc
= R_MICROBLAZE_32_PCREL
;
578 case BFD_RELOC_64_PCREL
:
579 microblaze_reloc
= R_MICROBLAZE_64_PCREL
;
581 case BFD_RELOC_MICROBLAZE_32_LO_PCREL
:
582 microblaze_reloc
= R_MICROBLAZE_32_PCREL_LO
;
585 microblaze_reloc
= R_MICROBLAZE_64
;
587 case BFD_RELOC_MICROBLAZE_32_LO
:
588 microblaze_reloc
= R_MICROBLAZE_32_LO
;
590 case BFD_RELOC_MICROBLAZE_32_ROSDA
:
591 microblaze_reloc
= R_MICROBLAZE_SRO32
;
593 case BFD_RELOC_MICROBLAZE_32_RWSDA
:
594 microblaze_reloc
= R_MICROBLAZE_SRW32
;
596 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM
:
597 microblaze_reloc
= R_MICROBLAZE_32_SYM_OP_SYM
;
599 case BFD_RELOC_VTABLE_INHERIT
:
600 microblaze_reloc
= R_MICROBLAZE_GNU_VTINHERIT
;
602 case BFD_RELOC_VTABLE_ENTRY
:
603 microblaze_reloc
= R_MICROBLAZE_GNU_VTENTRY
;
605 case BFD_RELOC_MICROBLAZE_64_GOTPC
:
606 microblaze_reloc
= R_MICROBLAZE_GOTPC_64
;
608 case BFD_RELOC_MICROBLAZE_64_GOT
:
609 microblaze_reloc
= R_MICROBLAZE_GOT_64
;
611 case BFD_RELOC_MICROBLAZE_64_TEXTPCREL
:
612 microblaze_reloc
= R_MICROBLAZE_TEXTPCREL_64
;
614 case BFD_RELOC_MICROBLAZE_64_TEXTREL
:
615 microblaze_reloc
= R_MICROBLAZE_TEXTREL_64
;
617 case BFD_RELOC_MICROBLAZE_64_PLT
:
618 microblaze_reloc
= R_MICROBLAZE_PLT_64
;
620 case BFD_RELOC_MICROBLAZE_64_GOTOFF
:
621 microblaze_reloc
= R_MICROBLAZE_GOTOFF_64
;
623 case BFD_RELOC_MICROBLAZE_32_GOTOFF
:
624 microblaze_reloc
= R_MICROBLAZE_GOTOFF_32
;
626 case BFD_RELOC_MICROBLAZE_64_TLSGD
:
627 microblaze_reloc
= R_MICROBLAZE_TLSGD
;
629 case BFD_RELOC_MICROBLAZE_64_TLSLD
:
630 microblaze_reloc
= R_MICROBLAZE_TLSLD
;
632 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL
:
633 microblaze_reloc
= R_MICROBLAZE_TLSDTPREL32
;
635 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL
:
636 microblaze_reloc
= R_MICROBLAZE_TLSDTPREL64
;
638 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD
:
639 microblaze_reloc
= R_MICROBLAZE_TLSDTPMOD32
;
641 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL
:
642 microblaze_reloc
= R_MICROBLAZE_TLSGOTTPREL32
;
644 case BFD_RELOC_MICROBLAZE_64_TLSTPREL
:
645 microblaze_reloc
= R_MICROBLAZE_TLSTPREL32
;
647 case BFD_RELOC_MICROBLAZE_COPY
:
648 microblaze_reloc
= R_MICROBLAZE_COPY
;
651 return (reloc_howto_type
*) NULL
;
654 if (!microblaze_elf_howto_table
[R_MICROBLAZE_32
])
655 /* Initialize howto table if needed. */
656 microblaze_elf_howto_init ();
658 return microblaze_elf_howto_table
[(int) microblaze_reloc
];
661 static reloc_howto_type
*
662 microblaze_elf_reloc_name_lookup (bfd
*abfd ATTRIBUTE_UNUSED
,
667 for (i
= 0; i
< NUM_ELEM (microblaze_elf_howto_raw
); i
++)
668 if (microblaze_elf_howto_raw
[i
].name
!= NULL
669 && strcasecmp (microblaze_elf_howto_raw
[i
].name
, r_name
) == 0)
670 return µblaze_elf_howto_raw
[i
];
675 /* Set the howto pointer for a RCE ELF reloc. */
678 microblaze_elf_info_to_howto (bfd
* abfd
,
680 Elf_Internal_Rela
* dst
)
684 if (!microblaze_elf_howto_table
[R_MICROBLAZE_32
])
685 /* Initialize howto table if needed. */
686 microblaze_elf_howto_init ();
688 r_type
= ELF32_R_TYPE (dst
->r_info
);
689 if (r_type
>= R_MICROBLAZE_max
)
691 /* xgettext:c-format */
692 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
694 bfd_set_error (bfd_error_bad_value
);
698 cache_ptr
->howto
= microblaze_elf_howto_table
[r_type
];
702 /* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
705 microblaze_elf_is_local_label_name (bfd
*abfd
, const char *name
)
707 if (name
[0] == 'L' && name
[1] == '.')
710 if (name
[0] == '$' && name
[1] == 'L')
713 /* With gcc, the labels go back to starting with '.', so we accept
714 the generic ELF local label syntax as well. */
715 return _bfd_elf_is_local_label_name (abfd
, name
);
718 /* ELF linker hash entry. */
720 struct elf32_mb_link_hash_entry
722 struct elf_link_hash_entry elf
;
724 /* Track dynamic relocs copied for this symbol. */
725 struct elf_dyn_relocs
*dyn_relocs
;
727 /* TLS Reference Types for the symbol; Updated by check_relocs */
728 #define TLS_GD 1 /* GD reloc. */
729 #define TLS_LD 2 /* LD reloc. */
730 #define TLS_TPREL 4 /* TPREL reloc, => IE. */
731 #define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
732 #define TLS_TLS 16 /* Any TLS reloc. */
733 unsigned char tls_mask
;
737 #define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD))
738 #define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD))
739 #define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL))
740 #define IS_TLS_NONE(x) (x == 0)
742 #define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent))
744 /* ELF linker hash table. */
746 struct elf32_mb_link_hash_table
748 struct elf_link_hash_table elf
;
750 /* Small local sym to section mapping cache. */
751 struct sym_cache sym_sec
;
753 /* TLS Local Dynamic GOT Entry */
755 bfd_signed_vma refcount
;
760 /* Nonzero if this section has TLS related relocations. */
761 #define has_tls_reloc sec_flg0
763 /* Get the ELF linker hash table from a link_info structure. */
765 #define elf32_mb_hash_table(p) \
766 (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
767 == MICROBLAZE_ELF_DATA ? ((struct elf32_mb_link_hash_table *) ((p)->hash)) : NULL)
769 /* Create an entry in a microblaze ELF linker hash table. */
771 static struct bfd_hash_entry
*
772 link_hash_newfunc (struct bfd_hash_entry
*entry
,
773 struct bfd_hash_table
*table
,
776 /* Allocate the structure if it has not already been allocated by a
780 entry
= bfd_hash_allocate (table
,
781 sizeof (struct elf32_mb_link_hash_entry
));
786 /* Call the allocation method of the superclass. */
787 entry
= _bfd_elf_link_hash_newfunc (entry
, table
, string
);
790 struct elf32_mb_link_hash_entry
*eh
;
792 eh
= (struct elf32_mb_link_hash_entry
*) entry
;
793 eh
->dyn_relocs
= NULL
;
800 /* Create a mb ELF linker hash table. */
802 static struct bfd_link_hash_table
*
803 microblaze_elf_link_hash_table_create (bfd
*abfd
)
805 struct elf32_mb_link_hash_table
*ret
;
806 size_t amt
= sizeof (struct elf32_mb_link_hash_table
);
808 ret
= (struct elf32_mb_link_hash_table
*) bfd_zmalloc (amt
);
812 if (!_bfd_elf_link_hash_table_init (&ret
->elf
, abfd
, link_hash_newfunc
,
813 sizeof (struct elf32_mb_link_hash_entry
),
814 MICROBLAZE_ELF_DATA
))
820 return &ret
->elf
.root
;
823 /* Set the values of the small data pointers. */
826 microblaze_elf_final_sdp (struct bfd_link_info
*info
)
828 struct bfd_link_hash_entry
*h
;
830 h
= bfd_link_hash_lookup (info
->hash
, RO_SDA_ANCHOR_NAME
, FALSE
, FALSE
, TRUE
);
831 if (h
!= (struct bfd_link_hash_entry
*) NULL
832 && h
->type
== bfd_link_hash_defined
)
833 ro_small_data_pointer
= (h
->u
.def
.value
834 + h
->u
.def
.section
->output_section
->vma
835 + h
->u
.def
.section
->output_offset
);
837 h
= bfd_link_hash_lookup (info
->hash
, RW_SDA_ANCHOR_NAME
, FALSE
, FALSE
, TRUE
);
838 if (h
!= (struct bfd_link_hash_entry
*) NULL
839 && h
->type
== bfd_link_hash_defined
)
840 rw_small_data_pointer
= (h
->u
.def
.value
841 + h
->u
.def
.section
->output_section
->vma
842 + h
->u
.def
.section
->output_offset
);
846 dtprel_base (struct bfd_link_info
*info
)
848 /* If tls_sec is NULL, we should have signalled an error already. */
849 if (elf_hash_table (info
)->tls_sec
== NULL
)
851 return elf_hash_table (info
)->tls_sec
->vma
;
854 /* The size of the thread control block. */
857 /* Output a simple dynamic relocation into SRELOC. */
860 microblaze_elf_output_dynamic_relocation (bfd
*output_bfd
,
862 unsigned long reloc_index
,
869 Elf_Internal_Rela rel
;
871 rel
.r_info
= ELF32_R_INFO (indx
, r_type
);
872 rel
.r_offset
= offset
;
873 rel
.r_addend
= addend
;
875 bfd_elf32_swap_reloca_out (output_bfd
, &rel
,
876 (sreloc
->contents
+ reloc_index
* sizeof (Elf32_External_Rela
)));
879 /* This code is taken from elf32-m32r.c
880 There is some attempt to make this function usable for many architectures,
881 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
882 if only to serve as a learning tool.
884 The RELOCATE_SECTION function is called by the new ELF backend linker
885 to handle the relocations for a section.
887 The relocs are always passed as Rela structures; if the section
888 actually uses Rel structures, the r_addend field will always be
891 This function is responsible for adjust the section contents as
892 necessary, and (if using Rela relocs and generating a
893 relocatable output file) adjusting the reloc addend as
896 This function does not have to worry about setting the reloc
897 address or the reloc symbol index.
899 LOCAL_SYMS is a pointer to the swapped in local symbols.
901 LOCAL_SECTIONS is an array giving the section in the input file
902 corresponding to the st_shndx field of each local symbol.
904 The global hash table entry for the global symbols can be found
905 via elf_sym_hashes (input_bfd).
907 When generating relocatable output, this function must handle
908 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
909 going to be the section symbol corresponding to the output
910 section, which means that the addend must be adjusted
914 microblaze_elf_relocate_section (bfd
*output_bfd
,
915 struct bfd_link_info
*info
,
917 asection
*input_section
,
919 Elf_Internal_Rela
*relocs
,
920 Elf_Internal_Sym
*local_syms
,
921 asection
**local_sections
)
923 struct elf32_mb_link_hash_table
*htab
;
924 Elf_Internal_Shdr
*symtab_hdr
= &elf_tdata (input_bfd
)->symtab_hdr
;
925 struct elf_link_hash_entry
**sym_hashes
= elf_sym_hashes (input_bfd
);
926 Elf_Internal_Rela
*rel
, *relend
;
927 int endian
= (bfd_little_endian (output_bfd
)) ? 0 : 2;
928 /* Assume success. */
929 bfd_boolean ret
= TRUE
;
931 bfd_vma
*local_got_offsets
;
932 unsigned int tls_type
;
934 if (!microblaze_elf_howto_table
[R_MICROBLAZE_max
-1])
935 microblaze_elf_howto_init ();
937 htab
= elf32_mb_hash_table (info
);
941 local_got_offsets
= elf_local_got_offsets (input_bfd
);
943 sreloc
= elf_section_data (input_section
)->sreloc
;
946 relend
= relocs
+ input_section
->reloc_count
;
947 for (; rel
< relend
; rel
++)
950 reloc_howto_type
*howto
;
951 unsigned long r_symndx
;
952 bfd_vma addend
= rel
->r_addend
;
953 bfd_vma offset
= rel
->r_offset
;
954 struct elf_link_hash_entry
*h
;
955 Elf_Internal_Sym
*sym
;
957 const char *sym_name
;
958 bfd_reloc_status_type r
= bfd_reloc_ok
;
959 const char *errmsg
= NULL
;
960 bfd_boolean unresolved_reloc
= FALSE
;
963 r_type
= ELF32_R_TYPE (rel
->r_info
);
966 if (r_type
< 0 || r_type
>= (int) R_MICROBLAZE_max
)
968 /* xgettext:c-format */
969 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
970 input_bfd
, (int) r_type
);
971 bfd_set_error (bfd_error_bad_value
);
976 howto
= microblaze_elf_howto_table
[r_type
];
977 r_symndx
= ELF32_R_SYM (rel
->r_info
);
979 if (bfd_link_relocatable (info
))
981 /* This is a relocatable link. We don't have to change
982 anything, unless the reloc is against a section symbol,
983 in which case we have to adjust according to where the
984 section symbol winds up in the output section. */
986 if (r_symndx
>= symtab_hdr
->sh_info
)
987 /* External symbol. */
991 sym
= local_syms
+ r_symndx
;
992 sym_name
= "<local symbol>";
993 /* STT_SECTION: symbol is associated with a section. */
994 if (ELF_ST_TYPE (sym
->st_info
) != STT_SECTION
)
995 /* Symbol isn't associated with a section. Nothing to do. */
998 sec
= local_sections
[r_symndx
];
999 addend
+= sec
->output_offset
+ sym
->st_value
;
1001 /* This can't be done for USE_REL because it doesn't mean anything
1002 and elf_link_input_bfd asserts this stays zero. */
1003 /* rel->r_addend = addend; */
1007 /* Addends are stored with relocs. We're done. */
1010 /* If partial_inplace, we need to store any additional addend
1011 back in the section. */
1012 if (!howto
->partial_inplace
)
1014 /* ??? Here is a nice place to call a special_function like handler. */
1015 r
= _bfd_relocate_contents (howto
, input_bfd
, addend
,
1017 #endif /* USE_REL */
1022 bfd_boolean resolved_to_zero
;
1024 /* This is a final link. */
1027 unresolved_reloc
= FALSE
;
1029 if (r_symndx
< symtab_hdr
->sh_info
)
1032 sym
= local_syms
+ r_symndx
;
1033 sec
= local_sections
[r_symndx
];
1036 sym_name
= "<local symbol>";
1037 relocation
= _bfd_elf_rela_local_sym (output_bfd
, sym
, &sec
, rel
);
1038 /* r_addend may have changed if the reference section was
1040 addend
= rel
->r_addend
;
1044 /* External symbol. */
1045 bfd_boolean warned ATTRIBUTE_UNUSED
;
1046 bfd_boolean ignored ATTRIBUTE_UNUSED
;
1048 RELOC_FOR_GLOBAL_SYMBOL (info
, input_bfd
, input_section
, rel
,
1049 r_symndx
, symtab_hdr
, sym_hashes
,
1051 unresolved_reloc
, warned
, ignored
);
1052 sym_name
= h
->root
.root
.string
;
1055 /* Sanity check the address. */
1056 if (offset
> bfd_get_section_limit (input_bfd
, input_section
))
1058 r
= bfd_reloc_outofrange
;
1062 resolved_to_zero
= (h
!= NULL
1063 && UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
));
1065 switch ((int) r_type
)
1067 case (int) R_MICROBLAZE_SRO32
:
1071 /* Only relocate if the symbol is defined. */
1074 name
= bfd_section_name (sec
);
1076 if (strcmp (name
, ".sdata2") == 0
1077 || strcmp (name
, ".sbss2") == 0)
1079 if (ro_small_data_pointer
== 0)
1080 microblaze_elf_final_sdp (info
);
1081 if (ro_small_data_pointer
== 0)
1084 r
= bfd_reloc_undefined
;
1088 /* At this point `relocation' contains the object's
1090 relocation
-= ro_small_data_pointer
;
1091 /* Now it contains the offset from _SDA2_BASE_. */
1092 r
= _bfd_final_link_relocate (howto
, input_bfd
,
1095 relocation
, addend
);
1100 /* xgettext:c-format */
1101 (_("%pB: the target (%s) of an %s relocation"
1102 " is in the wrong section (%pA)"),
1105 microblaze_elf_howto_table
[(int) r_type
]->name
,
1107 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1115 case (int) R_MICROBLAZE_SRW32
:
1119 /* Only relocate if the symbol is defined. */
1122 name
= bfd_section_name (sec
);
1124 if (strcmp (name
, ".sdata") == 0
1125 || strcmp (name
, ".sbss") == 0)
1127 if (rw_small_data_pointer
== 0)
1128 microblaze_elf_final_sdp (info
);
1129 if (rw_small_data_pointer
== 0)
1132 r
= bfd_reloc_undefined
;
1136 /* At this point `relocation' contains the object's
1138 relocation
-= rw_small_data_pointer
;
1139 /* Now it contains the offset from _SDA_BASE_. */
1140 r
= _bfd_final_link_relocate (howto
, input_bfd
,
1143 relocation
, addend
);
1148 /* xgettext:c-format */
1149 (_("%pB: the target (%s) of an %s relocation"
1150 " is in the wrong section (%pA)"),
1153 microblaze_elf_howto_table
[(int) r_type
]->name
,
1155 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1163 case (int) R_MICROBLAZE_32_SYM_OP_SYM
:
1164 break; /* Do nothing. */
1166 case (int) R_MICROBLAZE_GOTPC_64
:
1167 relocation
= (htab
->elf
.sgotplt
->output_section
->vma
1168 + htab
->elf
.sgotplt
->output_offset
);
1169 relocation
-= (input_section
->output_section
->vma
1170 + input_section
->output_offset
1171 + offset
+ INST_WORD_SIZE
);
1172 relocation
+= addend
;
1173 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1174 contents
+ offset
+ endian
);
1175 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1176 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1179 case (int) R_MICROBLAZE_TEXTPCREL_64
:
1180 relocation
= input_section
->output_section
->vma
;
1181 relocation
-= (input_section
->output_section
->vma
1182 + input_section
->output_offset
1183 + offset
+ INST_WORD_SIZE
);
1184 relocation
+= addend
;
1185 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1186 contents
+ offset
+ endian
);
1187 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1188 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1191 case (int) R_MICROBLAZE_PLT_64
:
1194 if (htab
->elf
.splt
!= NULL
&& h
!= NULL
1195 && h
->plt
.offset
!= (bfd_vma
) -1)
1197 relocation
= (htab
->elf
.splt
->output_section
->vma
1198 + htab
->elf
.splt
->output_offset
1200 unresolved_reloc
= FALSE
;
1201 immediate
= relocation
- (input_section
->output_section
->vma
1202 + input_section
->output_offset
1203 + offset
+ INST_WORD_SIZE
);
1204 bfd_put_16 (input_bfd
, (immediate
>> 16) & 0xffff,
1205 contents
+ offset
+ endian
);
1206 bfd_put_16 (input_bfd
, immediate
& 0xffff,
1207 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1211 relocation
-= (input_section
->output_section
->vma
1212 + input_section
->output_offset
1213 + offset
+ INST_WORD_SIZE
);
1214 immediate
= relocation
;
1215 bfd_put_16 (input_bfd
, (immediate
>> 16) & 0xffff,
1216 contents
+ offset
+ endian
);
1217 bfd_put_16 (input_bfd
, immediate
& 0xffff,
1218 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1223 case (int) R_MICROBLAZE_TLSGD
:
1224 tls_type
= (TLS_TLS
| TLS_GD
);
1226 case (int) R_MICROBLAZE_TLSLD
:
1227 tls_type
= (TLS_TLS
| TLS_LD
);
1230 case (int) R_MICROBLAZE_GOT_64
:
1235 bfd_vma static_value
;
1237 bfd_boolean need_relocs
= FALSE
;
1238 if (htab
->elf
.sgot
== NULL
)
1244 /* 1. Identify GOT Offset;
1245 2. Compute Static Values
1246 3. Process Module Id, Process Offset
1247 4. Fixup Relocation with GOT offset value. */
1249 /* 1. Determine GOT Offset to use : TLS_LD, global, local */
1250 if (IS_TLS_LD (tls_type
))
1251 offp
= &htab
->tlsld_got
.offset
;
1254 if (htab
->elf
.sgotplt
!= NULL
1255 && h
->got
.offset
!= (bfd_vma
) -1)
1256 offp
= &h
->got
.offset
;
1262 if (local_got_offsets
== NULL
)
1264 offp
= &local_got_offsets
[r_symndx
];
1273 if (IS_TLS_LD(tls_type
) || IS_TLS_GD(tls_type
))
1276 /* Symbol index to use for relocs */
1280 elf_hash_table (info
)->dynamic_sections_created
;
1282 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn
,
1283 bfd_link_pic (info
),
1285 && (!bfd_link_pic (info
)
1286 || !SYMBOL_REFERENCES_LOCAL (info
, h
)))
1290 /* Need to generate relocs ? */
1291 if ((bfd_link_pic (info
) || indx
!= 0)
1293 || (ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
1294 && !resolved_to_zero
)
1295 || h
->root
.type
!= bfd_link_hash_undefweak
))
1298 /* 2. Compute/Emit Static value of r-expression */
1299 static_value
= relocation
+ addend
;
1301 /* 3. Process module-id and offset */
1302 if (! ((*offp
) & 1) )
1306 got_offset
= (htab
->elf
.sgot
->output_section
->vma
1307 + htab
->elf
.sgot
->output_offset
1310 /* Process module-id */
1311 if (IS_TLS_LD(tls_type
))
1313 if (! bfd_link_pic (info
))
1314 bfd_put_32 (output_bfd
, 1,
1315 htab
->elf
.sgot
->contents
+ off
);
1317 microblaze_elf_output_dynamic_relocation
1320 htab
->elf
.srelgot
->reloc_count
++,
1321 /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32
,
1324 else if (IS_TLS_GD(tls_type
))
1327 bfd_put_32 (output_bfd
, 1,
1328 htab
->elf
.sgot
->contents
+ off
);
1330 microblaze_elf_output_dynamic_relocation
1333 htab
->elf
.srelgot
->reloc_count
++,
1334 /* symindex= */ indx
, R_MICROBLAZE_TLSDTPMOD32
,
1335 got_offset
, indx
? 0 : static_value
);
1338 /* Process Offset */
1339 if (htab
->elf
.srelgot
== NULL
)
1342 got_offset
= (htab
->elf
.sgot
->output_section
->vma
1343 + htab
->elf
.sgot
->output_offset
1345 if (IS_TLS_LD(tls_type
))
1347 /* For LD, offset should be 0 */
1349 bfd_put_32 (output_bfd
, 0,
1350 htab
->elf
.sgot
->contents
+ off2
);
1352 else if (IS_TLS_GD(tls_type
))
1355 static_value
-= dtprel_base(info
);
1357 microblaze_elf_output_dynamic_relocation
1360 htab
->elf
.srelgot
->reloc_count
++,
1361 /* symindex= */ indx
, R_MICROBLAZE_TLSDTPREL32
,
1362 got_offset
, indx
? 0 : static_value
);
1364 bfd_put_32 (output_bfd
, static_value
,
1365 htab
->elf
.sgot
->contents
+ off2
);
1369 bfd_put_32 (output_bfd
, static_value
,
1370 htab
->elf
.sgot
->contents
+ off2
);
1372 /* Relocs for dyn symbols generated by
1373 finish_dynamic_symbols */
1374 if (bfd_link_pic (info
) && h
== NULL
)
1377 microblaze_elf_output_dynamic_relocation
1380 htab
->elf
.srelgot
->reloc_count
++,
1381 /* symindex= */ indx
, R_MICROBLAZE_REL
,
1382 got_offset
, static_value
);
1387 /* 4. Fixup Relocation with GOT offset value
1388 Compute relative address of GOT entry for applying
1389 the current relocation */
1390 relocation
= htab
->elf
.sgot
->output_section
->vma
1391 + htab
->elf
.sgot
->output_offset
1393 - htab
->elf
.sgotplt
->output_section
->vma
1394 - htab
->elf
.sgotplt
->output_offset
;
1396 /* Apply Current Relocation */
1397 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1398 contents
+ offset
+ endian
);
1399 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1400 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1402 unresolved_reloc
= FALSE
;
1406 case (int) R_MICROBLAZE_GOTOFF_64
:
1409 unsigned short lo
, high
;
1410 relocation
+= addend
;
1411 relocation
-= (htab
->elf
.sgotplt
->output_section
->vma
1412 + htab
->elf
.sgotplt
->output_offset
);
1413 /* Write this value into correct location. */
1414 immediate
= relocation
;
1415 lo
= immediate
& 0x0000ffff;
1416 high
= (immediate
>> 16) & 0x0000ffff;
1417 bfd_put_16 (input_bfd
, high
, contents
+ offset
+ endian
);
1418 bfd_put_16 (input_bfd
, lo
,
1419 contents
+ offset
+ INST_WORD_SIZE
+ endian
);
1423 case (int) R_MICROBLAZE_GOTOFF_32
:
1425 relocation
+= addend
;
1426 relocation
-= (htab
->elf
.sgotplt
->output_section
->vma
1427 + htab
->elf
.sgotplt
->output_offset
);
1428 /* Write this value into correct location. */
1429 bfd_put_32 (input_bfd
, relocation
, contents
+ offset
);
1433 case (int) R_MICROBLAZE_TLSDTPREL64
:
1434 relocation
+= addend
;
1435 relocation
-= dtprel_base(info
);
1436 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1437 contents
+ offset
+ 2);
1438 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1439 contents
+ offset
+ 2 + INST_WORD_SIZE
);
1441 case (int) R_MICROBLAZE_TEXTREL_64
:
1442 case (int) R_MICROBLAZE_TEXTREL_32_LO
:
1443 case (int) R_MICROBLAZE_64_PCREL
:
1444 case (int) R_MICROBLAZE_64
:
1445 case (int) R_MICROBLAZE_32
:
1447 /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
1448 from removed linkonce sections, or sections discarded by
1450 if (r_symndx
== STN_UNDEF
|| (input_section
->flags
& SEC_ALLOC
) == 0)
1452 relocation
+= addend
;
1453 if (r_type
== R_MICROBLAZE_32
)
1454 bfd_put_32 (input_bfd
, relocation
, contents
+ offset
);
1457 if (r_type
== R_MICROBLAZE_64_PCREL
)
1458 relocation
-= (input_section
->output_section
->vma
1459 + input_section
->output_offset
1460 + offset
+ INST_WORD_SIZE
);
1461 else if (r_type
== R_MICROBLAZE_TEXTREL_64
1462 || r_type
== R_MICROBLAZE_TEXTREL_32_LO
)
1463 relocation
-= input_section
->output_section
->vma
;
1465 if (r_type
== R_MICROBLAZE_TEXTREL_32_LO
)
1466 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1467 contents
+ offset
+ endian
);
1471 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1472 contents
+ offset
+ endian
);
1473 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1474 contents
+ offset
+ endian
+ INST_WORD_SIZE
);
1480 if ((bfd_link_pic (info
)
1482 || (ELF_ST_VISIBILITY (h
->other
) == STV_DEFAULT
1483 && !resolved_to_zero
)
1484 || h
->root
.type
!= bfd_link_hash_undefweak
)
1485 && (!howto
->pc_relative
1489 || !h
->def_regular
))))
1490 || (!bfd_link_pic (info
)
1496 || h
->root
.type
== bfd_link_hash_undefweak
1497 || h
->root
.type
== bfd_link_hash_undefined
)))
1499 Elf_Internal_Rela outrel
;
1503 /* When generating a shared object, these relocations
1504 are copied into the output file to be resolved at run
1507 BFD_ASSERT (sreloc
!= NULL
);
1512 _bfd_elf_section_offset (output_bfd
, info
, input_section
,
1514 if (outrel
.r_offset
== (bfd_vma
) -1)
1516 else if (outrel
.r_offset
== (bfd_vma
) -2)
1518 outrel
.r_offset
+= (input_section
->output_section
->vma
1519 + input_section
->output_offset
);
1522 memset (&outrel
, 0, sizeof outrel
);
1523 /* h->dynindx may be -1 if the symbol was marked to
1526 && ((! info
->symbolic
&& h
->dynindx
!= -1)
1527 || !h
->def_regular
))
1529 BFD_ASSERT (h
->dynindx
!= -1);
1530 outrel
.r_info
= ELF32_R_INFO (h
->dynindx
, r_type
);
1531 outrel
.r_addend
= addend
;
1535 if (r_type
== R_MICROBLAZE_32
)
1537 outrel
.r_info
= ELF32_R_INFO (0, R_MICROBLAZE_REL
);
1538 outrel
.r_addend
= relocation
+ addend
;
1544 (_("%pB: probably compiled without -fPIC?"),
1546 bfd_set_error (bfd_error_bad_value
);
1551 loc
= sreloc
->contents
;
1552 loc
+= sreloc
->reloc_count
++ * sizeof (Elf32_External_Rela
);
1553 bfd_elf32_swap_reloca_out (output_bfd
, &outrel
, loc
);
1558 relocation
+= addend
;
1559 if (r_type
== R_MICROBLAZE_32
)
1560 bfd_put_32 (input_bfd
, relocation
, contents
+ offset
);
1563 if (r_type
== R_MICROBLAZE_64_PCREL
)
1564 relocation
-= (input_section
->output_section
->vma
1565 + input_section
->output_offset
1566 + offset
+ INST_WORD_SIZE
);
1567 else if (r_type
== R_MICROBLAZE_TEXTREL_64
1568 || r_type
== R_MICROBLAZE_TEXTREL_32_LO
)
1569 relocation
-= input_section
->output_section
->vma
;
1571 if (r_type
== R_MICROBLAZE_TEXTREL_32_LO
)
1573 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1574 contents
+ offset
+ endian
);
1578 bfd_put_16 (input_bfd
, (relocation
>> 16) & 0xffff,
1579 contents
+ offset
+ endian
);
1580 bfd_put_16 (input_bfd
, relocation
& 0xffff,
1581 contents
+ offset
+ endian
1590 r
= _bfd_final_link_relocate (howto
, input_bfd
, input_section
,
1592 relocation
, addend
);
1599 if (r
!= bfd_reloc_ok
)
1601 /* FIXME: This should be generic enough to go in a utility. */
1605 name
= h
->root
.root
.string
;
1608 name
= (bfd_elf_string_from_elf_section
1609 (input_bfd
, symtab_hdr
->sh_link
, sym
->st_name
));
1610 if (name
== NULL
|| *name
== '\0')
1611 name
= bfd_section_name (sec
);
1619 case bfd_reloc_overflow
:
1620 (*info
->callbacks
->reloc_overflow
)
1621 (info
, (h
? &h
->root
: NULL
), name
, howto
->name
,
1622 (bfd_vma
) 0, input_bfd
, input_section
, offset
);
1625 case bfd_reloc_undefined
:
1626 (*info
->callbacks
->undefined_symbol
)
1627 (info
, name
, input_bfd
, input_section
, offset
, TRUE
);
1630 case bfd_reloc_outofrange
:
1631 errmsg
= _("internal error: out of range error");
1634 case bfd_reloc_notsupported
:
1635 errmsg
= _("internal error: unsupported relocation error");
1638 case bfd_reloc_dangerous
:
1639 errmsg
= _("internal error: dangerous error");
1643 errmsg
= _("internal error: unknown error");
1646 (*info
->callbacks
->warning
) (info
, errmsg
, name
, input_bfd
,
1647 input_section
, offset
);
1656 /* Calculate fixup value for reference. */
1659 calc_fixup (bfd_vma start
, bfd_vma size
, asection
*sec
)
1661 bfd_vma end
= start
+ size
;
1664 if (sec
== NULL
|| sec
->relax
== NULL
)
1667 /* Look for addr in relax table, total fixup value. */
1668 for (i
= 0; i
< sec
->relax_count
; i
++)
1670 if (end
<= sec
->relax
[i
].addr
)
1672 if ((end
!= start
) && (start
> sec
->relax
[i
].addr
))
1674 fixup
+= sec
->relax
[i
].size
;
1679 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1680 a 32-bit instruction. */
1682 microblaze_bfd_write_imm_value_32 (bfd
*abfd
, bfd_byte
*bfd_addr
, bfd_vma val
)
1684 unsigned long instr
= bfd_get_32 (abfd
, bfd_addr
);
1685 instr
&= ~0x0000ffff;
1686 instr
|= (val
& 0x0000ffff);
1687 bfd_put_32 (abfd
, instr
, bfd_addr
);
1690 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1691 two consecutive 32-bit instructions. */
1693 microblaze_bfd_write_imm_value_64 (bfd
*abfd
, bfd_byte
*bfd_addr
, bfd_vma val
)
1695 unsigned long instr_hi
;
1696 unsigned long instr_lo
;
1698 instr_hi
= bfd_get_32 (abfd
, bfd_addr
);
1699 instr_hi
&= ~0x0000ffff;
1700 instr_hi
|= ((val
>> 16) & 0x0000ffff);
1701 bfd_put_32 (abfd
, instr_hi
, bfd_addr
);
1703 instr_lo
= bfd_get_32 (abfd
, bfd_addr
+ INST_WORD_SIZE
);
1704 instr_lo
&= ~0x0000ffff;
1705 instr_lo
|= (val
& 0x0000ffff);
1706 bfd_put_32 (abfd
, instr_lo
, bfd_addr
+ INST_WORD_SIZE
);
1710 microblaze_elf_relax_section (bfd
*abfd
,
1712 struct bfd_link_info
*link_info
,
1715 Elf_Internal_Shdr
*symtab_hdr
;
1716 Elf_Internal_Rela
*internal_relocs
;
1717 Elf_Internal_Rela
*free_relocs
= NULL
;
1718 Elf_Internal_Rela
*irel
, *irelend
;
1719 bfd_byte
*contents
= NULL
;
1720 bfd_byte
*free_contents
= NULL
;
1725 struct elf_link_hash_entry
*sym_hash
;
1726 Elf_Internal_Sym
*isymbuf
, *isymend
;
1727 Elf_Internal_Sym
*isym
;
1732 /* We only do this once per section. We may be able to delete some code
1733 by running multiple passes, but it is not worth it. */
1736 /* Only do this for a text section. */
1737 if (bfd_link_relocatable (link_info
)
1738 || (sec
->flags
& SEC_RELOC
) == 0
1739 || (sec
->reloc_count
== 0)
1740 || (sec
->flags
& SEC_CODE
) == 0)
1743 BFD_ASSERT ((sec
->size
> 0) || (sec
->rawsize
> 0));
1745 /* If this is the first time we have been called for this section,
1746 initialize the cooked size. */
1748 sec
->size
= sec
->rawsize
;
1750 /* Get symbols for this section. */
1751 symtab_hdr
= &elf_tdata (abfd
)->symtab_hdr
;
1752 isymbuf
= (Elf_Internal_Sym
*) symtab_hdr
->contents
;
1753 symcount
= symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
);
1754 if (isymbuf
== NULL
)
1755 isymbuf
= bfd_elf_get_elf_syms (abfd
, symtab_hdr
, symcount
,
1756 0, NULL
, NULL
, NULL
);
1757 BFD_ASSERT (isymbuf
!= NULL
);
1759 internal_relocs
= _bfd_elf_link_read_relocs (abfd
, sec
, NULL
, NULL
, link_info
->keep_memory
);
1760 if (internal_relocs
== NULL
)
1762 if (! link_info
->keep_memory
)
1763 free_relocs
= internal_relocs
;
1765 sec
->relax
= (struct relax_table
*) bfd_malloc ((sec
->reloc_count
+ 1)
1766 * sizeof (struct relax_table
));
1767 if (sec
->relax
== NULL
)
1769 sec
->relax_count
= 0;
1771 irelend
= internal_relocs
+ sec
->reloc_count
;
1773 for (irel
= internal_relocs
; irel
< irelend
; irel
++, rel_count
++)
1776 if ((ELF32_R_TYPE (irel
->r_info
) != (int) R_MICROBLAZE_64_PCREL
)
1777 && (ELF32_R_TYPE (irel
->r_info
) != (int) R_MICROBLAZE_64
)
1778 && (ELF32_R_TYPE (irel
->r_info
) != (int) R_MICROBLAZE_TEXTREL_64
))
1779 continue; /* Can't delete this reloc. */
1781 /* Get the section contents. */
1782 if (contents
== NULL
)
1784 if (elf_section_data (sec
)->this_hdr
.contents
!= NULL
)
1785 contents
= elf_section_data (sec
)->this_hdr
.contents
;
1788 contents
= (bfd_byte
*) bfd_malloc (sec
->size
);
1789 if (contents
== NULL
)
1791 free_contents
= contents
;
1793 if (!bfd_get_section_contents (abfd
, sec
, contents
,
1794 (file_ptr
) 0, sec
->size
))
1796 elf_section_data (sec
)->this_hdr
.contents
= contents
;
1800 /* Get the value of the symbol referred to by the reloc. */
1801 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
1803 /* A local symbol. */
1806 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
1807 if (isym
->st_shndx
== SHN_UNDEF
)
1808 sym_sec
= bfd_und_section_ptr
;
1809 else if (isym
->st_shndx
== SHN_ABS
)
1810 sym_sec
= bfd_abs_section_ptr
;
1811 else if (isym
->st_shndx
== SHN_COMMON
)
1812 sym_sec
= bfd_com_section_ptr
;
1814 sym_sec
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
1816 symval
= _bfd_elf_rela_local_sym (abfd
, isym
, &sym_sec
, irel
);
1821 struct elf_link_hash_entry
*h
;
1823 indx
= ELF32_R_SYM (irel
->r_info
) - symtab_hdr
->sh_info
;
1824 h
= elf_sym_hashes (abfd
)[indx
];
1825 BFD_ASSERT (h
!= NULL
);
1827 if (h
->root
.type
!= bfd_link_hash_defined
1828 && h
->root
.type
!= bfd_link_hash_defweak
)
1829 /* This appears to be a reference to an undefined
1830 symbol. Just ignore it--it will be caught by the
1831 regular reloc processing. */
1834 symval
= (h
->root
.u
.def
.value
1835 + h
->root
.u
.def
.section
->output_section
->vma
1836 + h
->root
.u
.def
.section
->output_offset
);
1839 /* If this is a PC-relative reloc, subtract the instr offset from
1840 the symbol value. */
1841 if (ELF32_R_TYPE (irel
->r_info
) == (int) R_MICROBLAZE_64_PCREL
)
1843 symval
= symval
+ irel
->r_addend
1845 + sec
->output_section
->vma
1846 + sec
->output_offset
);
1848 else if (ELF32_R_TYPE (irel
->r_info
) == (int) R_MICROBLAZE_TEXTREL_64
)
1850 symval
= symval
+ irel
->r_addend
- (sec
->output_section
->vma
);
1853 symval
+= irel
->r_addend
;
1855 if ((symval
& 0xffff8000) == 0
1856 || (symval
& 0xffff8000) == 0xffff8000)
1858 /* We can delete this instruction. */
1859 sec
->relax
[sec
->relax_count
].addr
= irel
->r_offset
;
1860 sec
->relax
[sec
->relax_count
].size
= INST_WORD_SIZE
;
1863 /* Rewrite relocation type. */
1864 switch ((enum elf_microblaze_reloc_type
) ELF32_R_TYPE (irel
->r_info
))
1866 case R_MICROBLAZE_64_PCREL
:
1867 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1868 (int) R_MICROBLAZE_32_PCREL_LO
);
1870 case R_MICROBLAZE_64
:
1871 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1872 (int) R_MICROBLAZE_32_LO
);
1874 case R_MICROBLAZE_TEXTREL_64
:
1875 irel
->r_info
= ELF32_R_INFO (ELF32_R_SYM (irel
->r_info
),
1876 (int) R_MICROBLAZE_TEXTREL_32_LO
);
1879 /* Cannot happen. */
1883 } /* Loop through all relocations. */
1885 /* Loop through the relocs again, and see if anything needs to change. */
1886 if (sec
->relax_count
> 0)
1888 shndx
= _bfd_elf_section_from_bfd_section (abfd
, sec
);
1890 sec
->relax
[sec
->relax_count
].addr
= sec
->size
;
1892 for (irel
= internal_relocs
; irel
< irelend
; irel
++, rel_count
++)
1896 /* Get the new reloc address. */
1897 nraddr
= irel
->r_offset
- calc_fixup (irel
->r_offset
, 0, sec
);
1898 switch ((enum elf_microblaze_reloc_type
) ELF32_R_TYPE (irel
->r_info
))
1902 case R_MICROBLAZE_64_PCREL
:
1904 case R_MICROBLAZE_TEXTREL_64
:
1905 case R_MICROBLAZE_TEXTREL_32_LO
:
1906 case R_MICROBLAZE_64
:
1907 case R_MICROBLAZE_32_LO
:
1908 /* If this reloc is against a symbol defined in this
1909 section, we must check the addend to see it will put the value in
1910 range to be adjusted, and hence must be changed. */
1911 if (ELF32_R_SYM (irel
->r_info
) < symtab_hdr
->sh_info
)
1913 isym
= isymbuf
+ ELF32_R_SYM (irel
->r_info
);
1914 /* Only handle relocs against .text. */
1915 if (isym
->st_shndx
== shndx
1916 && ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
)
1917 irel
->r_addend
-= calc_fixup (irel
->r_addend
, 0, sec
);
1920 case R_MICROBLAZE_NONE
:
1922 /* This was a PC-relative instruction that was
1923 completely resolved. */
1925 bfd_vma target_address
;
1926 target_address
= irel
->r_addend
+ irel
->r_offset
;
1927 sfix
= calc_fixup (irel
->r_offset
, 0, sec
);
1928 efix
= calc_fixup (target_address
, 0, sec
);
1929 irel
->r_addend
-= (efix
- sfix
);
1930 /* Should use HOWTO. */
1931 microblaze_bfd_write_imm_value_32 (abfd
, contents
+ irel
->r_offset
,
1935 case R_MICROBLAZE_64_NONE
:
1937 /* This was a PC-relative 64-bit instruction that was
1938 completely resolved. */
1940 bfd_vma target_address
;
1941 target_address
= irel
->r_addend
+ irel
->r_offset
+ INST_WORD_SIZE
;
1942 sfix
= calc_fixup (irel
->r_offset
+ INST_WORD_SIZE
, 0, sec
);
1943 efix
= calc_fixup (target_address
, 0, sec
);
1944 irel
->r_addend
-= (efix
- sfix
);
1945 microblaze_bfd_write_imm_value_32 (abfd
, contents
+ irel
->r_offset
1946 + INST_WORD_SIZE
, irel
->r_addend
);
1950 irel
->r_offset
= nraddr
;
1951 } /* Change all relocs in this section. */
1953 /* Look through all other sections. */
1954 for (o
= abfd
->sections
; o
!= NULL
; o
= o
->next
)
1956 Elf_Internal_Rela
*irelocs
;
1957 Elf_Internal_Rela
*irelscan
, *irelscanend
;
1958 bfd_byte
*ocontents
;
1961 || (o
->flags
& SEC_RELOC
) == 0
1962 || o
->reloc_count
== 0)
1965 /* We always cache the relocs. Perhaps, if info->keep_memory is
1966 FALSE, we should free them, if we are permitted to. */
1968 irelocs
= _bfd_elf_link_read_relocs (abfd
, o
, NULL
, NULL
, TRUE
);
1969 if (irelocs
== NULL
)
1973 irelscanend
= irelocs
+ o
->reloc_count
;
1974 for (irelscan
= irelocs
; irelscan
< irelscanend
; irelscan
++)
1976 if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32
)
1978 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
1980 /* Look at the reloc only if the value has been resolved. */
1981 if (isym
->st_shndx
== shndx
1982 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
1984 if (ocontents
== NULL
)
1986 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
1987 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
1990 /* We always cache the section contents.
1991 Perhaps, if info->keep_memory is FALSE, we
1992 should free them, if we are permitted to. */
1993 if (o
->rawsize
== 0)
1994 o
->rawsize
= o
->size
;
1995 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
1996 if (ocontents
== NULL
)
1998 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2002 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2006 irelscan
->r_addend
-= calc_fixup (irelscan
->r_addend
, 0, sec
);
2008 else if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32_SYM_OP_SYM
)
2010 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2012 /* Look at the reloc only if the value has been resolved. */
2013 if (ocontents
== NULL
)
2015 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2016 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2019 /* We always cache the section contents.
2020 Perhaps, if info->keep_memory is FALSE, we
2021 should free them, if we are permitted to. */
2023 if (o
->rawsize
== 0)
2024 o
->rawsize
= o
->size
;
2025 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2026 if (ocontents
== NULL
)
2028 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2032 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2035 irelscan
->r_addend
-= calc_fixup (irel
->r_addend
2041 else if ((ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_32_PCREL_LO
)
2042 || (ELF32_R_TYPE (irelscan
->r_info
)
2043 == (int) R_MICROBLAZE_32_LO
)
2044 || (ELF32_R_TYPE (irelscan
->r_info
)
2045 == (int) R_MICROBLAZE_TEXTREL_32_LO
))
2047 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2049 /* Look at the reloc only if the value has been resolved. */
2050 if (isym
->st_shndx
== shndx
2051 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2054 bfd_vma target_address
;
2056 if (ocontents
== NULL
)
2058 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2059 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2062 /* We always cache the section contents.
2063 Perhaps, if info->keep_memory is FALSE, we
2064 should free them, if we are permitted to. */
2065 if (o
->rawsize
== 0)
2066 o
->rawsize
= o
->size
;
2067 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2068 if (ocontents
== NULL
)
2070 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2074 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2078 unsigned long instr
= bfd_get_32 (abfd
, ocontents
+ irelscan
->r_offset
);
2079 immediate
= instr
& 0x0000ffff;
2080 target_address
= immediate
;
2081 offset
= calc_fixup (target_address
, 0, sec
);
2082 immediate
-= offset
;
2083 irelscan
->r_addend
-= offset
;
2084 microblaze_bfd_write_imm_value_32 (abfd
, ocontents
+ irelscan
->r_offset
,
2085 irelscan
->r_addend
);
2089 if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_64
2090 || (ELF32_R_TYPE (irelscan
->r_info
)
2091 == (int) R_MICROBLAZE_TEXTREL_64
))
2093 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2095 /* Look at the reloc only if the value has been resolved. */
2096 if (isym
->st_shndx
== shndx
2097 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2101 if (ocontents
== NULL
)
2103 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2104 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2107 /* We always cache the section contents.
2108 Perhaps, if info->keep_memory is FALSE, we
2109 should free them, if we are permitted to. */
2111 if (o
->rawsize
== 0)
2112 o
->rawsize
= o
->size
;
2113 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2114 if (ocontents
== NULL
)
2116 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2120 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2123 unsigned long instr_hi
= bfd_get_32 (abfd
, ocontents
2124 + irelscan
->r_offset
);
2125 unsigned long instr_lo
= bfd_get_32 (abfd
, ocontents
2126 + irelscan
->r_offset
2128 immediate
= (instr_hi
& 0x0000ffff) << 16;
2129 immediate
|= (instr_lo
& 0x0000ffff);
2130 offset
= calc_fixup (irelscan
->r_addend
, 0, sec
);
2131 immediate
-= offset
;
2132 irelscan
->r_addend
-= offset
;
2135 else if (ELF32_R_TYPE (irelscan
->r_info
) == (int) R_MICROBLAZE_64_PCREL
)
2137 isym
= isymbuf
+ ELF32_R_SYM (irelscan
->r_info
);
2139 /* Look at the reloc only if the value has been resolved. */
2140 if (isym
->st_shndx
== shndx
2141 && (ELF32_ST_TYPE (isym
->st_info
) == STT_SECTION
))
2144 bfd_vma target_address
;
2146 if (ocontents
== NULL
)
2148 if (elf_section_data (o
)->this_hdr
.contents
!= NULL
)
2149 ocontents
= elf_section_data (o
)->this_hdr
.contents
;
2152 /* We always cache the section contents.
2153 Perhaps, if info->keep_memory is FALSE, we
2154 should free them, if we are permitted to. */
2155 if (o
->rawsize
== 0)
2156 o
->rawsize
= o
->size
;
2157 ocontents
= (bfd_byte
*) bfd_malloc (o
->rawsize
);
2158 if (ocontents
== NULL
)
2160 if (!bfd_get_section_contents (abfd
, o
, ocontents
,
2164 elf_section_data (o
)->this_hdr
.contents
= ocontents
;
2167 unsigned long instr_hi
= bfd_get_32 (abfd
, ocontents
2168 + irelscan
->r_offset
);
2169 unsigned long instr_lo
= bfd_get_32 (abfd
, ocontents
2170 + irelscan
->r_offset
2172 immediate
= (instr_hi
& 0x0000ffff) << 16;
2173 immediate
|= (instr_lo
& 0x0000ffff);
2174 target_address
= immediate
;
2175 offset
= calc_fixup (target_address
, 0, sec
);
2176 immediate
-= offset
;
2177 irelscan
->r_addend
-= offset
;
2178 microblaze_bfd_write_imm_value_64 (abfd
, ocontents
2179 + irelscan
->r_offset
, immediate
);
2185 /* Adjust the local symbols defined in this section. */
2186 isymend
= isymbuf
+ symtab_hdr
->sh_info
;
2187 for (isym
= isymbuf
; isym
< isymend
; isym
++)
2189 if (isym
->st_shndx
== shndx
)
2191 isym
->st_value
-= calc_fixup (isym
->st_value
, 0, sec
);
2193 isym
->st_size
-= calc_fixup (isym
->st_value
, isym
->st_size
, sec
);
2197 /* Now adjust the global symbols defined in this section. */
2198 isym
= isymbuf
+ symtab_hdr
->sh_info
;
2199 symcount
= (symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
)) - symtab_hdr
->sh_info
;
2200 for (sym_index
= 0; sym_index
< symcount
; sym_index
++)
2202 sym_hash
= elf_sym_hashes (abfd
)[sym_index
];
2203 if ((sym_hash
->root
.type
== bfd_link_hash_defined
2204 || sym_hash
->root
.type
== bfd_link_hash_defweak
)
2205 && sym_hash
->root
.u
.def
.section
== sec
)
2207 sym_hash
->root
.u
.def
.value
-= calc_fixup (sym_hash
->root
.u
.def
.value
,
2210 sym_hash
->size
-= calc_fixup (sym_hash
->root
.u
.def
.value
,
2211 sym_hash
->size
, sec
);
2215 /* Physically move the code and change the cooked size. */
2216 dest
= sec
->relax
[0].addr
;
2217 for (i
= 0; i
< sec
->relax_count
; i
++)
2220 src
= sec
->relax
[i
].addr
+ sec
->relax
[i
].size
;
2221 len
= sec
->relax
[i
+1].addr
- sec
->relax
[i
].addr
- sec
->relax
[i
].size
;
2223 memmove (contents
+ dest
, contents
+ src
, len
);
2224 sec
->size
-= sec
->relax
[i
].size
;
2228 elf_section_data (sec
)->relocs
= internal_relocs
;
2231 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2232 free_contents
= NULL
;
2234 symtab_hdr
->contents
= (bfd_byte
*) isymbuf
;
2240 if (free_contents
!= NULL
)
2242 if (!link_info
->keep_memory
)
2243 free (free_contents
);
2245 /* Cache the section contents for elf_link_input_bfd. */
2246 elf_section_data (sec
)->this_hdr
.contents
= contents
;
2247 free_contents
= NULL
;
2250 if (sec
->relax_count
== 0)
2262 free (free_contents
);
2265 sec
->relax_count
= 0;
2269 /* Return the section that should be marked against GC for a given
2273 microblaze_elf_gc_mark_hook (asection
*sec
,
2274 struct bfd_link_info
* info
,
2275 Elf_Internal_Rela
* rel
,
2276 struct elf_link_hash_entry
* h
,
2277 Elf_Internal_Sym
* sym
)
2280 switch (ELF32_R_TYPE (rel
->r_info
))
2282 case R_MICROBLAZE_GNU_VTINHERIT
:
2283 case R_MICROBLAZE_GNU_VTENTRY
:
2287 return _bfd_elf_gc_mark_hook (sec
, info
, rel
, h
, sym
);
2292 #define PLT_ENTRY_SIZE 16
2294 #define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
2295 #define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
2296 #define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
2297 #define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
2298 #define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
2301 update_local_sym_info (bfd
*abfd
,
2302 Elf_Internal_Shdr
*symtab_hdr
,
2303 unsigned long r_symndx
,
2304 unsigned int tls_type
)
2306 bfd_signed_vma
*local_got_refcounts
= elf_local_got_refcounts (abfd
);
2307 unsigned char *local_got_tls_masks
;
2309 if (local_got_refcounts
== NULL
)
2311 bfd_size_type size
= symtab_hdr
->sh_info
;
2313 size
*= (sizeof (*local_got_refcounts
) + sizeof (*local_got_tls_masks
));
2314 local_got_refcounts
= bfd_zalloc (abfd
, size
);
2315 if (local_got_refcounts
== NULL
)
2317 elf_local_got_refcounts (abfd
) = local_got_refcounts
;
2320 local_got_tls_masks
=
2321 (unsigned char *) (local_got_refcounts
+ symtab_hdr
->sh_info
);
2322 local_got_tls_masks
[r_symndx
] |= tls_type
;
2323 local_got_refcounts
[r_symndx
] += 1;
2327 /* Look through the relocs for a section during the first phase. */
2330 microblaze_elf_check_relocs (bfd
* abfd
,
2331 struct bfd_link_info
* info
,
2333 const Elf_Internal_Rela
* relocs
)
2335 Elf_Internal_Shdr
* symtab_hdr
;
2336 struct elf_link_hash_entry
** sym_hashes
;
2337 struct elf_link_hash_entry
** sym_hashes_end
;
2338 const Elf_Internal_Rela
* rel
;
2339 const Elf_Internal_Rela
* rel_end
;
2340 struct elf32_mb_link_hash_table
*htab
;
2341 asection
*sreloc
= NULL
;
2343 if (bfd_link_relocatable (info
))
2346 htab
= elf32_mb_hash_table (info
);
2350 symtab_hdr
= & elf_tdata (abfd
)->symtab_hdr
;
2351 sym_hashes
= elf_sym_hashes (abfd
);
2352 sym_hashes_end
= sym_hashes
+ symtab_hdr
->sh_size
/ sizeof (Elf32_External_Sym
);
2353 if (!elf_bad_symtab (abfd
))
2354 sym_hashes_end
-= symtab_hdr
->sh_info
;
2356 rel_end
= relocs
+ sec
->reloc_count
;
2358 for (rel
= relocs
; rel
< rel_end
; rel
++)
2360 unsigned int r_type
;
2361 struct elf_link_hash_entry
* h
;
2362 unsigned long r_symndx
;
2363 unsigned char tls_type
= 0;
2365 r_symndx
= ELF32_R_SYM (rel
->r_info
);
2366 r_type
= ELF32_R_TYPE (rel
->r_info
);
2368 if (r_symndx
< symtab_hdr
->sh_info
)
2372 h
= sym_hashes
[r_symndx
- symtab_hdr
->sh_info
];
2373 while (h
->root
.type
== bfd_link_hash_indirect
2374 || h
->root
.type
== bfd_link_hash_warning
)
2375 h
= (struct elf_link_hash_entry
*) h
->root
.u
.i
.link
;
2380 /* This relocation describes the C++ object vtable hierarchy.
2381 Reconstruct it for later use during GC. */
2382 case R_MICROBLAZE_GNU_VTINHERIT
:
2383 if (!bfd_elf_gc_record_vtinherit (abfd
, sec
, h
, rel
->r_offset
))
2387 /* This relocation describes which C++ vtable entries are actually
2388 used. Record for later use during GC. */
2389 case R_MICROBLAZE_GNU_VTENTRY
:
2390 if (!bfd_elf_gc_record_vtentry (abfd
, sec
, h
, rel
->r_addend
))
2394 /* This relocation requires .plt entry. */
2395 case R_MICROBLAZE_PLT_64
:
2399 h
->plt
.refcount
+= 1;
2403 /* This relocation requires .got entry. */
2404 case R_MICROBLAZE_TLSGD
:
2405 tls_type
|= (TLS_TLS
| TLS_GD
);
2407 case R_MICROBLAZE_TLSLD
:
2408 tls_type
|= (TLS_TLS
| TLS_LD
);
2411 sec
->has_tls_reloc
= 1;
2413 case R_MICROBLAZE_GOT_64
:
2414 if (htab
->elf
.sgot
== NULL
)
2416 if (htab
->elf
.dynobj
== NULL
)
2417 htab
->elf
.dynobj
= abfd
;
2418 if (!_bfd_elf_create_got_section (htab
->elf
.dynobj
, info
))
2423 h
->got
.refcount
+= 1;
2424 elf32_mb_hash_entry (h
)->tls_mask
|= tls_type
;
2428 if (! update_local_sym_info(abfd
, symtab_hdr
, r_symndx
, tls_type
) )
2433 case R_MICROBLAZE_GOTOFF_64
:
2434 case R_MICROBLAZE_GOTOFF_32
:
2435 if (htab
->elf
.sgot
== NULL
)
2437 if (htab
->elf
.dynobj
== NULL
)
2438 htab
->elf
.dynobj
= abfd
;
2439 if (!_bfd_elf_create_got_section (htab
->elf
.dynobj
, info
))
2444 case R_MICROBLAZE_64
:
2445 case R_MICROBLAZE_64_PCREL
:
2446 case R_MICROBLAZE_32
:
2448 if (h
!= NULL
&& !bfd_link_pic (info
))
2450 /* we may need a copy reloc. */
2453 /* we may also need a .plt entry. */
2454 h
->plt
.refcount
+= 1;
2455 if (ELF32_R_TYPE (rel
->r_info
) != R_MICROBLAZE_64_PCREL
)
2456 h
->pointer_equality_needed
= 1;
2460 /* If we are creating a shared library, and this is a reloc
2461 against a global symbol, or a non PC relative reloc
2462 against a local symbol, then we need to copy the reloc
2463 into the shared library. However, if we are linking with
2464 -Bsymbolic, we do not need to copy a reloc against a
2465 global symbol which is defined in an object we are
2466 including in the link (i.e., DEF_REGULAR is set). At
2467 this point we have not seen all the input files, so it is
2468 possible that DEF_REGULAR is not set now but will be set
2469 later (it is never cleared). In case of a weak definition,
2470 DEF_REGULAR may be cleared later by a strong definition in
2471 a shared library. We account for that possibility below by
2472 storing information in the relocs_copied field of the hash
2473 table entry. A similar situation occurs when creating
2474 shared libraries and symbol visibility changes render the
2477 If on the other hand, we are creating an executable, we
2478 may need to keep relocations for symbols satisfied by a
2479 dynamic library if we manage to avoid copy relocs for the
2482 if ((bfd_link_pic (info
)
2483 && (sec
->flags
& SEC_ALLOC
) != 0
2484 && (r_type
!= R_MICROBLAZE_64_PCREL
2486 && (! info
->symbolic
2487 || h
->root
.type
== bfd_link_hash_defweak
2488 || !h
->def_regular
))))
2489 || (!bfd_link_pic (info
)
2490 && (sec
->flags
& SEC_ALLOC
) != 0
2492 && (h
->root
.type
== bfd_link_hash_defweak
2493 || !h
->def_regular
)))
2495 struct elf_dyn_relocs
*p
;
2496 struct elf_dyn_relocs
**head
;
2498 /* When creating a shared object, we must copy these
2499 relocs into the output file. We create a reloc
2500 section in dynobj and make room for the reloc. */
2506 if (htab
->elf
.dynobj
== NULL
)
2507 htab
->elf
.dynobj
= abfd
;
2508 dynobj
= htab
->elf
.dynobj
;
2510 sreloc
= _bfd_elf_make_dynamic_reloc_section (sec
, dynobj
,
2516 /* If this is a global symbol, we count the number of
2517 relocations we need for this symbol. */
2519 head
= &((struct elf32_mb_link_hash_entry
*) h
)->dyn_relocs
;
2522 /* Track dynamic relocs needed for local syms too.
2523 We really need local syms available to do this
2527 Elf_Internal_Sym
*isym
;
2530 isym
= bfd_sym_from_r_symndx (&htab
->sym_sec
,
2535 s
= bfd_section_from_elf_index (abfd
, isym
->st_shndx
);
2539 vpp
= &elf_section_data (s
)->local_dynrel
;
2540 head
= (struct elf_dyn_relocs
**) vpp
;
2544 if (p
== NULL
|| p
->sec
!= sec
)
2546 size_t amt
= sizeof *p
;
2547 p
= ((struct elf_dyn_relocs
*)
2548 bfd_alloc (htab
->elf
.dynobj
, amt
));
2559 if (r_type
== R_MICROBLAZE_64_PCREL
)
2570 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2573 microblaze_elf_copy_indirect_symbol (struct bfd_link_info
*info
,
2574 struct elf_link_hash_entry
*dir
,
2575 struct elf_link_hash_entry
*ind
)
2577 struct elf32_mb_link_hash_entry
*edir
, *eind
;
2579 edir
= (struct elf32_mb_link_hash_entry
*) dir
;
2580 eind
= (struct elf32_mb_link_hash_entry
*) ind
;
2582 if (eind
->dyn_relocs
!= NULL
)
2584 if (edir
->dyn_relocs
!= NULL
)
2586 struct elf_dyn_relocs
**pp
;
2587 struct elf_dyn_relocs
*p
;
2589 if (ind
->root
.type
== bfd_link_hash_indirect
)
2592 /* Add reloc counts against the weak sym to the strong sym
2593 list. Merge any entries against the same section. */
2594 for (pp
= &eind
->dyn_relocs
; (p
= *pp
) != NULL
; )
2596 struct elf_dyn_relocs
*q
;
2598 for (q
= edir
->dyn_relocs
; q
!= NULL
; q
= q
->next
)
2599 if (q
->sec
== p
->sec
)
2601 q
->pc_count
+= p
->pc_count
;
2602 q
->count
+= p
->count
;
2609 *pp
= edir
->dyn_relocs
;
2612 edir
->dyn_relocs
= eind
->dyn_relocs
;
2613 eind
->dyn_relocs
= NULL
;
2616 edir
->tls_mask
|= eind
->tls_mask
;
2618 _bfd_elf_link_hash_copy_indirect (info
, dir
, ind
);
2621 /* Find dynamic relocs for H that apply to read-only sections. */
2624 readonly_dynrelocs (struct elf_link_hash_entry
*h
)
2626 struct elf_dyn_relocs
*p
;
2628 for (p
= elf32_mb_hash_entry (h
)->dyn_relocs
; p
!= NULL
; p
= p
->next
)
2630 asection
*s
= p
->sec
->output_section
;
2632 if (s
!= NULL
&& (s
->flags
& SEC_READONLY
) != 0)
2639 microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info
*info
,
2640 struct elf_link_hash_entry
*h
)
2642 struct elf32_mb_link_hash_table
*htab
;
2644 unsigned int power_of_two
;
2646 htab
= elf32_mb_hash_table (info
);
2650 /* If this is a function, put it in the procedure linkage table. We
2651 will fill in the contents of the procedure linkage table later,
2652 when we know the address of the .got section. */
2653 if (h
->type
== STT_FUNC
2656 if (h
->plt
.refcount
<= 0
2657 || SYMBOL_CALLS_LOCAL (info
, h
)
2658 || (ELF_ST_VISIBILITY (h
->other
) != STV_DEFAULT
2659 && h
->root
.type
== bfd_link_hash_undefweak
))
2661 /* This case can occur if we saw a PLT reloc in an input
2662 file, but the symbol was never referred to by a dynamic
2663 object, or if all references were garbage collected. In
2664 such a case, we don't actually need to build a procedure
2665 linkage table, and we can just do a PC32 reloc instead. */
2666 h
->plt
.offset
= (bfd_vma
) -1;
2673 /* It's possible that we incorrectly decided a .plt reloc was
2674 needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
2675 check_relocs. We can't decide accurately between function and
2676 non-function syms in check-relocs; Objects loaded later in
2677 the link may change h->type. So fix it now. */
2678 h
->plt
.offset
= (bfd_vma
) -1;
2680 /* If this is a weak symbol, and there is a real definition, the
2681 processor independent code will have arranged for us to see the
2682 real definition first, and we can just use the same value. */
2683 if (h
->is_weakalias
)
2685 struct elf_link_hash_entry
*def
= weakdef (h
);
2686 BFD_ASSERT (def
->root
.type
== bfd_link_hash_defined
);
2687 h
->root
.u
.def
.section
= def
->root
.u
.def
.section
;
2688 h
->root
.u
.def
.value
= def
->root
.u
.def
.value
;
2692 /* This is a reference to a symbol defined by a dynamic object which
2693 is not a function. */
2695 /* If we are creating a shared library, we must presume that the
2696 only references to the symbol are via the global offset table.
2697 For such cases we need not do anything here; the relocations will
2698 be handled correctly by relocate_section. */
2699 if (bfd_link_pic (info
))
2702 /* If there are no references to this symbol that do not use the
2703 GOT, we don't need to generate a copy reloc. */
2704 if (!h
->non_got_ref
)
2707 /* If -z nocopyreloc was given, we won't generate them either. */
2708 if (info
->nocopyreloc
)
2714 /* If we don't find any dynamic relocs in read-only sections, then
2715 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
2716 if (!readonly_dynrelocs (h
))
2722 /* We must allocate the symbol in our .dynbss section, which will
2723 become part of the .bss section of the executable. There will be
2724 an entry for this symbol in the .dynsym section. The dynamic
2725 object will contain position independent code, so all references
2726 from the dynamic object to this symbol will go through the global
2727 offset table. The dynamic linker will use the .dynsym entry to
2728 determine the address it must put in the global offset table, so
2729 both the dynamic object and the regular object will refer to the
2730 same memory location for the variable. */
2732 /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
2733 to copy the initial value out of the dynamic object and into the
2734 runtime process image. */
2735 if ((h
->root
.u
.def
.section
->flags
& SEC_READONLY
) != 0)
2737 s
= htab
->elf
.sdynrelro
;
2738 srel
= htab
->elf
.sreldynrelro
;
2742 s
= htab
->elf
.sdynbss
;
2743 srel
= htab
->elf
.srelbss
;
2745 if ((h
->root
.u
.def
.section
->flags
& SEC_ALLOC
) != 0)
2747 srel
->size
+= sizeof (Elf32_External_Rela
);
2751 /* We need to figure out the alignment required for this symbol. I
2752 have no idea how ELF linkers handle this. */
2753 power_of_two
= bfd_log2 (h
->size
);
2754 if (power_of_two
> 3)
2757 /* Apply the required alignment. */
2758 s
->size
= BFD_ALIGN (s
->size
, (bfd_size_type
) (1 << power_of_two
));
2759 if (power_of_two
> s
->alignment_power
)
2761 if (!bfd_set_section_alignment (s
, power_of_two
))
2765 /* Define the symbol as being at this point in the section. */
2766 h
->root
.u
.def
.section
= s
;
2767 h
->root
.u
.def
.value
= s
->size
;
2769 /* Increment the section size to make room for the symbol. */
2774 /* Allocate space in .plt, .got and associated reloc sections for
2778 allocate_dynrelocs (struct elf_link_hash_entry
*h
, void * dat
)
2780 struct bfd_link_info
*info
;
2781 struct elf32_mb_link_hash_table
*htab
;
2782 struct elf32_mb_link_hash_entry
*eh
;
2783 struct elf_dyn_relocs
*p
;
2785 if (h
->root
.type
== bfd_link_hash_indirect
)
2788 info
= (struct bfd_link_info
*) dat
;
2789 htab
= elf32_mb_hash_table (info
);
2793 if (htab
->elf
.dynamic_sections_created
2794 && h
->plt
.refcount
> 0)
2796 /* Make sure this symbol is output as a dynamic symbol.
2797 Undefined weak syms won't yet be marked as dynamic. */
2798 if (h
->dynindx
== -1
2799 && !h
->forced_local
)
2801 if (! bfd_elf_link_record_dynamic_symbol (info
, h
))
2805 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info
), h
))
2807 asection
*s
= htab
->elf
.splt
;
2809 /* The first entry in .plt is reserved. */
2811 s
->size
= PLT_ENTRY_SIZE
;
2813 h
->plt
.offset
= s
->size
;
2815 /* If this symbol is not defined in a regular file, and we are
2816 not generating a shared library, then set the symbol to this
2817 location in the .plt. This is required to make function
2818 pointers compare as equal between the normal executable and
2819 the shared library. */
2820 if (! bfd_link_pic (info
)
2823 h
->root
.u
.def
.section
= s
;
2824 h
->root
.u
.def
.value
= h
->plt
.offset
;
2827 /* Make room for this entry. */
2828 s
->size
+= PLT_ENTRY_SIZE
;
2830 /* We also need to make an entry in the .got.plt section, which
2831 will be placed in the .got section by the linker script. */
2832 htab
->elf
.sgotplt
->size
+= 4;
2834 /* We also need to make an entry in the .rel.plt section. */
2835 htab
->elf
.srelplt
->size
+= sizeof (Elf32_External_Rela
);
2839 h
->plt
.offset
= (bfd_vma
) -1;
2845 h
->plt
.offset
= (bfd_vma
) -1;
2849 eh
= (struct elf32_mb_link_hash_entry
*) h
;
2850 if (h
->got
.refcount
> 0)
2855 /* Make sure this symbol is output as a dynamic symbol.
2856 Undefined weak syms won't yet be marked as dynamic. */
2857 if (h
->dynindx
== -1
2858 && !h
->forced_local
)
2860 if (! bfd_elf_link_record_dynamic_symbol (info
, h
))
2865 if ((eh
->tls_mask
& TLS_TLS
) != 0)
2867 /* Handle TLS Symbol */
2868 if ((eh
->tls_mask
& TLS_LD
) != 0)
2870 if (!eh
->elf
.def_dynamic
)
2871 /* We'll just use htab->tlsld_got.offset. This should
2872 always be the case. It's a little odd if we have
2873 a local dynamic reloc against a non-local symbol. */
2874 htab
->tlsld_got
.refcount
+= 1;
2878 if ((eh
->tls_mask
& TLS_GD
) != 0)
2883 /* Regular (non-TLS) symbol */
2888 h
->got
.offset
= (bfd_vma
) -1;
2893 h
->got
.offset
= s
->size
;
2895 htab
->elf
.srelgot
->size
+= need
* (sizeof (Elf32_External_Rela
) / 4);
2899 h
->got
.offset
= (bfd_vma
) -1;
2901 if (eh
->dyn_relocs
== NULL
)
2904 /* In the shared -Bsymbolic case, discard space allocated for
2905 dynamic pc-relative relocs against symbols which turn out to be
2906 defined in regular objects. For the normal shared case, discard
2907 space for pc-relative relocs that have become local due to symbol
2908 visibility changes. */
2910 if (bfd_link_pic (info
))
2916 struct elf_dyn_relocs
**pp
;
2918 for (pp
= &eh
->dyn_relocs
; (p
= *pp
) != NULL
; )
2920 p
->count
-= p
->pc_count
;
2928 else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info
, h
))
2929 eh
->dyn_relocs
= NULL
;
2933 /* For the non-shared case, discard space for relocs against
2934 symbols which turn out to need copy relocs or are not
2940 || (htab
->elf
.dynamic_sections_created
2941 && (h
->root
.type
== bfd_link_hash_undefweak
2942 || h
->root
.type
== bfd_link_hash_undefined
))))
2944 /* Make sure this symbol is output as a dynamic symbol.
2945 Undefined weak syms won't yet be marked as dynamic. */
2946 if (h
->dynindx
== -1
2947 && !h
->forced_local
)
2949 if (! bfd_elf_link_record_dynamic_symbol (info
, h
))
2953 /* If that succeeded, we know we'll be keeping all the
2955 if (h
->dynindx
!= -1)
2959 eh
->dyn_relocs
= NULL
;
2964 /* Finally, allocate space. */
2965 for (p
= eh
->dyn_relocs
; p
!= NULL
; p
= p
->next
)
2967 asection
*sreloc
= elf_section_data (p
->sec
)->sreloc
;
2968 sreloc
->size
+= p
->count
* sizeof (Elf32_External_Rela
);
2974 /* Set the sizes of the dynamic sections. */
2977 microblaze_elf_size_dynamic_sections (bfd
*output_bfd ATTRIBUTE_UNUSED
,
2978 struct bfd_link_info
*info
)
2980 struct elf32_mb_link_hash_table
*htab
;
2985 htab
= elf32_mb_hash_table (info
);
2989 dynobj
= htab
->elf
.dynobj
;
2990 BFD_ASSERT (dynobj
!= NULL
);
2992 /* Set up .got offsets for local syms, and space for local dynamic
2994 for (ibfd
= info
->input_bfds
; ibfd
!= NULL
; ibfd
= ibfd
->link
.next
)
2996 bfd_signed_vma
*local_got
;
2997 bfd_signed_vma
*end_local_got
;
2998 bfd_size_type locsymcount
;
2999 Elf_Internal_Shdr
*symtab_hdr
;
3000 unsigned char *lgot_masks
;
3003 if (bfd_get_flavour (ibfd
) != bfd_target_elf_flavour
)
3006 for (s
= ibfd
->sections
; s
!= NULL
; s
= s
->next
)
3008 struct elf_dyn_relocs
*p
;
3010 for (p
= ((struct elf_dyn_relocs
*)
3011 elf_section_data (s
)->local_dynrel
);
3015 if (!bfd_is_abs_section (p
->sec
)
3016 && bfd_is_abs_section (p
->sec
->output_section
))
3018 /* Input section has been discarded, either because
3019 it is a copy of a linkonce section or due to
3020 linker script /DISCARD/, so we'll be discarding
3023 else if (p
->count
!= 0)
3025 srel
= elf_section_data (p
->sec
)->sreloc
;
3026 srel
->size
+= p
->count
* sizeof (Elf32_External_Rela
);
3027 if ((p
->sec
->output_section
->flags
& SEC_READONLY
) != 0)
3028 info
->flags
|= DF_TEXTREL
;
3033 local_got
= elf_local_got_refcounts (ibfd
);
3037 symtab_hdr
= &elf_tdata (ibfd
)->symtab_hdr
;
3038 locsymcount
= symtab_hdr
->sh_info
;
3039 end_local_got
= local_got
+ locsymcount
;
3040 lgot_masks
= (unsigned char *) end_local_got
;
3042 srel
= htab
->elf
.srelgot
;
3044 for (; local_got
< end_local_got
; ++local_got
, ++lgot_masks
)
3048 unsigned int need
= 0;
3049 if ((*lgot_masks
& TLS_TLS
) != 0)
3051 if ((*lgot_masks
& TLS_GD
) != 0)
3053 if ((*lgot_masks
& TLS_LD
) != 0)
3054 htab
->tlsld_got
.refcount
+= 1;
3061 *local_got
= (bfd_vma
) -1;
3065 *local_got
= s
->size
;
3067 if (bfd_link_pic (info
))
3068 srel
->size
+= need
* (sizeof (Elf32_External_Rela
) / 4);
3072 *local_got
= (bfd_vma
) -1;
3076 /* Allocate global sym .plt and .got entries, and space for global
3077 sym dynamic relocs. */
3078 elf_link_hash_traverse (elf_hash_table (info
), allocate_dynrelocs
, info
);
3080 if (htab
->tlsld_got
.refcount
> 0)
3082 htab
->tlsld_got
.offset
= htab
->elf
.sgot
->size
;
3083 htab
->elf
.sgot
->size
+= 8;
3084 if (bfd_link_pic (info
))
3085 htab
->elf
.srelgot
->size
+= sizeof (Elf32_External_Rela
);
3088 htab
->tlsld_got
.offset
= (bfd_vma
) -1;
3090 if (elf_hash_table (info
)->dynamic_sections_created
)
3092 /* Make space for the trailing nop in .plt. */
3093 if (htab
->elf
.splt
->size
> 0)
3094 htab
->elf
.splt
->size
+= 4;
3097 /* The check_relocs and adjust_dynamic_symbol entry points have
3098 determined the sizes of the various dynamic sections. Allocate
3100 for (s
= dynobj
->sections
; s
!= NULL
; s
= s
->next
)
3103 bfd_boolean strip
= FALSE
;
3105 if ((s
->flags
& SEC_LINKER_CREATED
) == 0)
3108 /* It's OK to base decisions on the section name, because none
3109 of the dynobj section names depend upon the input files. */
3110 name
= bfd_section_name (s
);
3112 if (strncmp (name
, ".rela", 5) == 0)
3116 /* If we don't need this section, strip it from the
3117 output file. This is to handle .rela.bss and
3118 .rela.plt. We must create it in
3119 create_dynamic_sections, because it must be created
3120 before the linker maps input sections to output
3121 sections. The linker does that before
3122 adjust_dynamic_symbol is called, and it is that
3123 function which decides whether anything needs to go
3124 into these sections. */
3129 /* We use the reloc_count field as a counter if we need
3130 to copy relocs into the output file. */
3134 else if (s
!= htab
->elf
.splt
3135 && s
!= htab
->elf
.sgot
3136 && s
!= htab
->elf
.sgotplt
3137 && s
!= htab
->elf
.sdynbss
3138 && s
!= htab
->elf
.sdynrelro
)
3140 /* It's not one of our sections, so don't allocate space. */
3146 s
->flags
|= SEC_EXCLUDE
;
3150 /* Allocate memory for the section contents. */
3151 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
3152 Unused entries should be reclaimed before the section's contents
3153 are written out, but at the moment this does not happen. Thus in
3154 order to prevent writing out garbage, we initialise the section's
3155 contents to zero. */
3156 s
->contents
= (bfd_byte
*) bfd_zalloc (dynobj
, s
->size
);
3157 if (s
->contents
== NULL
&& s
->size
!= 0)
3161 if (elf_hash_table (info
)->dynamic_sections_created
)
3163 /* Add some entries to the .dynamic section. We fill in the
3164 values later, in microblaze_elf_finish_dynamic_sections, but we
3165 must add the entries now so that we get the correct size for
3166 the .dynamic section. The DT_DEBUG entry is filled in by the
3167 dynamic linker and used by the debugger. */
3168 #define add_dynamic_entry(TAG, VAL) \
3169 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
3171 if (bfd_link_executable (info
))
3173 if (!add_dynamic_entry (DT_DEBUG
, 0))
3177 if (!add_dynamic_entry (DT_RELA
, 0)
3178 || !add_dynamic_entry (DT_RELASZ
, 0)
3179 || !add_dynamic_entry (DT_RELAENT
, sizeof (Elf32_External_Rela
)))
3182 if (htab
->elf
.splt
->size
!= 0)
3184 if (!add_dynamic_entry (DT_PLTGOT
, 0)
3185 || !add_dynamic_entry (DT_PLTRELSZ
, 0)
3186 || !add_dynamic_entry (DT_PLTREL
, DT_RELA
)
3187 || !add_dynamic_entry (DT_JMPREL
, 0)
3188 || !add_dynamic_entry (DT_BIND_NOW
, 1))
3192 if (info
->flags
& DF_TEXTREL
)
3194 if (!add_dynamic_entry (DT_TEXTREL
, 0))
3198 #undef add_dynamic_entry
3202 /* Finish up dynamic symbol handling. We set the contents of various
3203 dynamic sections here. */
3206 microblaze_elf_finish_dynamic_symbol (bfd
*output_bfd
,
3207 struct bfd_link_info
*info
,
3208 struct elf_link_hash_entry
*h
,
3209 Elf_Internal_Sym
*sym
)
3211 struct elf32_mb_link_hash_table
*htab
;
3212 struct elf32_mb_link_hash_entry
*eh
= elf32_mb_hash_entry(h
);
3214 htab
= elf32_mb_hash_table (info
);
3218 if (h
->plt
.offset
!= (bfd_vma
) -1)
3223 Elf_Internal_Rela rela
;
3229 /* This symbol has an entry in the procedure linkage table. Set
3231 BFD_ASSERT (h
->dynindx
!= -1);
3233 splt
= htab
->elf
.splt
;
3234 srela
= htab
->elf
.srelplt
;
3235 sgotplt
= htab
->elf
.sgotplt
;
3236 BFD_ASSERT (splt
!= NULL
&& srela
!= NULL
&& sgotplt
!= NULL
);
3238 plt_index
= h
->plt
.offset
/ PLT_ENTRY_SIZE
- 1; /* first entry reserved. */
3239 got_offset
= (plt_index
+ 3) * 4; /* 3 reserved ??? */
3240 got_addr
= got_offset
;
3242 /* For non-PIC objects we need absolute address of the GOT entry. */
3243 if (!bfd_link_pic (info
))
3244 got_addr
+= sgotplt
->output_section
->vma
+ sgotplt
->output_offset
;
3246 /* Fill in the entry in the procedure linkage table. */
3247 bfd_put_32 (output_bfd
, PLT_ENTRY_WORD_0
+ ((got_addr
>> 16) & 0xffff),
3248 splt
->contents
+ h
->plt
.offset
);
3249 if (bfd_link_pic (info
))
3250 bfd_put_32 (output_bfd
, PLT_ENTRY_WORD_1
+ (got_addr
& 0xffff),
3251 splt
->contents
+ h
->plt
.offset
+ 4);
3253 bfd_put_32 (output_bfd
, PLT_ENTRY_WORD_1_NOPIC
+ (got_addr
& 0xffff),
3254 splt
->contents
+ h
->plt
.offset
+ 4);
3255 bfd_put_32 (output_bfd
, (bfd_vma
) PLT_ENTRY_WORD_2
,
3256 splt
->contents
+ h
->plt
.offset
+ 8);
3257 bfd_put_32 (output_bfd
, (bfd_vma
) PLT_ENTRY_WORD_3
,
3258 splt
->contents
+ h
->plt
.offset
+ 12);
3260 /* Any additions to the .got section??? */
3261 /* bfd_put_32 (output_bfd,
3262 splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
3263 sgotplt->contents + got_offset); */
3265 /* Fill in the entry in the .rela.plt section. */
3266 rela
.r_offset
= (sgotplt
->output_section
->vma
3267 + sgotplt
->output_offset
3269 rela
.r_info
= ELF32_R_INFO (h
->dynindx
, R_MICROBLAZE_JUMP_SLOT
);
3271 loc
= srela
->contents
;
3272 loc
+= plt_index
* sizeof (Elf32_External_Rela
);
3273 bfd_elf32_swap_reloca_out (output_bfd
, &rela
, loc
);
3275 if (!h
->def_regular
)
3277 /* Mark the symbol as undefined, rather than as defined in
3278 the .plt section. Zero the value. */
3279 sym
->st_shndx
= SHN_UNDEF
;
3284 /* h->got.refcount to be checked ? */
3285 if (h
->got
.offset
!= (bfd_vma
) -1 &&
3286 ! ((h
->got
.offset
& 1) ||
3287 IS_TLS_LD(eh
->tls_mask
) || IS_TLS_GD(eh
->tls_mask
)))
3293 /* This symbol has an entry in the global offset table. Set it
3296 sgot
= htab
->elf
.sgot
;
3297 srela
= htab
->elf
.srelgot
;
3298 BFD_ASSERT (sgot
!= NULL
&& srela
!= NULL
);
3300 offset
= (sgot
->output_section
->vma
+ sgot
->output_offset
3301 + (h
->got
.offset
&~ (bfd_vma
) 1));
3303 /* If this is a -Bsymbolic link, and the symbol is defined
3304 locally, we just want to emit a RELATIVE reloc. Likewise if
3305 the symbol was forced to be local because of a version file.
3306 The entry in the global offset table will already have been
3307 initialized in the relocate_section function. */
3308 if (bfd_link_pic (info
)
3309 && ((info
->symbolic
&& h
->def_regular
)
3310 || h
->dynindx
== -1))
3312 asection
*sec
= h
->root
.u
.def
.section
;
3315 value
= h
->root
.u
.def
.value
;
3316 if (sec
->output_section
!= NULL
)
3317 /* PR 21180: If the output section is NULL, then the symbol is no
3318 longer needed, and in theory the GOT entry is redundant. But
3319 it is too late to change our minds now... */
3320 value
+= sec
->output_section
->vma
+ sec
->output_offset
;
3322 microblaze_elf_output_dynamic_relocation (output_bfd
,
3323 srela
, srela
->reloc_count
++,
3325 R_MICROBLAZE_REL
, offset
,
3330 microblaze_elf_output_dynamic_relocation (output_bfd
,
3331 srela
, srela
->reloc_count
++,
3333 R_MICROBLAZE_GLOB_DAT
,
3337 bfd_put_32 (output_bfd
, (bfd_vma
) 0,
3338 sgot
->contents
+ (h
->got
.offset
&~ (bfd_vma
) 1));
3344 Elf_Internal_Rela rela
;
3347 /* This symbols needs a copy reloc. Set it up. */
3349 BFD_ASSERT (h
->dynindx
!= -1);
3351 rela
.r_offset
= (h
->root
.u
.def
.value
3352 + h
->root
.u
.def
.section
->output_section
->vma
3353 + h
->root
.u
.def
.section
->output_offset
);
3354 rela
.r_info
= ELF32_R_INFO (h
->dynindx
, R_MICROBLAZE_COPY
);
3356 if (h
->root
.u
.def
.section
== htab
->elf
.sdynrelro
)
3357 s
= htab
->elf
.sreldynrelro
;
3359 s
= htab
->elf
.srelbss
;
3360 loc
= s
->contents
+ s
->reloc_count
++ * sizeof (Elf32_External_Rela
);
3361 bfd_elf32_swap_reloca_out (output_bfd
, &rela
, loc
);
3364 /* Mark some specially defined symbols as absolute. */
3365 if (h
== htab
->elf
.hdynamic
3366 || h
== htab
->elf
.hgot
3367 || h
== htab
->elf
.hplt
)
3368 sym
->st_shndx
= SHN_ABS
;
3374 /* Finish up the dynamic sections. */
3377 microblaze_elf_finish_dynamic_sections (bfd
*output_bfd
,
3378 struct bfd_link_info
*info
)
3381 asection
*sdyn
, *sgot
;
3382 struct elf32_mb_link_hash_table
*htab
;
3384 htab
= elf32_mb_hash_table (info
);
3388 dynobj
= htab
->elf
.dynobj
;
3390 sdyn
= bfd_get_linker_section (dynobj
, ".dynamic");
3392 if (htab
->elf
.dynamic_sections_created
)
3395 Elf32_External_Dyn
*dyncon
, *dynconend
;
3397 dyncon
= (Elf32_External_Dyn
*) sdyn
->contents
;
3398 dynconend
= (Elf32_External_Dyn
*) (sdyn
->contents
+ sdyn
->size
);
3399 for (; dyncon
< dynconend
; dyncon
++)
3401 Elf_Internal_Dyn dyn
;
3405 bfd_elf32_swap_dyn_in (dynobj
, dyncon
, &dyn
);
3410 s
= htab
->elf
.sgotplt
;
3415 s
= htab
->elf
.srelplt
;
3420 s
= htab
->elf
.srelplt
;
3433 dyn
.d_un
.d_ptr
= s
->output_section
->vma
+ s
->output_offset
;
3435 dyn
.d_un
.d_val
= s
->size
;
3437 bfd_elf32_swap_dyn_out (output_bfd
, &dyn
, dyncon
);
3440 splt
= htab
->elf
.splt
;
3441 BFD_ASSERT (splt
!= NULL
&& sdyn
!= NULL
);
3443 /* Clear the first entry in the procedure linkage table,
3444 and put a nop in the last four bytes. */
3447 memset (splt
->contents
, 0, PLT_ENTRY_SIZE
);
3448 bfd_put_32 (output_bfd
, (bfd_vma
) 0x80000000 /* nop. */,
3449 splt
->contents
+ splt
->size
- 4);
3451 if (splt
->output_section
!= bfd_abs_section_ptr
)
3452 elf_section_data (splt
->output_section
)->this_hdr
.sh_entsize
= 4;
3456 /* Set the first entry in the global offset table to the address of
3457 the dynamic section. */
3458 sgot
= htab
->elf
.sgotplt
;
3459 if (sgot
&& sgot
->size
> 0)
3462 bfd_put_32 (output_bfd
, (bfd_vma
) 0, sgot
->contents
);
3464 bfd_put_32 (output_bfd
,
3465 sdyn
->output_section
->vma
+ sdyn
->output_offset
,
3467 elf_section_data (sgot
->output_section
)->this_hdr
.sh_entsize
= 4;
3470 if (htab
->elf
.sgot
&& htab
->elf
.sgot
->size
> 0)
3471 elf_section_data (htab
->elf
.sgot
->output_section
)->this_hdr
.sh_entsize
= 4;
3476 /* Hook called by the linker routine which adds symbols from an object
3477 file. We use it to put .comm items in .sbss, and not .bss. */
3480 microblaze_elf_add_symbol_hook (bfd
*abfd
,
3481 struct bfd_link_info
*info
,
3482 Elf_Internal_Sym
*sym
,
3483 const char **namep ATTRIBUTE_UNUSED
,
3484 flagword
*flagsp ATTRIBUTE_UNUSED
,
3488 if (sym
->st_shndx
== SHN_COMMON
3489 && !bfd_link_relocatable (info
)
3490 && sym
->st_size
<= elf_gp_size (abfd
))
3492 /* Common symbols less than or equal to -G nn bytes are automatically
3494 *secp
= bfd_make_section_old_way (abfd
, ".sbss");
3496 || !bfd_set_section_flags (*secp
, SEC_IS_COMMON
))
3499 *valp
= sym
->st_size
;
3505 #define TARGET_LITTLE_SYM microblaze_elf32_le_vec
3506 #define TARGET_LITTLE_NAME "elf32-microblazeel"
3508 #define TARGET_BIG_SYM microblaze_elf32_vec
3509 #define TARGET_BIG_NAME "elf32-microblaze"
3511 #define ELF_ARCH bfd_arch_microblaze
3512 #define ELF_TARGET_ID MICROBLAZE_ELF_DATA
3513 #define ELF_MACHINE_CODE EM_MICROBLAZE
3514 #define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
3515 #define ELF_MAXPAGESIZE 0x1000
3516 #define elf_info_to_howto microblaze_elf_info_to_howto
3517 #define elf_info_to_howto_rel NULL
3519 #define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
3520 #define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name
3521 #define elf_backend_relocate_section microblaze_elf_relocate_section
3522 #define bfd_elf32_bfd_relax_section microblaze_elf_relax_section
3523 #define bfd_elf32_bfd_merge_private_bfd_data _bfd_generic_verify_endian_match
3524 #define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
3526 #define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
3527 #define elf_backend_check_relocs microblaze_elf_check_relocs
3528 #define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
3529 #define bfd_elf32_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
3530 #define elf_backend_can_gc_sections 1
3531 #define elf_backend_can_refcount 1
3532 #define elf_backend_want_got_plt 1
3533 #define elf_backend_plt_readonly 1
3534 #define elf_backend_got_header_size 12
3535 #define elf_backend_want_dynrelro 1
3536 #define elf_backend_rela_normal 1
3537 #define elf_backend_dtrel_excludes_plt 1
3539 #define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
3540 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
3541 #define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
3542 #define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
3543 #define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
3544 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
3546 #include "elf32-target.h"