Automatic date update in version.in
[binutils-gdb.git] / bfd / elf32-microblaze.c
blob013c32a1e516fd19079595deef0df4d93f52feb3
1 /* Xilinx MicroBlaze-specific support for 32-bit ELF
3 Copyright (C) 2009-2022 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 Boston, MA 02110-1301, USA. */
23 #include "sysdep.h"
24 #include "bfd.h"
25 #include "bfdlink.h"
26 #include "libbfd.h"
27 #include "elf-bfd.h"
28 #include "elf/microblaze.h"
29 #include <assert.h>
31 #define USE_RELA /* Only USE_REL is actually significant, but this is
32 here are a reminder... */
33 #define INST_WORD_SIZE 4
35 static int ro_small_data_pointer = 0;
36 static int rw_small_data_pointer = 0;
38 static reloc_howto_type * microblaze_elf_howto_table [(int) R_MICROBLAZE_max];
40 static reloc_howto_type microblaze_elf_howto_raw[] =
42 /* This reloc does nothing. */
43 HOWTO (R_MICROBLAZE_NONE, /* Type. */
44 0, /* Rightshift. */
45 0, /* Size. */
46 0, /* Bitsize. */
47 false, /* PC_relative. */
48 0, /* Bitpos. */
49 complain_overflow_dont, /* Complain on overflow. */
50 NULL, /* Special Function. */
51 "R_MICROBLAZE_NONE", /* Name. */
52 false, /* Partial Inplace. */
53 0, /* Source Mask. */
54 0, /* Dest Mask. */
55 false), /* PC relative offset? */
57 /* A standard 32 bit relocation. */
58 HOWTO (R_MICROBLAZE_32, /* Type. */
59 0, /* Rightshift. */
60 4, /* Size. */
61 32, /* Bitsize. */
62 false, /* PC_relative. */
63 0, /* Bitpos. */
64 complain_overflow_bitfield, /* Complain on overflow. */
65 bfd_elf_generic_reloc,/* Special Function. */
66 "R_MICROBLAZE_32", /* Name. */
67 false, /* Partial Inplace. */
68 0, /* Source Mask. */
69 0xffffffff, /* Dest Mask. */
70 false), /* PC relative offset? */
72 /* A standard PCREL 32 bit relocation. */
73 HOWTO (R_MICROBLAZE_32_PCREL,/* Type. */
74 0, /* Rightshift. */
75 4, /* Size. */
76 32, /* Bitsize. */
77 true, /* PC_relative. */
78 0, /* Bitpos. */
79 complain_overflow_bitfield, /* Complain on overflow. */
80 bfd_elf_generic_reloc,/* Special Function. */
81 "R_MICROBLAZE_32_PCREL", /* Name. */
82 true, /* Partial Inplace. */
83 0, /* Source Mask. */
84 0xffffffff, /* Dest Mask. */
85 true), /* PC relative offset? */
87 /* A 64 bit PCREL relocation. Table-entry not really used. */
88 HOWTO (R_MICROBLAZE_64_PCREL,/* Type. */
89 0, /* Rightshift. */
90 4, /* Size. */
91 16, /* Bitsize. */
92 true, /* PC_relative. */
93 0, /* Bitpos. */
94 complain_overflow_dont, /* Complain on overflow. */
95 bfd_elf_generic_reloc,/* Special Function. */
96 "R_MICROBLAZE_64_PCREL", /* Name. */
97 false, /* Partial Inplace. */
98 0, /* Source Mask. */
99 0x0000ffff, /* Dest Mask. */
100 true), /* PC relative offset? */
102 /* The low half of a PCREL 32 bit relocation. */
103 HOWTO (R_MICROBLAZE_32_PCREL_LO, /* Type. */
104 0, /* Rightshift. */
105 4, /* Size. */
106 16, /* Bitsize. */
107 true, /* PC_relative. */
108 0, /* Bitpos. */
109 complain_overflow_signed, /* Complain on overflow. */
110 bfd_elf_generic_reloc, /* Special Function. */
111 "R_MICROBLAZE_32_PCREL_LO", /* Name. */
112 false, /* Partial Inplace. */
113 0, /* Source Mask. */
114 0x0000ffff, /* Dest Mask. */
115 true), /* PC relative offset? */
117 /* A 64 bit relocation. Table entry not really used. */
118 HOWTO (R_MICROBLAZE_64, /* Type. */
119 0, /* Rightshift. */
120 4, /* Size. */
121 16, /* Bitsize. */
122 false, /* PC_relative. */
123 0, /* Bitpos. */
124 complain_overflow_dont, /* Complain on overflow. */
125 bfd_elf_generic_reloc,/* Special Function. */
126 "R_MICROBLAZE_64", /* Name. */
127 false, /* Partial Inplace. */
128 0, /* Source Mask. */
129 0x0000ffff, /* Dest Mask. */
130 false), /* PC relative offset? */
132 /* The low half of a 32 bit relocation. */
133 HOWTO (R_MICROBLAZE_32_LO, /* Type. */
134 0, /* Rightshift. */
135 4, /* Size. */
136 16, /* Bitsize. */
137 false, /* PC_relative. */
138 0, /* Bitpos. */
139 complain_overflow_signed, /* Complain on overflow. */
140 bfd_elf_generic_reloc,/* Special Function. */
141 "R_MICROBLAZE_32_LO", /* Name. */
142 false, /* Partial Inplace. */
143 0, /* Source Mask. */
144 0x0000ffff, /* Dest Mask. */
145 false), /* PC relative offset? */
147 /* Read-only small data section relocation. */
148 HOWTO (R_MICROBLAZE_SRO32, /* Type. */
149 0, /* Rightshift. */
150 4, /* Size. */
151 16, /* Bitsize. */
152 false, /* PC_relative. */
153 0, /* Bitpos. */
154 complain_overflow_bitfield, /* Complain on overflow. */
155 bfd_elf_generic_reloc,/* Special Function. */
156 "R_MICROBLAZE_SRO32", /* Name. */
157 false, /* Partial Inplace. */
158 0, /* Source Mask. */
159 0x0000ffff, /* Dest Mask. */
160 false), /* PC relative offset? */
162 /* Read-write small data area relocation. */
163 HOWTO (R_MICROBLAZE_SRW32, /* Type. */
164 0, /* Rightshift. */
165 4, /* Size. */
166 16, /* Bitsize. */
167 false, /* PC_relative. */
168 0, /* Bitpos. */
169 complain_overflow_bitfield, /* Complain on overflow. */
170 bfd_elf_generic_reloc,/* Special Function. */
171 "R_MICROBLAZE_SRW32", /* Name. */
172 false, /* Partial Inplace. */
173 0, /* Source Mask. */
174 0x0000ffff, /* Dest Mask. */
175 false), /* PC relative offset? */
177 /* This reloc does nothing. Used for relaxation. */
178 HOWTO (R_MICROBLAZE_64_NONE, /* Type. */
179 0, /* Rightshift. */
180 0, /* Size. */
181 0, /* Bitsize. */
182 true, /* PC_relative. */
183 0, /* Bitpos. */
184 complain_overflow_dont, /* Complain on overflow. */
185 NULL, /* Special Function. */
186 "R_MICROBLAZE_64_NONE",/* Name. */
187 false, /* Partial Inplace. */
188 0, /* Source Mask. */
189 0, /* Dest Mask. */
190 false), /* PC relative offset? */
192 /* Symbol Op Symbol relocation. */
193 HOWTO (R_MICROBLAZE_32_SYM_OP_SYM, /* Type. */
194 0, /* Rightshift. */
195 4, /* Size. */
196 32, /* Bitsize. */
197 false, /* PC_relative. */
198 0, /* Bitpos. */
199 complain_overflow_bitfield, /* Complain on overflow. */
200 bfd_elf_generic_reloc,/* Special Function. */
201 "R_MICROBLAZE_32_SYM_OP_SYM", /* Name. */
202 false, /* Partial Inplace. */
203 0, /* Source Mask. */
204 0xffffffff, /* Dest Mask. */
205 false), /* PC relative offset? */
207 /* GNU extension to record C++ vtable hierarchy. */
208 HOWTO (R_MICROBLAZE_GNU_VTINHERIT, /* Type. */
209 0, /* Rightshift. */
210 4, /* Size. */
211 0, /* Bitsize. */
212 false, /* PC_relative. */
213 0, /* Bitpos. */
214 complain_overflow_dont,/* Complain on overflow. */
215 NULL, /* Special Function. */
216 "R_MICROBLAZE_GNU_VTINHERIT", /* Name. */
217 false, /* Partial Inplace. */
218 0, /* Source Mask. */
219 0, /* Dest Mask. */
220 false), /* PC relative offset? */
222 /* GNU extension to record C++ vtable member usage. */
223 HOWTO (R_MICROBLAZE_GNU_VTENTRY, /* Type. */
224 0, /* Rightshift. */
225 4, /* Size. */
226 0, /* Bitsize. */
227 false, /* PC_relative. */
228 0, /* Bitpos. */
229 complain_overflow_dont,/* Complain on overflow. */
230 _bfd_elf_rel_vtable_reloc_fn, /* Special Function. */
231 "R_MICROBLAZE_GNU_VTENTRY", /* Name. */
232 false, /* Partial Inplace. */
233 0, /* Source Mask. */
234 0, /* Dest Mask. */
235 false), /* PC relative offset? */
237 /* A 64 bit GOTPC relocation. Table-entry not really used. */
238 HOWTO (R_MICROBLAZE_GOTPC_64, /* Type. */
239 0, /* Rightshift. */
240 4, /* Size. */
241 16, /* Bitsize. */
242 true, /* PC_relative. */
243 0, /* Bitpos. */
244 complain_overflow_dont, /* Complain on overflow. */
245 bfd_elf_generic_reloc, /* Special Function. */
246 "R_MICROBLAZE_GOTPC_64", /* Name. */
247 false, /* Partial Inplace. */
248 0, /* Source Mask. */
249 0x0000ffff, /* Dest Mask. */
250 true), /* PC relative offset? */
252 /* A 64 bit TEXTPCREL relocation. Table-entry not really used. */
253 HOWTO (R_MICROBLAZE_TEXTPCREL_64, /* Type. */
254 0, /* Rightshift. */
255 4, /* Size. */
256 16, /* Bitsize. */
257 true, /* PC_relative. */
258 0, /* Bitpos. */
259 complain_overflow_dont, /* Complain on overflow. */
260 bfd_elf_generic_reloc, /* Special Function. */
261 "R_MICROBLAZE_TEXTPCREL_64", /* Name. */
262 false, /* Partial Inplace. */
263 0, /* Source Mask. */
264 0x0000ffff, /* Dest Mask. */
265 true), /* PC relative offset? */
267 /* A 64 bit GOT relocation. Table-entry not really used. */
268 HOWTO (R_MICROBLAZE_GOT_64, /* Type. */
269 0, /* Rightshift. */
270 4, /* Size. */
271 16, /* Bitsize. */
272 false, /* PC_relative. */
273 0, /* Bitpos. */
274 complain_overflow_dont, /* Complain on overflow. */
275 bfd_elf_generic_reloc,/* Special Function. */
276 "R_MICROBLAZE_GOT_64",/* Name. */
277 false, /* Partial Inplace. */
278 0, /* Source Mask. */
279 0x0000ffff, /* Dest Mask. */
280 false), /* PC relative offset? */
282 /* A 64 bit TEXTREL relocation. Table-entry not really used. */
283 HOWTO (R_MICROBLAZE_TEXTREL_64, /* Type. */
284 0, /* Rightshift. */
285 4, /* Size. */
286 16, /* Bitsize. */
287 false, /* PC_relative. */
288 0, /* Bitpos. */
289 complain_overflow_dont, /* Complain on overflow. */
290 bfd_elf_generic_reloc,/* Special Function. */
291 "R_MICROBLAZE_TEXTREL_64",/* Name. */
292 false, /* Partial Inplace. */
293 0, /* Source Mask. */
294 0x0000ffff, /* Dest Mask. */
295 false), /* PC relative offset? */
297 /* A 64 bit PLT relocation. Table-entry not really used. */
298 HOWTO (R_MICROBLAZE_PLT_64, /* Type. */
299 0, /* Rightshift. */
300 4, /* Size. */
301 16, /* Bitsize. */
302 true, /* PC_relative. */
303 0, /* Bitpos. */
304 complain_overflow_dont, /* Complain on overflow. */
305 bfd_elf_generic_reloc,/* Special Function. */
306 "R_MICROBLAZE_PLT_64",/* Name. */
307 false, /* Partial Inplace. */
308 0, /* Source Mask. */
309 0x0000ffff, /* Dest Mask. */
310 true), /* PC relative offset? */
312 /* Table-entry not really used. */
313 HOWTO (R_MICROBLAZE_REL, /* Type. */
314 0, /* Rightshift. */
315 4, /* Size. */
316 16, /* Bitsize. */
317 true, /* PC_relative. */
318 0, /* Bitpos. */
319 complain_overflow_dont, /* Complain on overflow. */
320 bfd_elf_generic_reloc,/* Special Function. */
321 "R_MICROBLAZE_REL", /* Name. */
322 false, /* Partial Inplace. */
323 0, /* Source Mask. */
324 0x0000ffff, /* Dest Mask. */
325 true), /* PC relative offset? */
327 /* Table-entry not really used. */
328 HOWTO (R_MICROBLAZE_JUMP_SLOT,/* Type. */
329 0, /* Rightshift. */
330 4, /* Size. */
331 16, /* Bitsize. */
332 true, /* PC_relative. */
333 0, /* Bitpos. */
334 complain_overflow_dont, /* Complain on overflow. */
335 bfd_elf_generic_reloc,/* Special Function. */
336 "R_MICROBLAZE_JUMP_SLOT", /* Name. */
337 false, /* Partial Inplace. */
338 0, /* Source Mask. */
339 0x0000ffff, /* Dest Mask. */
340 true), /* PC relative offset? */
342 /* Table-entry not really used. */
343 HOWTO (R_MICROBLAZE_GLOB_DAT,/* Type. */
344 0, /* Rightshift. */
345 4, /* Size. */
346 16, /* Bitsize. */
347 true, /* PC_relative. */
348 0, /* Bitpos. */
349 complain_overflow_dont, /* Complain on overflow. */
350 bfd_elf_generic_reloc,/* Special Function. */
351 "R_MICROBLAZE_GLOB_DAT", /* Name. */
352 false, /* Partial Inplace. */
353 0, /* Source Mask. */
354 0x0000ffff, /* Dest Mask. */
355 true), /* PC relative offset? */
357 /* A 64 bit GOT relative relocation. Table-entry not really used. */
358 HOWTO (R_MICROBLAZE_GOTOFF_64, /* Type. */
359 0, /* Rightshift. */
360 4, /* Size. */
361 16, /* Bitsize. */
362 false, /* PC_relative. */
363 0, /* Bitpos. */
364 complain_overflow_dont, /* Complain on overflow. */
365 bfd_elf_generic_reloc,/* Special Function. */
366 "R_MICROBLAZE_GOTOFF_64", /* Name. */
367 false, /* Partial Inplace. */
368 0, /* Source Mask. */
369 0x0000ffff, /* Dest Mask. */
370 false), /* PC relative offset? */
372 /* A 32 bit GOT relative relocation. Table-entry not really used. */
373 HOWTO (R_MICROBLAZE_GOTOFF_32, /* Type. */
374 0, /* Rightshift. */
375 4, /* Size. */
376 16, /* Bitsize. */
377 false, /* PC_relative. */
378 0, /* Bitpos. */
379 complain_overflow_dont, /* Complain on overflow. */
380 bfd_elf_generic_reloc, /* Special Function. */
381 "R_MICROBLAZE_GOTOFF_32", /* Name. */
382 false, /* Partial Inplace. */
383 0, /* Source Mask. */
384 0x0000ffff, /* Dest Mask. */
385 false), /* PC relative offset? */
387 /* COPY relocation. Table-entry not really used. */
388 HOWTO (R_MICROBLAZE_COPY, /* Type. */
389 0, /* Rightshift. */
390 4, /* Size. */
391 16, /* Bitsize. */
392 false, /* PC_relative. */
393 0, /* Bitpos. */
394 complain_overflow_dont, /* Complain on overflow. */
395 bfd_elf_generic_reloc,/* Special Function. */
396 "R_MICROBLAZE_COPY", /* Name. */
397 false, /* Partial Inplace. */
398 0, /* Source Mask. */
399 0x0000ffff, /* Dest Mask. */
400 false), /* PC relative offset? */
402 /* Marker relocs for TLS. */
403 HOWTO (R_MICROBLAZE_TLS,
404 0, /* rightshift */
405 4, /* size */
406 32, /* bitsize */
407 false, /* pc_relative */
408 0, /* bitpos */
409 complain_overflow_dont, /* complain_on_overflow */
410 bfd_elf_generic_reloc, /* special_function */
411 "R_MICROBLAZE_TLS", /* name */
412 false, /* partial_inplace */
413 0, /* src_mask */
414 0x0000ffff, /* dst_mask */
415 false), /* pcrel_offset */
417 HOWTO (R_MICROBLAZE_TLSGD,
418 0, /* rightshift */
419 4, /* size */
420 32, /* bitsize */
421 false, /* pc_relative */
422 0, /* bitpos */
423 complain_overflow_dont, /* complain_on_overflow */
424 bfd_elf_generic_reloc, /* special_function */
425 "R_MICROBLAZE_TLSGD", /* name */
426 false, /* partial_inplace */
427 0, /* src_mask */
428 0x0000ffff, /* dst_mask */
429 false), /* pcrel_offset */
431 HOWTO (R_MICROBLAZE_TLSLD,
432 0, /* rightshift */
433 4, /* size */
434 32, /* bitsize */
435 false, /* pc_relative */
436 0, /* bitpos */
437 complain_overflow_dont, /* complain_on_overflow */
438 bfd_elf_generic_reloc, /* special_function */
439 "R_MICROBLAZE_TLSLD", /* name */
440 false, /* partial_inplace */
441 0, /* src_mask */
442 0x0000ffff, /* dst_mask */
443 false), /* pcrel_offset */
445 /* Computes the load module index of the load module that contains the
446 definition of its TLS sym. */
447 HOWTO (R_MICROBLAZE_TLSDTPMOD32,
448 0, /* rightshift */
449 4, /* size */
450 32, /* bitsize */
451 false, /* pc_relative */
452 0, /* bitpos */
453 complain_overflow_dont, /* complain_on_overflow */
454 bfd_elf_generic_reloc, /* special_function */
455 "R_MICROBLAZE_TLSDTPMOD32", /* name */
456 false, /* partial_inplace */
457 0, /* src_mask */
458 0x0000ffff, /* dst_mask */
459 false), /* pcrel_offset */
461 /* Computes a dtv-relative displacement, the difference between the value
462 of sym+add and the base address of the thread-local storage block that
463 contains the definition of sym, minus 0x8000. Used for initializing GOT */
464 HOWTO (R_MICROBLAZE_TLSDTPREL32,
465 0, /* rightshift */
466 4, /* size */
467 32, /* bitsize */
468 false, /* pc_relative */
469 0, /* bitpos */
470 complain_overflow_dont, /* complain_on_overflow */
471 bfd_elf_generic_reloc, /* special_function */
472 "R_MICROBLAZE_TLSDTPREL32", /* name */
473 false, /* partial_inplace */
474 0, /* src_mask */
475 0x0000ffff, /* dst_mask */
476 false), /* pcrel_offset */
478 /* Computes a dtv-relative displacement, the difference between the value
479 of sym+add and the base address of the thread-local storage block that
480 contains the definition of sym, minus 0x8000. */
481 HOWTO (R_MICROBLAZE_TLSDTPREL64,
482 0, /* rightshift */
483 4, /* size */
484 32, /* bitsize */
485 false, /* pc_relative */
486 0, /* bitpos */
487 complain_overflow_dont, /* complain_on_overflow */
488 bfd_elf_generic_reloc, /* special_function */
489 "R_MICROBLAZE_TLSDTPREL64", /* name */
490 false, /* partial_inplace */
491 0, /* src_mask */
492 0x0000ffff, /* dst_mask */
493 false), /* pcrel_offset */
495 /* Computes a tp-relative displacement, the difference between the value of
496 sym+add and the value of the thread pointer (r13). */
497 HOWTO (R_MICROBLAZE_TLSGOTTPREL32,
498 0, /* rightshift */
499 4, /* size */
500 32, /* bitsize */
501 false, /* pc_relative */
502 0, /* bitpos */
503 complain_overflow_dont, /* complain_on_overflow */
504 bfd_elf_generic_reloc, /* special_function */
505 "R_MICROBLAZE_TLSGOTTPREL32", /* name */
506 false, /* partial_inplace */
507 0, /* src_mask */
508 0x0000ffff, /* dst_mask */
509 false), /* pcrel_offset */
511 /* Computes a tp-relative displacement, the difference between the value of
512 sym+add and the value of the thread pointer (r13). */
513 HOWTO (R_MICROBLAZE_TLSTPREL32,
514 0, /* rightshift */
515 4, /* size */
516 32, /* bitsize */
517 false, /* pc_relative */
518 0, /* bitpos */
519 complain_overflow_dont, /* complain_on_overflow */
520 bfd_elf_generic_reloc, /* special_function */
521 "R_MICROBLAZE_TLSTPREL32", /* name */
522 false, /* partial_inplace */
523 0, /* src_mask */
524 0x0000ffff, /* dst_mask */
525 false), /* pcrel_offset */
529 #ifndef NUM_ELEM
530 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
531 #endif
533 /* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */
535 static void
536 microblaze_elf_howto_init (void)
538 unsigned int i;
540 for (i = NUM_ELEM (microblaze_elf_howto_raw); i--;)
542 unsigned int type;
544 type = microblaze_elf_howto_raw[i].type;
546 BFD_ASSERT (type < NUM_ELEM (microblaze_elf_howto_table));
548 microblaze_elf_howto_table [type] = & microblaze_elf_howto_raw [i];
552 static reloc_howto_type *
553 microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
554 bfd_reloc_code_real_type code)
556 enum elf_microblaze_reloc_type microblaze_reloc = R_MICROBLAZE_NONE;
558 switch (code)
560 case BFD_RELOC_NONE:
561 microblaze_reloc = R_MICROBLAZE_NONE;
562 break;
563 case BFD_RELOC_MICROBLAZE_64_NONE:
564 microblaze_reloc = R_MICROBLAZE_64_NONE;
565 break;
566 case BFD_RELOC_32:
567 microblaze_reloc = R_MICROBLAZE_32;
568 break;
569 /* RVA is treated the same as 32 */
570 case BFD_RELOC_RVA:
571 microblaze_reloc = R_MICROBLAZE_32;
572 break;
573 case BFD_RELOC_32_PCREL:
574 microblaze_reloc = R_MICROBLAZE_32_PCREL;
575 break;
576 case BFD_RELOC_64_PCREL:
577 microblaze_reloc = R_MICROBLAZE_64_PCREL;
578 break;
579 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
580 microblaze_reloc = R_MICROBLAZE_32_PCREL_LO;
581 break;
582 case BFD_RELOC_64:
583 microblaze_reloc = R_MICROBLAZE_64;
584 break;
585 case BFD_RELOC_MICROBLAZE_32_LO:
586 microblaze_reloc = R_MICROBLAZE_32_LO;
587 break;
588 case BFD_RELOC_MICROBLAZE_32_ROSDA:
589 microblaze_reloc = R_MICROBLAZE_SRO32;
590 break;
591 case BFD_RELOC_MICROBLAZE_32_RWSDA:
592 microblaze_reloc = R_MICROBLAZE_SRW32;
593 break;
594 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
595 microblaze_reloc = R_MICROBLAZE_32_SYM_OP_SYM;
596 break;
597 case BFD_RELOC_VTABLE_INHERIT:
598 microblaze_reloc = R_MICROBLAZE_GNU_VTINHERIT;
599 break;
600 case BFD_RELOC_VTABLE_ENTRY:
601 microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
602 break;
603 case BFD_RELOC_MICROBLAZE_64_GOTPC:
604 microblaze_reloc = R_MICROBLAZE_GOTPC_64;
605 break;
606 case BFD_RELOC_MICROBLAZE_64_GOT:
607 microblaze_reloc = R_MICROBLAZE_GOT_64;
608 break;
609 case BFD_RELOC_MICROBLAZE_64_TEXTPCREL:
610 microblaze_reloc = R_MICROBLAZE_TEXTPCREL_64;
611 break;
612 case BFD_RELOC_MICROBLAZE_64_TEXTREL:
613 microblaze_reloc = R_MICROBLAZE_TEXTREL_64;
614 break;
615 case BFD_RELOC_MICROBLAZE_64_PLT:
616 microblaze_reloc = R_MICROBLAZE_PLT_64;
617 break;
618 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
619 microblaze_reloc = R_MICROBLAZE_GOTOFF_64;
620 break;
621 case BFD_RELOC_MICROBLAZE_32_GOTOFF:
622 microblaze_reloc = R_MICROBLAZE_GOTOFF_32;
623 break;
624 case BFD_RELOC_MICROBLAZE_64_TLSGD:
625 microblaze_reloc = R_MICROBLAZE_TLSGD;
626 break;
627 case BFD_RELOC_MICROBLAZE_64_TLSLD:
628 microblaze_reloc = R_MICROBLAZE_TLSLD;
629 break;
630 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
631 microblaze_reloc = R_MICROBLAZE_TLSDTPREL32;
632 break;
633 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
634 microblaze_reloc = R_MICROBLAZE_TLSDTPREL64;
635 break;
636 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
637 microblaze_reloc = R_MICROBLAZE_TLSDTPMOD32;
638 break;
639 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
640 microblaze_reloc = R_MICROBLAZE_TLSGOTTPREL32;
641 break;
642 case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
643 microblaze_reloc = R_MICROBLAZE_TLSTPREL32;
644 break;
645 case BFD_RELOC_MICROBLAZE_COPY:
646 microblaze_reloc = R_MICROBLAZE_COPY;
647 break;
648 default:
649 return (reloc_howto_type *) NULL;
652 if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
653 /* Initialize howto table if needed. */
654 microblaze_elf_howto_init ();
656 return microblaze_elf_howto_table [(int) microblaze_reloc];
659 static reloc_howto_type *
660 microblaze_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
661 const char *r_name)
663 unsigned int i;
665 for (i = 0; i < NUM_ELEM (microblaze_elf_howto_raw); i++)
666 if (microblaze_elf_howto_raw[i].name != NULL
667 && strcasecmp (microblaze_elf_howto_raw[i].name, r_name) == 0)
668 return &microblaze_elf_howto_raw[i];
670 return NULL;
673 /* Set the howto pointer for a RCE ELF reloc. */
675 static bool
676 microblaze_elf_info_to_howto (bfd * abfd,
677 arelent * cache_ptr,
678 Elf_Internal_Rela * dst)
680 unsigned int r_type;
682 if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
683 /* Initialize howto table if needed. */
684 microblaze_elf_howto_init ();
686 r_type = ELF32_R_TYPE (dst->r_info);
687 if (r_type >= R_MICROBLAZE_max)
689 /* xgettext:c-format */
690 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
691 abfd, r_type);
692 bfd_set_error (bfd_error_bad_value);
693 return false;
696 cache_ptr->howto = microblaze_elf_howto_table [r_type];
697 return true;
700 /* Relax table contains information about instructions which can
701 be removed by relaxation -- replacing a long address with a
702 short address. */
703 struct relax_table
705 /* Address where bytes may be deleted. */
706 bfd_vma addr;
708 /* Number of bytes to be deleted. */
709 size_t size;
712 struct _microblaze_elf_section_data
714 struct bfd_elf_section_data elf;
715 /* Count of used relaxation table entries. */
716 size_t relax_count;
717 /* Relaxation table. */
718 struct relax_table *relax;
721 #define microblaze_elf_section_data(sec) \
722 ((struct _microblaze_elf_section_data *) elf_section_data (sec))
724 static bool
725 microblaze_elf_new_section_hook (bfd *abfd, asection *sec)
727 if (!sec->used_by_bfd)
729 struct _microblaze_elf_section_data *sdata;
730 size_t amt = sizeof (*sdata);
732 sdata = bfd_zalloc (abfd, amt);
733 if (sdata == NULL)
734 return false;
735 sec->used_by_bfd = sdata;
738 return _bfd_elf_new_section_hook (abfd, sec);
741 /* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
743 static bool
744 microblaze_elf_is_local_label_name (bfd *abfd, const char *name)
746 if (name[0] == 'L' && name[1] == '.')
747 return true;
749 if (name[0] == '$' && name[1] == 'L')
750 return true;
752 /* With gcc, the labels go back to starting with '.', so we accept
753 the generic ELF local label syntax as well. */
754 return _bfd_elf_is_local_label_name (abfd, name);
757 /* ELF linker hash entry. */
759 struct elf32_mb_link_hash_entry
761 struct elf_link_hash_entry elf;
763 /* TLS Reference Types for the symbol; Updated by check_relocs */
764 #define TLS_GD 1 /* GD reloc. */
765 #define TLS_LD 2 /* LD reloc. */
766 #define TLS_TPREL 4 /* TPREL reloc, => IE. */
767 #define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
768 #define TLS_TLS 16 /* Any TLS reloc. */
769 unsigned char tls_mask;
773 #define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD))
774 #define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD))
775 #define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL))
776 #define IS_TLS_NONE(x) (x == 0)
778 #define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent))
780 /* ELF linker hash table. */
782 struct elf32_mb_link_hash_table
784 struct elf_link_hash_table elf;
786 /* TLS Local Dynamic GOT Entry */
787 union {
788 bfd_signed_vma refcount;
789 bfd_vma offset;
790 } tlsld_got;
793 /* Nonzero if this section has TLS related relocations. */
794 #define has_tls_reloc sec_flg0
796 /* Get the ELF linker hash table from a link_info structure. */
798 #define elf32_mb_hash_table(p) \
799 ((is_elf_hash_table ((p)->hash) \
800 && elf_hash_table_id (elf_hash_table (p)) == MICROBLAZE_ELF_DATA) \
801 ? (struct elf32_mb_link_hash_table *) (p)->hash : NULL)
803 /* Create an entry in a microblaze ELF linker hash table. */
805 static struct bfd_hash_entry *
806 link_hash_newfunc (struct bfd_hash_entry *entry,
807 struct bfd_hash_table *table,
808 const char *string)
810 /* Allocate the structure if it has not already been allocated by a
811 subclass. */
812 if (entry == NULL)
814 entry = bfd_hash_allocate (table,
815 sizeof (struct elf32_mb_link_hash_entry));
816 if (entry == NULL)
817 return entry;
820 /* Call the allocation method of the superclass. */
821 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
822 if (entry != NULL)
824 struct elf32_mb_link_hash_entry *eh;
826 eh = (struct elf32_mb_link_hash_entry *) entry;
827 eh->tls_mask = 0;
830 return entry;
833 /* Create a mb ELF linker hash table. */
835 static struct bfd_link_hash_table *
836 microblaze_elf_link_hash_table_create (bfd *abfd)
838 struct elf32_mb_link_hash_table *ret;
839 size_t amt = sizeof (struct elf32_mb_link_hash_table);
841 ret = (struct elf32_mb_link_hash_table *) bfd_zmalloc (amt);
842 if (ret == NULL)
843 return NULL;
845 if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
846 sizeof (struct elf32_mb_link_hash_entry),
847 MICROBLAZE_ELF_DATA))
849 free (ret);
850 return NULL;
853 return &ret->elf.root;
856 /* Set the values of the small data pointers. */
858 static void
859 microblaze_elf_final_sdp (struct bfd_link_info *info)
861 struct bfd_link_hash_entry *h;
863 h = bfd_link_hash_lookup (info->hash, RO_SDA_ANCHOR_NAME, false, false, true);
864 if (h != (struct bfd_link_hash_entry *) NULL
865 && h->type == bfd_link_hash_defined)
866 ro_small_data_pointer = (h->u.def.value
867 + h->u.def.section->output_section->vma
868 + h->u.def.section->output_offset);
870 h = bfd_link_hash_lookup (info->hash, RW_SDA_ANCHOR_NAME, false, false, true);
871 if (h != (struct bfd_link_hash_entry *) NULL
872 && h->type == bfd_link_hash_defined)
873 rw_small_data_pointer = (h->u.def.value
874 + h->u.def.section->output_section->vma
875 + h->u.def.section->output_offset);
878 static bfd_vma
879 dtprel_base (struct bfd_link_info *info)
881 /* If tls_sec is NULL, we should have signalled an error already. */
882 if (elf_hash_table (info)->tls_sec == NULL)
883 return 0;
884 return elf_hash_table (info)->tls_sec->vma;
887 /* The size of the thread control block. */
888 #define TCB_SIZE 8
890 /* Output a simple dynamic relocation into SRELOC. */
892 static void
893 microblaze_elf_output_dynamic_relocation (bfd *output_bfd,
894 asection *sreloc,
895 unsigned long reloc_index,
896 unsigned long indx,
897 int r_type,
898 bfd_vma offset,
899 bfd_vma addend)
902 Elf_Internal_Rela rel;
904 rel.r_info = ELF32_R_INFO (indx, r_type);
905 rel.r_offset = offset;
906 rel.r_addend = addend;
908 bfd_elf32_swap_reloca_out (output_bfd, &rel,
909 (sreloc->contents + reloc_index * sizeof (Elf32_External_Rela)));
912 /* This code is taken from elf32-m32r.c
913 There is some attempt to make this function usable for many architectures,
914 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
915 if only to serve as a learning tool.
917 The RELOCATE_SECTION function is called by the new ELF backend linker
918 to handle the relocations for a section.
920 The relocs are always passed as Rela structures; if the section
921 actually uses Rel structures, the r_addend field will always be
922 zero.
924 This function is responsible for adjust the section contents as
925 necessary, and (if using Rela relocs and generating a
926 relocatable output file) adjusting the reloc addend as
927 necessary.
929 This function does not have to worry about setting the reloc
930 address or the reloc symbol index.
932 LOCAL_SYMS is a pointer to the swapped in local symbols.
934 LOCAL_SECTIONS is an array giving the section in the input file
935 corresponding to the st_shndx field of each local symbol.
937 The global hash table entry for the global symbols can be found
938 via elf_sym_hashes (input_bfd).
940 When generating relocatable output, this function must handle
941 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
942 going to be the section symbol corresponding to the output
943 section, which means that the addend must be adjusted
944 accordingly. */
946 static int
947 microblaze_elf_relocate_section (bfd *output_bfd,
948 struct bfd_link_info *info,
949 bfd *input_bfd,
950 asection *input_section,
951 bfd_byte *contents,
952 Elf_Internal_Rela *relocs,
953 Elf_Internal_Sym *local_syms,
954 asection **local_sections)
956 struct elf32_mb_link_hash_table *htab;
957 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
958 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
959 Elf_Internal_Rela *rel, *relend;
960 int endian = (bfd_little_endian (output_bfd)) ? 0 : 2;
961 /* Assume success. */
962 bool ret = true;
963 asection *sreloc;
964 bfd_vma *local_got_offsets;
965 unsigned int tls_type;
967 if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1])
968 microblaze_elf_howto_init ();
970 htab = elf32_mb_hash_table (info);
971 if (htab == NULL)
972 return false;
974 local_got_offsets = elf_local_got_offsets (input_bfd);
976 sreloc = elf_section_data (input_section)->sreloc;
978 rel = relocs;
979 relend = relocs + input_section->reloc_count;
980 for (; rel < relend; rel++)
982 int r_type;
983 reloc_howto_type *howto;
984 unsigned long r_symndx;
985 bfd_vma addend = rel->r_addend;
986 bfd_vma offset = rel->r_offset;
987 struct elf_link_hash_entry *h;
988 Elf_Internal_Sym *sym;
989 asection *sec;
990 const char *sym_name;
991 bfd_reloc_status_type r = bfd_reloc_ok;
992 const char *errmsg = NULL;
993 bool unresolved_reloc = false;
995 h = NULL;
996 r_type = ELF32_R_TYPE (rel->r_info);
997 tls_type = 0;
999 if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max)
1001 /* xgettext:c-format */
1002 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
1003 input_bfd, (int) r_type);
1004 bfd_set_error (bfd_error_bad_value);
1005 ret = false;
1006 continue;
1009 howto = microblaze_elf_howto_table[r_type];
1010 r_symndx = ELF32_R_SYM (rel->r_info);
1012 if (bfd_link_relocatable (info))
1014 /* This is a relocatable link. We don't have to change
1015 anything, unless the reloc is against a section symbol,
1016 in which case we have to adjust according to where the
1017 section symbol winds up in the output section. */
1018 sec = NULL;
1019 if (r_symndx >= symtab_hdr->sh_info)
1020 /* External symbol. */
1021 continue;
1023 /* Local symbol. */
1024 sym = local_syms + r_symndx;
1025 sym_name = "<local symbol>";
1026 /* STT_SECTION: symbol is associated with a section. */
1027 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
1028 /* Symbol isn't associated with a section. Nothing to do. */
1029 continue;
1031 sec = local_sections[r_symndx];
1032 addend += sec->output_offset + sym->st_value;
1033 #ifndef USE_REL
1034 /* This can't be done for USE_REL because it doesn't mean anything
1035 and elf_link_input_bfd asserts this stays zero. */
1036 /* rel->r_addend = addend; */
1037 #endif
1039 #ifndef USE_REL
1040 /* Addends are stored with relocs. We're done. */
1041 continue;
1042 #else /* USE_REL */
1043 /* If partial_inplace, we need to store any additional addend
1044 back in the section. */
1045 if (!howto->partial_inplace)
1046 continue;
1047 /* ??? Here is a nice place to call a special_function like handler. */
1048 r = _bfd_relocate_contents (howto, input_bfd, addend,
1049 contents + offset);
1050 #endif /* USE_REL */
1052 else
1054 bfd_vma relocation;
1055 bool resolved_to_zero;
1057 /* This is a final link. */
1058 sym = NULL;
1059 sec = NULL;
1060 unresolved_reloc = false;
1062 if (r_symndx < symtab_hdr->sh_info)
1064 /* Local symbol. */
1065 sym = local_syms + r_symndx;
1066 sec = local_sections[r_symndx];
1067 if (sec == 0)
1068 continue;
1069 sym_name = "<local symbol>";
1070 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1071 /* r_addend may have changed if the reference section was
1072 a merge section. */
1073 addend = rel->r_addend;
1075 else
1077 /* External symbol. */
1078 bool warned ATTRIBUTE_UNUSED;
1079 bool ignored ATTRIBUTE_UNUSED;
1081 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1082 r_symndx, symtab_hdr, sym_hashes,
1083 h, sec, relocation,
1084 unresolved_reloc, warned, ignored);
1085 sym_name = h->root.root.string;
1088 /* Sanity check the address. */
1089 if (offset > bfd_get_section_limit (input_bfd, input_section))
1091 r = bfd_reloc_outofrange;
1092 goto check_reloc;
1095 resolved_to_zero = (h != NULL
1096 && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
1098 switch ((int) r_type)
1100 case (int) R_MICROBLAZE_SRO32 :
1102 const char *name;
1104 /* Only relocate if the symbol is defined. */
1105 if (sec)
1107 name = bfd_section_name (sec);
1109 if (strcmp (name, ".sdata2") == 0
1110 || strcmp (name, ".sbss2") == 0)
1112 if (ro_small_data_pointer == 0)
1113 microblaze_elf_final_sdp (info);
1114 if (ro_small_data_pointer == 0)
1116 ret = false;
1117 r = bfd_reloc_undefined;
1118 goto check_reloc;
1121 /* At this point `relocation' contains the object's
1122 address. */
1123 relocation -= ro_small_data_pointer;
1124 /* Now it contains the offset from _SDA2_BASE_. */
1125 r = _bfd_final_link_relocate (howto, input_bfd,
1126 input_section,
1127 contents, offset,
1128 relocation, addend);
1130 else
1132 _bfd_error_handler
1133 /* xgettext:c-format */
1134 (_("%pB: the target (%s) of an %s relocation"
1135 " is in the wrong section (%pA)"),
1136 input_bfd,
1137 sym_name,
1138 microblaze_elf_howto_table[(int) r_type]->name,
1139 sec);
1140 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1141 ret = false;
1142 continue;
1146 break;
1148 case (int) R_MICROBLAZE_SRW32 :
1150 const char *name;
1152 /* Only relocate if the symbol is defined. */
1153 if (sec)
1155 name = bfd_section_name (sec);
1157 if (strcmp (name, ".sdata") == 0
1158 || strcmp (name, ".sbss") == 0)
1160 if (rw_small_data_pointer == 0)
1161 microblaze_elf_final_sdp (info);
1162 if (rw_small_data_pointer == 0)
1164 ret = false;
1165 r = bfd_reloc_undefined;
1166 goto check_reloc;
1169 /* At this point `relocation' contains the object's
1170 address. */
1171 relocation -= rw_small_data_pointer;
1172 /* Now it contains the offset from _SDA_BASE_. */
1173 r = _bfd_final_link_relocate (howto, input_bfd,
1174 input_section,
1175 contents, offset,
1176 relocation, addend);
1178 else
1180 _bfd_error_handler
1181 /* xgettext:c-format */
1182 (_("%pB: the target (%s) of an %s relocation"
1183 " is in the wrong section (%pA)"),
1184 input_bfd,
1185 sym_name,
1186 microblaze_elf_howto_table[(int) r_type]->name,
1187 sec);
1188 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1189 ret = false;
1190 continue;
1194 break;
1196 case (int) R_MICROBLAZE_32_SYM_OP_SYM:
1197 break; /* Do nothing. */
1199 case (int) R_MICROBLAZE_GOTPC_64:
1200 relocation = (htab->elf.sgotplt->output_section->vma
1201 + htab->elf.sgotplt->output_offset);
1202 relocation -= (input_section->output_section->vma
1203 + input_section->output_offset
1204 + offset + INST_WORD_SIZE);
1205 relocation += addend;
1206 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1207 contents + offset + endian);
1208 bfd_put_16 (input_bfd, relocation & 0xffff,
1209 contents + offset + endian + INST_WORD_SIZE);
1210 break;
1212 case (int) R_MICROBLAZE_TEXTPCREL_64:
1213 relocation = input_section->output_section->vma;
1214 relocation -= (input_section->output_section->vma
1215 + input_section->output_offset
1216 + offset + INST_WORD_SIZE);
1217 relocation += addend;
1218 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1219 contents + offset + endian);
1220 bfd_put_16 (input_bfd, relocation & 0xffff,
1221 contents + offset + endian + INST_WORD_SIZE);
1222 break;
1224 case (int) R_MICROBLAZE_PLT_64:
1226 bfd_vma immediate;
1227 if (htab->elf.splt != NULL && h != NULL
1228 && h->plt.offset != (bfd_vma) -1)
1230 relocation = (htab->elf.splt->output_section->vma
1231 + htab->elf.splt->output_offset
1232 + h->plt.offset);
1233 unresolved_reloc = false;
1234 immediate = relocation - (input_section->output_section->vma
1235 + input_section->output_offset
1236 + offset + INST_WORD_SIZE);
1237 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
1238 contents + offset + endian);
1239 bfd_put_16 (input_bfd, immediate & 0xffff,
1240 contents + offset + endian + INST_WORD_SIZE);
1242 else
1244 relocation -= (input_section->output_section->vma
1245 + input_section->output_offset
1246 + offset + INST_WORD_SIZE);
1247 immediate = relocation;
1248 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
1249 contents + offset + endian);
1250 bfd_put_16 (input_bfd, immediate & 0xffff,
1251 contents + offset + endian + INST_WORD_SIZE);
1253 break;
1256 case (int) R_MICROBLAZE_TLSGD:
1257 tls_type = (TLS_TLS | TLS_GD);
1258 goto dogot;
1259 case (int) R_MICROBLAZE_TLSLD:
1260 tls_type = (TLS_TLS | TLS_LD);
1261 /* Fall through. */
1262 dogot:
1263 case (int) R_MICROBLAZE_GOT_64:
1265 bfd_vma *offp;
1266 bfd_vma off, off2;
1267 unsigned long indx;
1268 bfd_vma static_value;
1270 bool need_relocs = false;
1271 if (htab->elf.sgot == NULL)
1272 abort ();
1274 indx = 0;
1275 offp = NULL;
1277 /* 1. Identify GOT Offset;
1278 2. Compute Static Values
1279 3. Process Module Id, Process Offset
1280 4. Fixup Relocation with GOT offset value. */
1282 /* 1. Determine GOT Offset to use : TLS_LD, global, local */
1283 if (IS_TLS_LD (tls_type))
1284 offp = &htab->tlsld_got.offset;
1285 else if (h != NULL)
1287 if (htab->elf.sgotplt != NULL
1288 && h->got.offset != (bfd_vma) -1)
1289 offp = &h->got.offset;
1290 else
1291 abort ();
1293 else
1295 if (local_got_offsets == NULL)
1296 abort ();
1297 offp = &local_got_offsets[r_symndx];
1300 if (!offp)
1301 abort ();
1303 off = (*offp) & ~1;
1304 off2 = off;
1306 if (IS_TLS_LD(tls_type) || IS_TLS_GD(tls_type))
1307 off2 = off + 4;
1309 /* Symbol index to use for relocs */
1310 if (h != NULL)
1312 bool dyn =
1313 elf_hash_table (info)->dynamic_sections_created;
1315 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
1316 bfd_link_pic (info),
1318 && (!bfd_link_pic (info)
1319 || !SYMBOL_REFERENCES_LOCAL (info, h)))
1320 indx = h->dynindx;
1323 /* Need to generate relocs ? */
1324 if ((bfd_link_pic (info) || indx != 0)
1325 && (h == NULL
1326 || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1327 && !resolved_to_zero)
1328 || h->root.type != bfd_link_hash_undefweak))
1329 need_relocs = true;
1331 /* 2. Compute/Emit Static value of r-expression */
1332 static_value = relocation + addend;
1334 /* 3. Process module-id and offset */
1335 if (! ((*offp) & 1) )
1337 bfd_vma got_offset;
1339 got_offset = (htab->elf.sgot->output_section->vma
1340 + htab->elf.sgot->output_offset
1341 + off);
1343 /* Process module-id */
1344 if (IS_TLS_LD(tls_type))
1346 if (! bfd_link_pic (info))
1347 bfd_put_32 (output_bfd, 1,
1348 htab->elf.sgot->contents + off);
1349 else
1350 microblaze_elf_output_dynamic_relocation
1351 (output_bfd,
1352 htab->elf.srelgot,
1353 htab->elf.srelgot->reloc_count++,
1354 /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32,
1355 got_offset, 0);
1357 else if (IS_TLS_GD(tls_type))
1359 if (! need_relocs)
1360 bfd_put_32 (output_bfd, 1,
1361 htab->elf.sgot->contents + off);
1362 else
1363 microblaze_elf_output_dynamic_relocation
1364 (output_bfd,
1365 htab->elf.srelgot,
1366 htab->elf.srelgot->reloc_count++,
1367 /* symindex= */ indx, R_MICROBLAZE_TLSDTPMOD32,
1368 got_offset, indx ? 0 : static_value);
1371 /* Process Offset */
1372 if (htab->elf.srelgot == NULL)
1373 abort ();
1375 got_offset = (htab->elf.sgot->output_section->vma
1376 + htab->elf.sgot->output_offset
1377 + off2);
1378 if (IS_TLS_LD(tls_type))
1380 /* For LD, offset should be 0 */
1381 *offp |= 1;
1382 bfd_put_32 (output_bfd, 0,
1383 htab->elf.sgot->contents + off2);
1385 else if (IS_TLS_GD(tls_type))
1387 *offp |= 1;
1388 static_value -= dtprel_base(info);
1389 if (need_relocs)
1390 microblaze_elf_output_dynamic_relocation
1391 (output_bfd,
1392 htab->elf.srelgot,
1393 htab->elf.srelgot->reloc_count++,
1394 /* symindex= */ indx, R_MICROBLAZE_TLSDTPREL32,
1395 got_offset, indx ? 0 : static_value);
1396 else
1397 bfd_put_32 (output_bfd, static_value,
1398 htab->elf.sgot->contents + off2);
1400 else
1402 bfd_put_32 (output_bfd, static_value,
1403 htab->elf.sgot->contents + off2);
1405 /* Relocs for dyn symbols generated by
1406 finish_dynamic_symbols */
1407 if (bfd_link_pic (info) && h == NULL)
1409 *offp |= 1;
1410 microblaze_elf_output_dynamic_relocation
1411 (output_bfd,
1412 htab->elf.srelgot,
1413 htab->elf.srelgot->reloc_count++,
1414 /* symindex= */ indx, R_MICROBLAZE_REL,
1415 got_offset, static_value);
1420 /* 4. Fixup Relocation with GOT offset value
1421 Compute relative address of GOT entry for applying
1422 the current relocation */
1423 relocation = htab->elf.sgot->output_section->vma
1424 + htab->elf.sgot->output_offset
1425 + off
1426 - htab->elf.sgotplt->output_section->vma
1427 - htab->elf.sgotplt->output_offset;
1429 /* Apply Current Relocation */
1430 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1431 contents + offset + endian);
1432 bfd_put_16 (input_bfd, relocation & 0xffff,
1433 contents + offset + endian + INST_WORD_SIZE);
1435 unresolved_reloc = false;
1436 break;
1439 case (int) R_MICROBLAZE_GOTOFF_64:
1441 bfd_vma immediate;
1442 unsigned short lo, high;
1443 relocation += addend;
1444 relocation -= (htab->elf.sgotplt->output_section->vma
1445 + htab->elf.sgotplt->output_offset);
1446 /* Write this value into correct location. */
1447 immediate = relocation;
1448 lo = immediate & 0x0000ffff;
1449 high = (immediate >> 16) & 0x0000ffff;
1450 bfd_put_16 (input_bfd, high, contents + offset + endian);
1451 bfd_put_16 (input_bfd, lo,
1452 contents + offset + INST_WORD_SIZE + endian);
1453 break;
1456 case (int) R_MICROBLAZE_GOTOFF_32:
1458 relocation += addend;
1459 relocation -= (htab->elf.sgotplt->output_section->vma
1460 + htab->elf.sgotplt->output_offset);
1461 /* Write this value into correct location. */
1462 bfd_put_32 (input_bfd, relocation, contents + offset);
1463 break;
1466 case (int) R_MICROBLAZE_TLSDTPREL64:
1467 relocation += addend;
1468 relocation -= dtprel_base(info);
1469 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1470 contents + offset + 2);
1471 bfd_put_16 (input_bfd, relocation & 0xffff,
1472 contents + offset + 2 + INST_WORD_SIZE);
1473 break;
1474 case (int) R_MICROBLAZE_TEXTREL_64:
1475 case (int) R_MICROBLAZE_TEXTREL_32_LO:
1476 case (int) R_MICROBLAZE_64_PCREL :
1477 case (int) R_MICROBLAZE_64:
1478 case (int) R_MICROBLAZE_32:
1480 /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
1481 from removed linkonce sections, or sections discarded by
1482 a linker script. */
1483 if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
1485 relocation += addend;
1486 if (r_type == R_MICROBLAZE_32)
1487 bfd_put_32 (input_bfd, relocation, contents + offset);
1488 else
1490 if (r_type == R_MICROBLAZE_64_PCREL)
1491 relocation -= (input_section->output_section->vma
1492 + input_section->output_offset
1493 + offset + INST_WORD_SIZE);
1494 else if (r_type == R_MICROBLAZE_TEXTREL_64
1495 || r_type == R_MICROBLAZE_TEXTREL_32_LO)
1496 relocation -= input_section->output_section->vma;
1498 if (r_type == R_MICROBLAZE_TEXTREL_32_LO)
1499 bfd_put_16 (input_bfd, relocation & 0xffff,
1500 contents + offset + endian);
1502 else
1504 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1505 contents + offset + endian);
1506 bfd_put_16 (input_bfd, relocation & 0xffff,
1507 contents + offset + endian + INST_WORD_SIZE);
1510 break;
1513 if ((bfd_link_pic (info)
1514 && (h == NULL
1515 || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1516 && !resolved_to_zero)
1517 || h->root.type != bfd_link_hash_undefweak)
1518 && (!howto->pc_relative
1519 || (h != NULL
1520 && h->dynindx != -1
1521 && (!info->symbolic
1522 || !h->def_regular))))
1523 || (!bfd_link_pic (info)
1524 && h != NULL
1525 && h->dynindx != -1
1526 && !h->non_got_ref
1527 && ((h->def_dynamic
1528 && !h->def_regular)
1529 || h->root.type == bfd_link_hash_undefweak
1530 || h->root.type == bfd_link_hash_undefined)))
1532 Elf_Internal_Rela outrel;
1533 bfd_byte *loc;
1534 bool skip;
1536 /* When generating a shared object, these relocations
1537 are copied into the output file to be resolved at run
1538 time. */
1540 BFD_ASSERT (sreloc != NULL);
1542 skip = false;
1544 outrel.r_offset =
1545 _bfd_elf_section_offset (output_bfd, info, input_section,
1546 rel->r_offset);
1547 if (outrel.r_offset == (bfd_vma) -1)
1548 skip = true;
1549 else if (outrel.r_offset == (bfd_vma) -2)
1550 skip = true;
1551 outrel.r_offset += (input_section->output_section->vma
1552 + input_section->output_offset);
1554 if (skip)
1555 memset (&outrel, 0, sizeof outrel);
1556 /* h->dynindx may be -1 if the symbol was marked to
1557 become local. */
1558 else if (h != NULL
1559 && ((! info->symbolic && h->dynindx != -1)
1560 || !h->def_regular))
1562 BFD_ASSERT (h->dynindx != -1);
1563 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1564 outrel.r_addend = addend;
1566 else
1568 if (r_type == R_MICROBLAZE_32)
1570 outrel.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL);
1571 outrel.r_addend = relocation + addend;
1573 else
1575 BFD_FAIL ();
1576 _bfd_error_handler
1577 (_("%pB: probably compiled without -fPIC?"),
1578 input_bfd);
1579 bfd_set_error (bfd_error_bad_value);
1580 return false;
1584 loc = sreloc->contents;
1585 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
1586 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1587 break;
1589 else
1591 relocation += addend;
1592 if (r_type == R_MICROBLAZE_32)
1593 bfd_put_32 (input_bfd, relocation, contents + offset);
1594 else
1596 if (r_type == R_MICROBLAZE_64_PCREL)
1597 relocation -= (input_section->output_section->vma
1598 + input_section->output_offset
1599 + offset + INST_WORD_SIZE);
1600 else if (r_type == R_MICROBLAZE_TEXTREL_64
1601 || r_type == R_MICROBLAZE_TEXTREL_32_LO)
1602 relocation -= input_section->output_section->vma;
1604 if (r_type == R_MICROBLAZE_TEXTREL_32_LO)
1606 bfd_put_16 (input_bfd, relocation & 0xffff,
1607 contents + offset + endian);
1609 else
1611 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1612 contents + offset + endian);
1613 bfd_put_16 (input_bfd, relocation & 0xffff,
1614 contents + offset + endian
1615 + INST_WORD_SIZE);
1618 break;
1622 default :
1623 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1624 contents, offset,
1625 relocation, addend);
1626 break;
1630 check_reloc:
1632 if (r != bfd_reloc_ok)
1634 /* FIXME: This should be generic enough to go in a utility. */
1635 const char *name;
1637 if (h != NULL)
1638 name = h->root.root.string;
1639 else
1641 name = (bfd_elf_string_from_elf_section
1642 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1643 if (name == NULL || *name == '\0')
1644 name = bfd_section_name (sec);
1647 if (errmsg != NULL)
1648 goto common_error;
1650 switch (r)
1652 case bfd_reloc_overflow:
1653 (*info->callbacks->reloc_overflow)
1654 (info, (h ? &h->root : NULL), name, howto->name,
1655 (bfd_vma) 0, input_bfd, input_section, offset);
1656 break;
1658 case bfd_reloc_undefined:
1659 (*info->callbacks->undefined_symbol)
1660 (info, name, input_bfd, input_section, offset, true);
1661 break;
1663 case bfd_reloc_outofrange:
1664 errmsg = _("internal error: out of range error");
1665 goto common_error;
1667 case bfd_reloc_notsupported:
1668 errmsg = _("internal error: unsupported relocation error");
1669 goto common_error;
1671 case bfd_reloc_dangerous:
1672 errmsg = _("internal error: dangerous error");
1673 goto common_error;
1675 default:
1676 errmsg = _("internal error: unknown error");
1677 /* Fall through. */
1678 common_error:
1679 (*info->callbacks->warning) (info, errmsg, name, input_bfd,
1680 input_section, offset);
1681 break;
1686 return ret;
1689 /* Calculate fixup value for reference. */
1691 static size_t
1692 calc_fixup (bfd_vma start, bfd_vma size, asection *sec)
1694 bfd_vma end = start + size;
1695 size_t i, fixup = 0;
1696 struct _microblaze_elf_section_data *sdata;
1698 if (sec == NULL || (sdata = microblaze_elf_section_data (sec)) == NULL)
1699 return 0;
1701 /* Look for addr in relax table, total fixup value. */
1702 for (i = 0; i < sdata->relax_count; i++)
1704 if (end <= sdata->relax[i].addr)
1705 break;
1706 if (end != start && start > sdata->relax[i].addr)
1707 continue;
1708 fixup += sdata->relax[i].size;
1710 return fixup;
1713 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1714 a 32-bit instruction. */
1715 static void
1716 microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1718 unsigned long instr = bfd_get_32 (abfd, bfd_addr);
1719 instr &= ~0x0000ffff;
1720 instr |= (val & 0x0000ffff);
1721 bfd_put_32 (abfd, instr, bfd_addr);
1724 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1725 two consecutive 32-bit instructions. */
1726 static void
1727 microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1729 unsigned long instr_hi;
1730 unsigned long instr_lo;
1732 instr_hi = bfd_get_32 (abfd, bfd_addr);
1733 instr_hi &= ~0x0000ffff;
1734 instr_hi |= ((val >> 16) & 0x0000ffff);
1735 bfd_put_32 (abfd, instr_hi, bfd_addr);
1737 instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE);
1738 instr_lo &= ~0x0000ffff;
1739 instr_lo |= (val & 0x0000ffff);
1740 bfd_put_32 (abfd, instr_lo, bfd_addr + INST_WORD_SIZE);
1743 static bool
1744 microblaze_elf_relax_section (bfd *abfd,
1745 asection *sec,
1746 struct bfd_link_info *link_info,
1747 bool *again)
1749 Elf_Internal_Shdr *symtab_hdr;
1750 Elf_Internal_Rela *internal_relocs;
1751 Elf_Internal_Rela *free_relocs = NULL;
1752 Elf_Internal_Rela *irel, *irelend;
1753 bfd_byte *contents = NULL;
1754 bfd_byte *free_contents = NULL;
1755 int rel_count;
1756 unsigned int shndx;
1757 size_t i, sym_index;
1758 asection *o;
1759 struct elf_link_hash_entry *sym_hash;
1760 Elf_Internal_Sym *isymbuf, *isymend;
1761 Elf_Internal_Sym *isym;
1762 size_t symcount;
1763 size_t offset;
1764 bfd_vma src, dest;
1765 struct _microblaze_elf_section_data *sdata;
1767 /* We only do this once per section. We may be able to delete some code
1768 by running multiple passes, but it is not worth it. */
1769 *again = false;
1771 /* Only do this for a text section. */
1772 if (bfd_link_relocatable (link_info)
1773 || (sec->flags & SEC_RELOC) == 0
1774 || (sec->flags & SEC_CODE) == 0
1775 || sec->reloc_count == 0
1776 || (sdata = microblaze_elf_section_data (sec)) == NULL)
1777 return true;
1779 BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0));
1781 /* If this is the first time we have been called for this section,
1782 initialize the cooked size. */
1783 if (sec->size == 0)
1784 sec->size = sec->rawsize;
1786 /* Get symbols for this section. */
1787 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1788 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1789 symcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
1790 if (isymbuf == NULL)
1791 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount,
1792 0, NULL, NULL, NULL);
1793 BFD_ASSERT (isymbuf != NULL);
1795 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
1796 if (internal_relocs == NULL)
1797 goto error_return;
1798 if (! link_info->keep_memory)
1799 free_relocs = internal_relocs;
1801 sdata->relax_count = 0;
1802 sdata->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
1803 * sizeof (*sdata->relax));
1804 if (sdata->relax == NULL)
1805 goto error_return;
1807 irelend = internal_relocs + sec->reloc_count;
1808 rel_count = 0;
1809 for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1811 bfd_vma symval;
1812 if ((ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL)
1813 && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64)
1814 && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_TEXTREL_64))
1815 continue; /* Can't delete this reloc. */
1817 /* Get the section contents. */
1818 if (contents == NULL)
1820 if (elf_section_data (sec)->this_hdr.contents != NULL)
1821 contents = elf_section_data (sec)->this_hdr.contents;
1822 else
1824 contents = (bfd_byte *) bfd_malloc (sec->size);
1825 if (contents == NULL)
1826 goto error_return;
1827 free_contents = contents;
1829 if (!bfd_get_section_contents (abfd, sec, contents,
1830 (file_ptr) 0, sec->size))
1831 goto error_return;
1832 elf_section_data (sec)->this_hdr.contents = contents;
1836 /* Get the value of the symbol referred to by the reloc. */
1837 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1839 /* A local symbol. */
1840 asection *sym_sec;
1842 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1843 if (isym->st_shndx == SHN_UNDEF)
1844 sym_sec = bfd_und_section_ptr;
1845 else if (isym->st_shndx == SHN_ABS)
1846 sym_sec = bfd_abs_section_ptr;
1847 else if (isym->st_shndx == SHN_COMMON)
1848 sym_sec = bfd_com_section_ptr;
1849 else
1850 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1852 symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
1854 else
1856 unsigned long indx;
1857 struct elf_link_hash_entry *h;
1859 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1860 h = elf_sym_hashes (abfd)[indx];
1861 BFD_ASSERT (h != NULL);
1863 if (h->root.type != bfd_link_hash_defined
1864 && h->root.type != bfd_link_hash_defweak)
1865 /* This appears to be a reference to an undefined
1866 symbol. Just ignore it--it will be caught by the
1867 regular reloc processing. */
1868 continue;
1870 symval = (h->root.u.def.value
1871 + h->root.u.def.section->output_section->vma
1872 + h->root.u.def.section->output_offset);
1875 /* If this is a PC-relative reloc, subtract the instr offset from
1876 the symbol value. */
1877 if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_64_PCREL)
1879 symval = symval + irel->r_addend
1880 - (irel->r_offset
1881 + sec->output_section->vma
1882 + sec->output_offset);
1884 else if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_TEXTREL_64)
1886 symval = symval + irel->r_addend - (sec->output_section->vma);
1888 else
1889 symval += irel->r_addend;
1891 if ((symval & 0xffff8000) == 0
1892 || (symval & 0xffff8000) == 0xffff8000)
1894 /* We can delete this instruction. */
1895 sdata->relax[sdata->relax_count].addr = irel->r_offset;
1896 sdata->relax[sdata->relax_count].size = INST_WORD_SIZE;
1897 sdata->relax_count++;
1899 /* Rewrite relocation type. */
1900 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1902 case R_MICROBLAZE_64_PCREL:
1903 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1904 (int) R_MICROBLAZE_32_PCREL_LO);
1905 break;
1906 case R_MICROBLAZE_64:
1907 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1908 (int) R_MICROBLAZE_32_LO);
1909 break;
1910 case R_MICROBLAZE_TEXTREL_64:
1911 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1912 (int) R_MICROBLAZE_TEXTREL_32_LO);
1913 break;
1914 default:
1915 /* Cannot happen. */
1916 BFD_ASSERT (false);
1919 } /* Loop through all relocations. */
1921 /* Loop through the relocs again, and see if anything needs to change. */
1922 if (sdata->relax_count > 0)
1924 shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1925 rel_count = 0;
1926 sdata->relax[sdata->relax_count].addr = sec->size;
1928 for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1930 bfd_vma nraddr;
1932 /* Get the new reloc address. */
1933 nraddr = irel->r_offset - calc_fixup (irel->r_offset, 0, sec);
1934 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1936 default:
1937 break;
1938 case R_MICROBLAZE_64_PCREL:
1939 break;
1940 case R_MICROBLAZE_TEXTREL_64:
1941 case R_MICROBLAZE_TEXTREL_32_LO:
1942 case R_MICROBLAZE_64:
1943 case R_MICROBLAZE_32_LO:
1944 /* If this reloc is against a symbol defined in this
1945 section, we must check the addend to see it will put the value in
1946 range to be adjusted, and hence must be changed. */
1947 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1949 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1950 /* Only handle relocs against .text. */
1951 if (isym->st_shndx == shndx
1952 && ELF32_ST_TYPE (isym->st_info) == STT_SECTION)
1953 irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
1955 break;
1956 case R_MICROBLAZE_NONE:
1958 /* This was a PC-relative instruction that was
1959 completely resolved. */
1960 size_t sfix, efix;
1961 bfd_vma target_address;
1962 target_address = irel->r_addend + irel->r_offset;
1963 sfix = calc_fixup (irel->r_offset, 0, sec);
1964 efix = calc_fixup (target_address, 0, sec);
1965 irel->r_addend -= (efix - sfix);
1966 /* Should use HOWTO. */
1967 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
1968 irel->r_addend);
1970 break;
1971 case R_MICROBLAZE_64_NONE:
1973 /* This was a PC-relative 64-bit instruction that was
1974 completely resolved. */
1975 size_t sfix, efix;
1976 bfd_vma target_address;
1977 target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE;
1978 sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec);
1979 efix = calc_fixup (target_address, 0, sec);
1980 irel->r_addend -= (efix - sfix);
1981 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset
1982 + INST_WORD_SIZE, irel->r_addend);
1984 break;
1986 irel->r_offset = nraddr;
1987 } /* Change all relocs in this section. */
1989 /* Look through all other sections. */
1990 for (o = abfd->sections; o != NULL; o = o->next)
1992 Elf_Internal_Rela *irelocs;
1993 Elf_Internal_Rela *irelscan, *irelscanend;
1994 bfd_byte *ocontents;
1996 if (o == sec
1997 || (o->flags & SEC_RELOC) == 0
1998 || o->reloc_count == 0)
1999 continue;
2001 /* We always cache the relocs. Perhaps, if info->keep_memory is
2002 FALSE, we should free them, if we are permitted to. */
2004 irelocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, true);
2005 if (irelocs == NULL)
2006 goto error_return;
2008 ocontents = NULL;
2009 irelscanend = irelocs + o->reloc_count;
2010 for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
2012 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
2014 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2016 /* Look at the reloc only if the value has been resolved. */
2017 if (isym->st_shndx == shndx
2018 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2020 if (ocontents == NULL)
2022 if (elf_section_data (o)->this_hdr.contents != NULL)
2023 ocontents = elf_section_data (o)->this_hdr.contents;
2024 else
2026 /* We always cache the section contents.
2027 Perhaps, if info->keep_memory is FALSE, we
2028 should free them, if we are permitted to. */
2029 if (o->rawsize == 0)
2030 o->rawsize = o->size;
2031 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2032 if (ocontents == NULL)
2033 goto error_return;
2034 if (!bfd_get_section_contents (abfd, o, ocontents,
2035 (file_ptr) 0,
2036 o->rawsize))
2037 goto error_return;
2038 elf_section_data (o)->this_hdr.contents = ocontents;
2042 irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
2044 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
2046 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2048 /* Look at the reloc only if the value has been resolved. */
2049 if (ocontents == NULL)
2051 if (elf_section_data (o)->this_hdr.contents != NULL)
2052 ocontents = elf_section_data (o)->this_hdr.contents;
2053 else
2055 /* We always cache the section contents.
2056 Perhaps, if info->keep_memory is FALSE, we
2057 should free them, if we are permitted to. */
2059 if (o->rawsize == 0)
2060 o->rawsize = o->size;
2061 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2062 if (ocontents == NULL)
2063 goto error_return;
2064 if (!bfd_get_section_contents (abfd, o, ocontents,
2065 (file_ptr) 0,
2066 o->rawsize))
2067 goto error_return;
2068 elf_section_data (o)->this_hdr.contents = ocontents;
2071 irelscan->r_addend -= calc_fixup (irel->r_addend
2072 + isym->st_value,
2074 sec);
2077 else if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO)
2078 || (ELF32_R_TYPE (irelscan->r_info)
2079 == (int) R_MICROBLAZE_32_LO)
2080 || (ELF32_R_TYPE (irelscan->r_info)
2081 == (int) R_MICROBLAZE_TEXTREL_32_LO))
2083 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2085 /* Look at the reloc only if the value has been resolved. */
2086 if (isym->st_shndx == shndx
2087 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2089 bfd_vma immediate;
2090 bfd_vma target_address;
2092 if (ocontents == NULL)
2094 if (elf_section_data (o)->this_hdr.contents != NULL)
2095 ocontents = elf_section_data (o)->this_hdr.contents;
2096 else
2098 /* We always cache the section contents.
2099 Perhaps, if info->keep_memory is FALSE, we
2100 should free them, if we are permitted to. */
2101 if (o->rawsize == 0)
2102 o->rawsize = o->size;
2103 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2104 if (ocontents == NULL)
2105 goto error_return;
2106 if (!bfd_get_section_contents (abfd, o, ocontents,
2107 (file_ptr) 0,
2108 o->rawsize))
2109 goto error_return;
2110 elf_section_data (o)->this_hdr.contents = ocontents;
2114 unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
2115 immediate = instr & 0x0000ffff;
2116 target_address = immediate;
2117 offset = calc_fixup (target_address, 0, sec);
2118 immediate -= offset;
2119 irelscan->r_addend -= offset;
2120 microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
2121 irelscan->r_addend);
2125 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64
2126 || (ELF32_R_TYPE (irelscan->r_info)
2127 == (int) R_MICROBLAZE_TEXTREL_64))
2129 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2131 /* Look at the reloc only if the value has been resolved. */
2132 if (isym->st_shndx == shndx
2133 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2135 if (ocontents == NULL)
2137 if (elf_section_data (o)->this_hdr.contents != NULL)
2138 ocontents = elf_section_data (o)->this_hdr.contents;
2139 else
2141 /* We always cache the section contents.
2142 Perhaps, if info->keep_memory is FALSE, we
2143 should free them, if we are permitted to. */
2145 if (o->rawsize == 0)
2146 o->rawsize = o->size;
2147 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2148 if (ocontents == NULL)
2149 goto error_return;
2150 if (!bfd_get_section_contents (abfd, o, ocontents,
2151 (file_ptr) 0,
2152 o->rawsize))
2153 goto error_return;
2154 elf_section_data (o)->this_hdr.contents = ocontents;
2157 offset = calc_fixup (irelscan->r_addend, 0, sec);
2158 irelscan->r_addend -= offset;
2161 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
2163 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2165 /* Look at the reloc only if the value has been resolved. */
2166 if (isym->st_shndx == shndx
2167 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2169 bfd_vma immediate;
2170 bfd_vma target_address;
2172 if (ocontents == NULL)
2174 if (elf_section_data (o)->this_hdr.contents != NULL)
2175 ocontents = elf_section_data (o)->this_hdr.contents;
2176 else
2178 /* We always cache the section contents.
2179 Perhaps, if info->keep_memory is FALSE, we
2180 should free them, if we are permitted to. */
2181 if (o->rawsize == 0)
2182 o->rawsize = o->size;
2183 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2184 if (ocontents == NULL)
2185 goto error_return;
2186 if (!bfd_get_section_contents (abfd, o, ocontents,
2187 (file_ptr) 0,
2188 o->rawsize))
2189 goto error_return;
2190 elf_section_data (o)->this_hdr.contents = ocontents;
2193 unsigned long instr_hi = bfd_get_32 (abfd, ocontents
2194 + irelscan->r_offset);
2195 unsigned long instr_lo = bfd_get_32 (abfd, ocontents
2196 + irelscan->r_offset
2197 + INST_WORD_SIZE);
2198 immediate = (instr_hi & 0x0000ffff) << 16;
2199 immediate |= (instr_lo & 0x0000ffff);
2200 target_address = immediate;
2201 offset = calc_fixup (target_address, 0, sec);
2202 immediate -= offset;
2203 irelscan->r_addend -= offset;
2204 microblaze_bfd_write_imm_value_64 (abfd, ocontents
2205 + irelscan->r_offset, immediate);
2211 /* Adjust the local symbols defined in this section. */
2212 isymend = isymbuf + symtab_hdr->sh_info;
2213 for (isym = isymbuf; isym < isymend; isym++)
2215 if (isym->st_shndx == shndx)
2217 isym->st_value -= calc_fixup (isym->st_value, 0, sec);
2218 if (isym->st_size)
2219 isym->st_size -= calc_fixup (isym->st_value, isym->st_size, sec);
2223 /* Now adjust the global symbols defined in this section. */
2224 isym = isymbuf + symtab_hdr->sh_info;
2225 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)) - symtab_hdr->sh_info;
2226 for (sym_index = 0; sym_index < symcount; sym_index++)
2228 sym_hash = elf_sym_hashes (abfd)[sym_index];
2229 if ((sym_hash->root.type == bfd_link_hash_defined
2230 || sym_hash->root.type == bfd_link_hash_defweak)
2231 && sym_hash->root.u.def.section == sec)
2233 sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value,
2234 0, sec);
2235 if (sym_hash->size)
2236 sym_hash->size -= calc_fixup (sym_hash->root.u.def.value,
2237 sym_hash->size, sec);
2241 /* Physically move the code and change the cooked size. */
2242 dest = sdata->relax[0].addr;
2243 for (i = 0; i < sdata->relax_count; i++)
2245 size_t len;
2246 src = sdata->relax[i].addr + sdata->relax[i].size;
2247 len = (sdata->relax[i+1].addr - sdata->relax[i].addr
2248 - sdata->relax[i].size);
2250 memmove (contents + dest, contents + src, len);
2251 sec->size -= sdata->relax[i].size;
2252 dest += len;
2255 elf_section_data (sec)->relocs = internal_relocs;
2256 free_relocs = NULL;
2258 elf_section_data (sec)->this_hdr.contents = contents;
2259 free_contents = NULL;
2261 symtab_hdr->contents = (bfd_byte *) isymbuf;
2264 free (free_relocs);
2265 free_relocs = NULL;
2267 if (free_contents != NULL)
2269 if (!link_info->keep_memory)
2270 free (free_contents);
2271 else
2272 /* Cache the section contents for elf_link_input_bfd. */
2273 elf_section_data (sec)->this_hdr.contents = contents;
2274 free_contents = NULL;
2277 if (sdata->relax_count == 0)
2279 *again = false;
2280 free (sdata->relax);
2281 sdata->relax = NULL;
2283 else
2284 *again = true;
2285 return true;
2287 error_return:
2288 free (free_relocs);
2289 free (free_contents);
2290 free (sdata->relax);
2291 sdata->relax = NULL;
2292 sdata->relax_count = 0;
2293 return false;
2296 /* Return the section that should be marked against GC for a given
2297 relocation. */
2299 static asection *
2300 microblaze_elf_gc_mark_hook (asection *sec,
2301 struct bfd_link_info * info,
2302 Elf_Internal_Rela * rel,
2303 struct elf_link_hash_entry * h,
2304 Elf_Internal_Sym * sym)
2306 if (h != NULL)
2307 switch (ELF32_R_TYPE (rel->r_info))
2309 case R_MICROBLAZE_GNU_VTINHERIT:
2310 case R_MICROBLAZE_GNU_VTENTRY:
2311 return NULL;
2314 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
2317 /* PIC support. */
2319 #define PLT_ENTRY_SIZE 16
2321 #define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
2322 #define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
2323 #define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
2324 #define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
2325 #define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
2327 static bool
2328 update_local_sym_info (bfd *abfd,
2329 Elf_Internal_Shdr *symtab_hdr,
2330 unsigned long r_symndx,
2331 unsigned int tls_type)
2333 bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
2334 unsigned char *local_got_tls_masks;
2336 if (local_got_refcounts == NULL)
2338 bfd_size_type size = symtab_hdr->sh_info;
2340 size *= (sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks));
2341 local_got_refcounts = bfd_zalloc (abfd, size);
2342 if (local_got_refcounts == NULL)
2343 return false;
2344 elf_local_got_refcounts (abfd) = local_got_refcounts;
2347 local_got_tls_masks =
2348 (unsigned char *) (local_got_refcounts + symtab_hdr->sh_info);
2349 local_got_tls_masks[r_symndx] |= tls_type;
2350 local_got_refcounts[r_symndx] += 1;
2352 return true;
2354 /* Look through the relocs for a section during the first phase. */
2356 static bool
2357 microblaze_elf_check_relocs (bfd * abfd,
2358 struct bfd_link_info * info,
2359 asection * sec,
2360 const Elf_Internal_Rela * relocs)
2362 Elf_Internal_Shdr * symtab_hdr;
2363 struct elf_link_hash_entry ** sym_hashes;
2364 const Elf_Internal_Rela * rel;
2365 const Elf_Internal_Rela * rel_end;
2366 struct elf32_mb_link_hash_table *htab;
2367 asection *sreloc = NULL;
2369 if (bfd_link_relocatable (info))
2370 return true;
2372 htab = elf32_mb_hash_table (info);
2373 if (htab == NULL)
2374 return false;
2376 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
2377 sym_hashes = elf_sym_hashes (abfd);
2379 rel_end = relocs + sec->reloc_count;
2381 for (rel = relocs; rel < rel_end; rel++)
2383 unsigned int r_type;
2384 struct elf_link_hash_entry * h;
2385 unsigned long r_symndx;
2386 unsigned char tls_type = 0;
2388 r_symndx = ELF32_R_SYM (rel->r_info);
2389 r_type = ELF32_R_TYPE (rel->r_info);
2391 if (r_symndx < symtab_hdr->sh_info)
2392 h = NULL;
2393 else
2395 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
2396 while (h->root.type == bfd_link_hash_indirect
2397 || h->root.type == bfd_link_hash_warning)
2398 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2401 switch (r_type)
2403 /* This relocation describes the C++ object vtable hierarchy.
2404 Reconstruct it for later use during GC. */
2405 case R_MICROBLAZE_GNU_VTINHERIT:
2406 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2407 return false;
2408 break;
2410 /* This relocation describes which C++ vtable entries are actually
2411 used. Record for later use during GC. */
2412 case R_MICROBLAZE_GNU_VTENTRY:
2413 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
2414 return false;
2415 break;
2417 /* This relocation requires .plt entry. */
2418 case R_MICROBLAZE_PLT_64:
2419 if (h != NULL)
2421 h->needs_plt = 1;
2422 h->plt.refcount += 1;
2424 break;
2426 /* This relocation requires .got entry. */
2427 case R_MICROBLAZE_TLSGD:
2428 tls_type |= (TLS_TLS | TLS_GD);
2429 goto dogottls;
2430 case R_MICROBLAZE_TLSLD:
2431 tls_type |= (TLS_TLS | TLS_LD);
2432 /* Fall through. */
2433 dogottls:
2434 sec->has_tls_reloc = 1;
2435 /* Fall through. */
2436 case R_MICROBLAZE_GOT_64:
2437 if (htab->elf.sgot == NULL)
2439 if (htab->elf.dynobj == NULL)
2440 htab->elf.dynobj = abfd;
2441 if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
2442 return false;
2444 if (h != NULL)
2446 h->got.refcount += 1;
2447 elf32_mb_hash_entry (h)->tls_mask |= tls_type;
2449 else
2451 if (! update_local_sym_info(abfd, symtab_hdr, r_symndx, tls_type) )
2452 return false;
2454 break;
2456 case R_MICROBLAZE_GOTOFF_64:
2457 case R_MICROBLAZE_GOTOFF_32:
2458 if (htab->elf.sgot == NULL)
2460 if (htab->elf.dynobj == NULL)
2461 htab->elf.dynobj = abfd;
2462 if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
2463 return false;
2465 break;
2467 case R_MICROBLAZE_64:
2468 case R_MICROBLAZE_64_PCREL:
2469 case R_MICROBLAZE_32:
2471 if (h != NULL && !bfd_link_pic (info))
2473 /* we may need a copy reloc. */
2474 h->non_got_ref = 1;
2476 /* we may also need a .plt entry. */
2477 h->plt.refcount += 1;
2478 if (ELF32_R_TYPE (rel->r_info) != R_MICROBLAZE_64_PCREL)
2479 h->pointer_equality_needed = 1;
2483 /* If we are creating a shared library, and this is a reloc
2484 against a global symbol, or a non PC relative reloc
2485 against a local symbol, then we need to copy the reloc
2486 into the shared library. However, if we are linking with
2487 -Bsymbolic, we do not need to copy a reloc against a
2488 global symbol which is defined in an object we are
2489 including in the link (i.e., DEF_REGULAR is set). At
2490 this point we have not seen all the input files, so it is
2491 possible that DEF_REGULAR is not set now but will be set
2492 later (it is never cleared). In case of a weak definition,
2493 DEF_REGULAR may be cleared later by a strong definition in
2494 a shared library. We account for that possibility below by
2495 storing information in the relocs_copied field of the hash
2496 table entry. A similar situation occurs when creating
2497 shared libraries and symbol visibility changes render the
2498 symbol local.
2500 If on the other hand, we are creating an executable, we
2501 may need to keep relocations for symbols satisfied by a
2502 dynamic library if we manage to avoid copy relocs for the
2503 symbol. */
2505 if ((bfd_link_pic (info)
2506 && (sec->flags & SEC_ALLOC) != 0
2507 && (r_type != R_MICROBLAZE_64_PCREL
2508 || (h != NULL
2509 && (! info->symbolic
2510 || h->root.type == bfd_link_hash_defweak
2511 || !h->def_regular))))
2512 || (!bfd_link_pic (info)
2513 && (sec->flags & SEC_ALLOC) != 0
2514 && h != NULL
2515 && (h->root.type == bfd_link_hash_defweak
2516 || !h->def_regular)))
2518 struct elf_dyn_relocs *p;
2519 struct elf_dyn_relocs **head;
2521 /* When creating a shared object, we must copy these
2522 relocs into the output file. We create a reloc
2523 section in dynobj and make room for the reloc. */
2525 if (sreloc == NULL)
2527 bfd *dynobj;
2529 if (htab->elf.dynobj == NULL)
2530 htab->elf.dynobj = abfd;
2531 dynobj = htab->elf.dynobj;
2533 sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
2534 2, abfd, 1);
2535 if (sreloc == NULL)
2536 return false;
2539 /* If this is a global symbol, we count the number of
2540 relocations we need for this symbol. */
2541 if (h != NULL)
2542 head = &h->dyn_relocs;
2543 else
2545 /* Track dynamic relocs needed for local syms too.
2546 We really need local syms available to do this
2547 easily. Oh well. */
2549 asection *s;
2550 Elf_Internal_Sym *isym;
2551 void *vpp;
2553 isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
2554 abfd, r_symndx);
2555 if (isym == NULL)
2556 return false;
2558 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2559 if (s == NULL)
2560 return false;
2562 vpp = &elf_section_data (s)->local_dynrel;
2563 head = (struct elf_dyn_relocs **) vpp;
2566 p = *head;
2567 if (p == NULL || p->sec != sec)
2569 size_t amt = sizeof *p;
2570 p = ((struct elf_dyn_relocs *)
2571 bfd_alloc (htab->elf.dynobj, amt));
2572 if (p == NULL)
2573 return false;
2574 p->next = *head;
2575 *head = p;
2576 p->sec = sec;
2577 p->count = 0;
2578 p->pc_count = 0;
2581 p->count += 1;
2582 if (r_type == R_MICROBLAZE_64_PCREL)
2583 p->pc_count += 1;
2586 break;
2590 return true;
2593 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2595 static void
2596 microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
2597 struct elf_link_hash_entry *dir,
2598 struct elf_link_hash_entry *ind)
2600 struct elf32_mb_link_hash_entry *edir, *eind;
2602 edir = (struct elf32_mb_link_hash_entry *) dir;
2603 eind = (struct elf32_mb_link_hash_entry *) ind;
2605 edir->tls_mask |= eind->tls_mask;
2607 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
2610 static bool
2611 microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2612 struct elf_link_hash_entry *h)
2614 struct elf32_mb_link_hash_table *htab;
2615 asection *s, *srel;
2616 unsigned int power_of_two;
2618 htab = elf32_mb_hash_table (info);
2619 if (htab == NULL)
2620 return false;
2622 /* If this is a function, put it in the procedure linkage table. We
2623 will fill in the contents of the procedure linkage table later,
2624 when we know the address of the .got section. */
2625 if (h->type == STT_FUNC
2626 || h->needs_plt)
2628 if (h->plt.refcount <= 0
2629 || SYMBOL_CALLS_LOCAL (info, h)
2630 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
2631 && h->root.type == bfd_link_hash_undefweak))
2633 /* This case can occur if we saw a PLT reloc in an input
2634 file, but the symbol was never referred to by a dynamic
2635 object, or if all references were garbage collected. In
2636 such a case, we don't actually need to build a procedure
2637 linkage table, and we can just do a PC32 reloc instead. */
2638 h->plt.offset = (bfd_vma) -1;
2639 h->needs_plt = 0;
2642 return true;
2644 else
2645 /* It's possible that we incorrectly decided a .plt reloc was
2646 needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
2647 check_relocs. We can't decide accurately between function and
2648 non-function syms in check-relocs; Objects loaded later in
2649 the link may change h->type. So fix it now. */
2650 h->plt.offset = (bfd_vma) -1;
2652 /* If this is a weak symbol, and there is a real definition, the
2653 processor independent code will have arranged for us to see the
2654 real definition first, and we can just use the same value. */
2655 if (h->is_weakalias)
2657 struct elf_link_hash_entry *def = weakdef (h);
2658 BFD_ASSERT (def->root.type == bfd_link_hash_defined);
2659 h->root.u.def.section = def->root.u.def.section;
2660 h->root.u.def.value = def->root.u.def.value;
2661 return true;
2664 /* This is a reference to a symbol defined by a dynamic object which
2665 is not a function. */
2667 /* If we are creating a shared library, we must presume that the
2668 only references to the symbol are via the global offset table.
2669 For such cases we need not do anything here; the relocations will
2670 be handled correctly by relocate_section. */
2671 if (bfd_link_pic (info))
2672 return true;
2674 /* If there are no references to this symbol that do not use the
2675 GOT, we don't need to generate a copy reloc. */
2676 if (!h->non_got_ref)
2677 return true;
2679 /* If -z nocopyreloc was given, we won't generate them either. */
2680 if (info->nocopyreloc)
2682 h->non_got_ref = 0;
2683 return true;
2686 /* If we don't find any dynamic relocs in read-only sections, then
2687 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
2688 if (!_bfd_elf_readonly_dynrelocs (h))
2690 h->non_got_ref = 0;
2691 return true;
2694 /* We must allocate the symbol in our .dynbss section, which will
2695 become part of the .bss section of the executable. There will be
2696 an entry for this symbol in the .dynsym section. The dynamic
2697 object will contain position independent code, so all references
2698 from the dynamic object to this symbol will go through the global
2699 offset table. The dynamic linker will use the .dynsym entry to
2700 determine the address it must put in the global offset table, so
2701 both the dynamic object and the regular object will refer to the
2702 same memory location for the variable. */
2704 /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
2705 to copy the initial value out of the dynamic object and into the
2706 runtime process image. */
2707 if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
2709 s = htab->elf.sdynrelro;
2710 srel = htab->elf.sreldynrelro;
2712 else
2714 s = htab->elf.sdynbss;
2715 srel = htab->elf.srelbss;
2717 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2719 srel->size += sizeof (Elf32_External_Rela);
2720 h->needs_copy = 1;
2723 /* We need to figure out the alignment required for this symbol. I
2724 have no idea how ELF linkers handle this. */
2725 power_of_two = bfd_log2 (h->size);
2726 if (power_of_two > 3)
2727 power_of_two = 3;
2729 /* Apply the required alignment. */
2730 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
2731 if (power_of_two > s->alignment_power)
2733 if (!bfd_set_section_alignment (s, power_of_two))
2734 return false;
2737 /* Define the symbol as being at this point in the section. */
2738 h->root.u.def.section = s;
2739 h->root.u.def.value = s->size;
2741 /* Increment the section size to make room for the symbol. */
2742 s->size += h->size;
2743 return true;
2746 /* Allocate space in .plt, .got and associated reloc sections for
2747 dynamic relocs. */
2749 static bool
2750 allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
2752 struct bfd_link_info *info;
2753 struct elf32_mb_link_hash_table *htab;
2754 struct elf32_mb_link_hash_entry *eh;
2755 struct elf_dyn_relocs *p;
2757 if (h->root.type == bfd_link_hash_indirect)
2758 return true;
2760 info = (struct bfd_link_info *) dat;
2761 htab = elf32_mb_hash_table (info);
2762 if (htab == NULL)
2763 return false;
2765 if (htab->elf.dynamic_sections_created
2766 && h->plt.refcount > 0)
2768 /* Make sure this symbol is output as a dynamic symbol.
2769 Undefined weak syms won't yet be marked as dynamic. */
2770 if (h->dynindx == -1
2771 && !h->forced_local)
2773 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2774 return false;
2777 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
2779 asection *s = htab->elf.splt;
2781 /* The first entry in .plt is reserved. */
2782 if (s->size == 0)
2783 s->size = PLT_ENTRY_SIZE;
2785 h->plt.offset = s->size;
2787 /* If this symbol is not defined in a regular file, and we are
2788 not generating a shared library, then set the symbol to this
2789 location in the .plt. This is required to make function
2790 pointers compare as equal between the normal executable and
2791 the shared library. */
2792 if (! bfd_link_pic (info)
2793 && !h->def_regular)
2795 h->root.u.def.section = s;
2796 h->root.u.def.value = h->plt.offset;
2799 /* Make room for this entry. */
2800 s->size += PLT_ENTRY_SIZE;
2802 /* We also need to make an entry in the .got.plt section, which
2803 will be placed in the .got section by the linker script. */
2804 htab->elf.sgotplt->size += 4;
2806 /* We also need to make an entry in the .rel.plt section. */
2807 htab->elf.srelplt->size += sizeof (Elf32_External_Rela);
2809 else
2811 h->plt.offset = (bfd_vma) -1;
2812 h->needs_plt = 0;
2815 else
2817 h->plt.offset = (bfd_vma) -1;
2818 h->needs_plt = 0;
2821 eh = (struct elf32_mb_link_hash_entry *) h;
2822 if (h->got.refcount > 0)
2824 unsigned int need;
2825 asection *s;
2827 /* Make sure this symbol is output as a dynamic symbol.
2828 Undefined weak syms won't yet be marked as dynamic. */
2829 if (h->dynindx == -1
2830 && !h->forced_local)
2832 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2833 return false;
2836 need = 0;
2837 if ((eh->tls_mask & TLS_TLS) != 0)
2839 /* Handle TLS Symbol */
2840 if ((eh->tls_mask & TLS_LD) != 0)
2842 if (!eh->elf.def_dynamic)
2843 /* We'll just use htab->tlsld_got.offset. This should
2844 always be the case. It's a little odd if we have
2845 a local dynamic reloc against a non-local symbol. */
2846 htab->tlsld_got.refcount += 1;
2847 else
2848 need += 8;
2850 if ((eh->tls_mask & TLS_GD) != 0)
2851 need += 8;
2853 else
2855 /* Regular (non-TLS) symbol */
2856 need += 4;
2858 if (need == 0)
2860 h->got.offset = (bfd_vma) -1;
2862 else
2864 s = htab->elf.sgot;
2865 h->got.offset = s->size;
2866 s->size += need;
2867 htab->elf.srelgot->size += need * (sizeof (Elf32_External_Rela) / 4);
2870 else
2871 h->got.offset = (bfd_vma) -1;
2873 if (h->dyn_relocs == NULL)
2874 return true;
2876 /* In the shared -Bsymbolic case, discard space allocated for
2877 dynamic pc-relative relocs against symbols which turn out to be
2878 defined in regular objects. For the normal shared case, discard
2879 space for pc-relative relocs that have become local due to symbol
2880 visibility changes. */
2882 if (bfd_link_pic (info))
2884 if (h->def_regular
2885 && (h->forced_local
2886 || info->symbolic))
2888 struct elf_dyn_relocs **pp;
2890 for (pp = &h->dyn_relocs; (p = *pp) != NULL; )
2892 p->count -= p->pc_count;
2893 p->pc_count = 0;
2894 if (p->count == 0)
2895 *pp = p->next;
2896 else
2897 pp = &p->next;
2900 else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
2901 h->dyn_relocs = NULL;
2903 else
2905 /* For the non-shared case, discard space for relocs against
2906 symbols which turn out to need copy relocs or are not
2907 dynamic. */
2909 if (!h->non_got_ref
2910 && ((h->def_dynamic
2911 && !h->def_regular)
2912 || (htab->elf.dynamic_sections_created
2913 && (h->root.type == bfd_link_hash_undefweak
2914 || h->root.type == bfd_link_hash_undefined))))
2916 /* Make sure this symbol is output as a dynamic symbol.
2917 Undefined weak syms won't yet be marked as dynamic. */
2918 if (h->dynindx == -1
2919 && !h->forced_local)
2921 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2922 return false;
2925 /* If that succeeded, we know we'll be keeping all the
2926 relocs. */
2927 if (h->dynindx != -1)
2928 goto keep;
2931 h->dyn_relocs = NULL;
2933 keep: ;
2936 /* Finally, allocate space. */
2937 for (p = h->dyn_relocs; p != NULL; p = p->next)
2939 asection *sreloc = elf_section_data (p->sec)->sreloc;
2940 sreloc->size += p->count * sizeof (Elf32_External_Rela);
2943 return true;
2946 /* Set the sizes of the dynamic sections. */
2948 static bool
2949 microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2950 struct bfd_link_info *info)
2952 struct elf32_mb_link_hash_table *htab;
2953 bfd *dynobj;
2954 asection *s;
2955 bfd *ibfd;
2957 htab = elf32_mb_hash_table (info);
2958 if (htab == NULL)
2959 return false;
2961 dynobj = htab->elf.dynobj;
2962 BFD_ASSERT (dynobj != NULL);
2964 /* Set up .got offsets for local syms, and space for local dynamic
2965 relocs. */
2966 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
2968 bfd_signed_vma *local_got;
2969 bfd_signed_vma *end_local_got;
2970 bfd_size_type locsymcount;
2971 Elf_Internal_Shdr *symtab_hdr;
2972 unsigned char *lgot_masks;
2973 asection *srel;
2975 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
2976 continue;
2978 for (s = ibfd->sections; s != NULL; s = s->next)
2980 struct elf_dyn_relocs *p;
2982 for (p = ((struct elf_dyn_relocs *)
2983 elf_section_data (s)->local_dynrel);
2984 p != NULL;
2985 p = p->next)
2987 if (!bfd_is_abs_section (p->sec)
2988 && bfd_is_abs_section (p->sec->output_section))
2990 /* Input section has been discarded, either because
2991 it is a copy of a linkonce section or due to
2992 linker script /DISCARD/, so we'll be discarding
2993 the relocs too. */
2995 else if (p->count != 0)
2997 srel = elf_section_data (p->sec)->sreloc;
2998 srel->size += p->count * sizeof (Elf32_External_Rela);
2999 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
3000 info->flags |= DF_TEXTREL;
3005 local_got = elf_local_got_refcounts (ibfd);
3006 if (!local_got)
3007 continue;
3009 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
3010 locsymcount = symtab_hdr->sh_info;
3011 end_local_got = local_got + locsymcount;
3012 lgot_masks = (unsigned char *) end_local_got;
3013 s = htab->elf.sgot;
3014 srel = htab->elf.srelgot;
3016 for (; local_got < end_local_got; ++local_got, ++lgot_masks)
3018 if (*local_got > 0)
3020 unsigned int need = 0;
3021 if ((*lgot_masks & TLS_TLS) != 0)
3023 if ((*lgot_masks & TLS_GD) != 0)
3024 need += 8;
3025 if ((*lgot_masks & TLS_LD) != 0)
3026 htab->tlsld_got.refcount += 1;
3028 else
3029 need += 4;
3031 if (need == 0)
3033 *local_got = (bfd_vma) -1;
3035 else
3037 *local_got = s->size;
3038 s->size += need;
3039 if (bfd_link_pic (info))
3040 srel->size += need * (sizeof (Elf32_External_Rela) / 4);
3043 else
3044 *local_got = (bfd_vma) -1;
3048 /* Allocate global sym .plt and .got entries, and space for global
3049 sym dynamic relocs. */
3050 elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
3052 if (htab->tlsld_got.refcount > 0)
3054 htab->tlsld_got.offset = htab->elf.sgot->size;
3055 htab->elf.sgot->size += 8;
3056 if (bfd_link_pic (info))
3057 htab->elf.srelgot->size += sizeof (Elf32_External_Rela);
3059 else
3060 htab->tlsld_got.offset = (bfd_vma) -1;
3062 if (elf_hash_table (info)->dynamic_sections_created)
3064 /* Make space for the trailing nop in .plt. */
3065 if (htab->elf.splt->size > 0)
3066 htab->elf.splt->size += 4;
3069 /* The check_relocs and adjust_dynamic_symbol entry points have
3070 determined the sizes of the various dynamic sections. Allocate
3071 memory for them. */
3072 for (s = dynobj->sections; s != NULL; s = s->next)
3074 const char *name;
3075 bool strip = false;
3077 if ((s->flags & SEC_LINKER_CREATED) == 0)
3078 continue;
3080 /* It's OK to base decisions on the section name, because none
3081 of the dynobj section names depend upon the input files. */
3082 name = bfd_section_name (s);
3084 if (startswith (name, ".rela"))
3086 if (s->size == 0)
3088 /* If we don't need this section, strip it from the
3089 output file. This is to handle .rela.bss and
3090 .rela.plt. We must create it in
3091 create_dynamic_sections, because it must be created
3092 before the linker maps input sections to output
3093 sections. The linker does that before
3094 adjust_dynamic_symbol is called, and it is that
3095 function which decides whether anything needs to go
3096 into these sections. */
3097 strip = true;
3099 else
3101 /* We use the reloc_count field as a counter if we need
3102 to copy relocs into the output file. */
3103 s->reloc_count = 0;
3106 else if (s != htab->elf.splt
3107 && s != htab->elf.sgot
3108 && s != htab->elf.sgotplt
3109 && s != htab->elf.sdynbss
3110 && s != htab->elf.sdynrelro)
3112 /* It's not one of our sections, so don't allocate space. */
3113 continue;
3116 if (strip)
3118 s->flags |= SEC_EXCLUDE;
3119 continue;
3122 /* Allocate memory for the section contents. */
3123 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
3124 Unused entries should be reclaimed before the section's contents
3125 are written out, but at the moment this does not happen. Thus in
3126 order to prevent writing out garbage, we initialise the section's
3127 contents to zero. */
3128 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
3129 if (s->contents == NULL && s->size != 0)
3130 return false;
3133 /* ??? Force DF_BIND_NOW? */
3134 info->flags |= DF_BIND_NOW;
3135 return _bfd_elf_add_dynamic_tags (output_bfd, info, true);
3138 /* Finish up dynamic symbol handling. We set the contents of various
3139 dynamic sections here. */
3141 static bool
3142 microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
3143 struct bfd_link_info *info,
3144 struct elf_link_hash_entry *h,
3145 Elf_Internal_Sym *sym)
3147 struct elf32_mb_link_hash_table *htab;
3148 struct elf32_mb_link_hash_entry *eh = elf32_mb_hash_entry(h);
3150 htab = elf32_mb_hash_table (info);
3151 if (htab == NULL)
3152 return false;
3154 if (h->plt.offset != (bfd_vma) -1)
3156 asection *splt;
3157 asection *srela;
3158 asection *sgotplt;
3159 Elf_Internal_Rela rela;
3160 bfd_byte *loc;
3161 bfd_vma plt_index;
3162 bfd_vma got_offset;
3163 bfd_vma got_addr;
3165 /* This symbol has an entry in the procedure linkage table. Set
3166 it up. */
3167 BFD_ASSERT (h->dynindx != -1);
3169 splt = htab->elf.splt;
3170 srela = htab->elf.srelplt;
3171 sgotplt = htab->elf.sgotplt;
3172 BFD_ASSERT (splt != NULL && srela != NULL && sgotplt != NULL);
3174 plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* first entry reserved. */
3175 got_offset = (plt_index + 3) * 4; /* 3 reserved ??? */
3176 got_addr = got_offset;
3178 /* For non-PIC objects we need absolute address of the GOT entry. */
3179 if (!bfd_link_pic (info))
3180 got_addr += sgotplt->output_section->vma + sgotplt->output_offset;
3182 /* Fill in the entry in the procedure linkage table. */
3183 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_0 + ((got_addr >> 16) & 0xffff),
3184 splt->contents + h->plt.offset);
3185 if (bfd_link_pic (info))
3186 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1 + (got_addr & 0xffff),
3187 splt->contents + h->plt.offset + 4);
3188 else
3189 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1_NOPIC + (got_addr & 0xffff),
3190 splt->contents + h->plt.offset + 4);
3191 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_2,
3192 splt->contents + h->plt.offset + 8);
3193 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_3,
3194 splt->contents + h->plt.offset + 12);
3196 /* Any additions to the .got section??? */
3197 /* bfd_put_32 (output_bfd,
3198 splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
3199 sgotplt->contents + got_offset); */
3201 /* Fill in the entry in the .rela.plt section. */
3202 rela.r_offset = (sgotplt->output_section->vma
3203 + sgotplt->output_offset
3204 + got_offset);
3205 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_JUMP_SLOT);
3206 rela.r_addend = 0;
3207 loc = srela->contents;
3208 loc += plt_index * sizeof (Elf32_External_Rela);
3209 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
3211 if (!h->def_regular)
3213 /* Mark the symbol as undefined, rather than as defined in
3214 the .plt section. Zero the value. */
3215 sym->st_shndx = SHN_UNDEF;
3216 sym->st_value = 0;
3220 /* h->got.refcount to be checked ? */
3221 if (h->got.offset != (bfd_vma) -1 &&
3222 ! ((h->got.offset & 1) ||
3223 IS_TLS_LD(eh->tls_mask) || IS_TLS_GD(eh->tls_mask)))
3225 asection *sgot;
3226 asection *srela;
3227 bfd_vma offset;
3229 /* This symbol has an entry in the global offset table. Set it
3230 up. */
3232 sgot = htab->elf.sgot;
3233 srela = htab->elf.srelgot;
3234 BFD_ASSERT (sgot != NULL && srela != NULL);
3236 offset = (sgot->output_section->vma + sgot->output_offset
3237 + (h->got.offset &~ (bfd_vma) 1));
3239 /* If this is a -Bsymbolic link, and the symbol is defined
3240 locally, we just want to emit a RELATIVE reloc. Likewise if
3241 the symbol was forced to be local because of a version file.
3242 The entry in the global offset table will already have been
3243 initialized in the relocate_section function. */
3244 if (bfd_link_pic (info)
3245 && ((info->symbolic && h->def_regular)
3246 || h->dynindx == -1))
3248 asection *sec = h->root.u.def.section;
3249 bfd_vma value;
3251 value = h->root.u.def.value;
3252 if (sec->output_section != NULL)
3253 /* PR 21180: If the output section is NULL, then the symbol is no
3254 longer needed, and in theory the GOT entry is redundant. But
3255 it is too late to change our minds now... */
3256 value += sec->output_section->vma + sec->output_offset;
3258 microblaze_elf_output_dynamic_relocation (output_bfd,
3259 srela, srela->reloc_count++,
3260 /* symindex= */ 0,
3261 R_MICROBLAZE_REL, offset,
3262 value);
3264 else
3266 microblaze_elf_output_dynamic_relocation (output_bfd,
3267 srela, srela->reloc_count++,
3268 h->dynindx,
3269 R_MICROBLAZE_GLOB_DAT,
3270 offset, 0);
3273 bfd_put_32 (output_bfd, (bfd_vma) 0,
3274 sgot->contents + (h->got.offset &~ (bfd_vma) 1));
3277 if (h->needs_copy)
3279 asection *s;
3280 Elf_Internal_Rela rela;
3281 bfd_byte *loc;
3283 /* This symbols needs a copy reloc. Set it up. */
3285 BFD_ASSERT (h->dynindx != -1);
3287 rela.r_offset = (h->root.u.def.value
3288 + h->root.u.def.section->output_section->vma
3289 + h->root.u.def.section->output_offset);
3290 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_COPY);
3291 rela.r_addend = 0;
3292 if (h->root.u.def.section == htab->elf.sdynrelro)
3293 s = htab->elf.sreldynrelro;
3294 else
3295 s = htab->elf.srelbss;
3296 loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
3297 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
3300 /* Mark some specially defined symbols as absolute. */
3301 if (h == htab->elf.hdynamic
3302 || h == htab->elf.hgot
3303 || h == htab->elf.hplt)
3304 sym->st_shndx = SHN_ABS;
3306 return true;
3310 /* Finish up the dynamic sections. */
3312 static bool
3313 microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
3314 struct bfd_link_info *info)
3316 bfd *dynobj;
3317 asection *sdyn, *sgot;
3318 struct elf32_mb_link_hash_table *htab;
3320 htab = elf32_mb_hash_table (info);
3321 if (htab == NULL)
3322 return false;
3324 dynobj = htab->elf.dynobj;
3326 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
3328 if (htab->elf.dynamic_sections_created)
3330 asection *splt;
3331 Elf32_External_Dyn *dyncon, *dynconend;
3333 dyncon = (Elf32_External_Dyn *) sdyn->contents;
3334 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
3335 for (; dyncon < dynconend; dyncon++)
3337 Elf_Internal_Dyn dyn;
3338 asection *s;
3339 bool size;
3341 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
3343 switch (dyn.d_tag)
3345 case DT_PLTGOT:
3346 s = htab->elf.sgotplt;
3347 size = false;
3348 break;
3350 case DT_PLTRELSZ:
3351 s = htab->elf.srelplt;
3352 size = true;
3353 break;
3355 case DT_JMPREL:
3356 s = htab->elf.srelplt;
3357 size = false;
3358 break;
3360 default:
3361 continue;
3364 if (s == NULL)
3365 dyn.d_un.d_val = 0;
3366 else
3368 if (!size)
3369 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
3370 else
3371 dyn.d_un.d_val = s->size;
3373 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
3376 splt = htab->elf.splt;
3377 BFD_ASSERT (splt != NULL && sdyn != NULL);
3379 /* Clear the first entry in the procedure linkage table,
3380 and put a nop in the last four bytes. */
3381 if (splt->size > 0)
3383 memset (splt->contents, 0, PLT_ENTRY_SIZE);
3384 bfd_put_32 (output_bfd, (bfd_vma) 0x80000000 /* nop. */,
3385 splt->contents + splt->size - 4);
3387 if (splt->output_section != bfd_abs_section_ptr)
3388 elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
3392 /* Set the first entry in the global offset table to the address of
3393 the dynamic section. */
3394 sgot = htab->elf.sgotplt;
3395 if (sgot && sgot->size > 0)
3397 if (sdyn == NULL)
3398 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
3399 else
3400 bfd_put_32 (output_bfd,
3401 sdyn->output_section->vma + sdyn->output_offset,
3402 sgot->contents);
3403 elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
3406 if (htab->elf.sgot && htab->elf.sgot->size > 0)
3407 elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4;
3409 return true;
3412 /* Hook called by the linker routine which adds symbols from an object
3413 file. We use it to put .comm items in .sbss, and not .bss. */
3415 static bool
3416 microblaze_elf_add_symbol_hook (bfd *abfd,
3417 struct bfd_link_info *info,
3418 Elf_Internal_Sym *sym,
3419 const char **namep ATTRIBUTE_UNUSED,
3420 flagword *flagsp ATTRIBUTE_UNUSED,
3421 asection **secp,
3422 bfd_vma *valp)
3424 if (sym->st_shndx == SHN_COMMON
3425 && !bfd_link_relocatable (info)
3426 && sym->st_size <= elf_gp_size (abfd))
3428 /* Common symbols less than or equal to -G nn bytes are automatically
3429 put into .sbss. */
3430 *secp = bfd_make_section_old_way (abfd, ".sbss");
3431 if (*secp == NULL
3432 || !bfd_set_section_flags (*secp, SEC_IS_COMMON | SEC_SMALL_DATA))
3433 return false;
3435 *valp = sym->st_size;
3438 return true;
3441 #define TARGET_LITTLE_SYM microblaze_elf32_le_vec
3442 #define TARGET_LITTLE_NAME "elf32-microblazeel"
3444 #define TARGET_BIG_SYM microblaze_elf32_vec
3445 #define TARGET_BIG_NAME "elf32-microblaze"
3447 #define ELF_ARCH bfd_arch_microblaze
3448 #define ELF_TARGET_ID MICROBLAZE_ELF_DATA
3449 #define ELF_MACHINE_CODE EM_MICROBLAZE
3450 #define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
3451 #define ELF_MAXPAGESIZE 0x1000
3452 #define elf_info_to_howto microblaze_elf_info_to_howto
3453 #define elf_info_to_howto_rel NULL
3455 #define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
3456 #define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name
3457 #define bfd_elf32_new_section_hook microblaze_elf_new_section_hook
3458 #define elf_backend_relocate_section microblaze_elf_relocate_section
3459 #define bfd_elf32_bfd_relax_section microblaze_elf_relax_section
3460 #define bfd_elf32_bfd_merge_private_bfd_data _bfd_generic_verify_endian_match
3461 #define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
3463 #define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
3464 #define elf_backend_check_relocs microblaze_elf_check_relocs
3465 #define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
3466 #define bfd_elf32_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
3467 #define elf_backend_can_gc_sections 1
3468 #define elf_backend_can_refcount 1
3469 #define elf_backend_want_got_plt 1
3470 #define elf_backend_plt_readonly 1
3471 #define elf_backend_got_header_size 12
3472 #define elf_backend_want_dynrelro 1
3473 #define elf_backend_rela_normal 1
3474 #define elf_backend_dtrel_excludes_plt 1
3476 #define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
3477 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
3478 #define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
3479 #define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
3480 #define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
3481 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
3483 #include "elf32-target.h"