Add markers for bihnutils 2.44 branch
[binutils-gdb.git] / bfd / elf32-microblaze.c
blob4d36577b0fda2aa27cf1bb698127bad63b377350
1 /* Xilinx MicroBlaze-specific support for 32-bit ELF
3 Copyright (C) 2009-2025 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 Boston, MA 02110-1301, USA. */
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_32_NONE, /* Type. */
179 0, /* Rightshift. */
180 2, /* Size (0 = byte, 1 = short, 2 = long). */
181 32, /* Bitsize. */
182 true, /* PC_relative. */
183 0, /* Bitpos. */
184 complain_overflow_bitfield, /* Complain on overflow. */
185 NULL, /* Special Function. */
186 "R_MICROBLAZE_32_NONE", /* Name. */
187 false, /* Partial Inplace. */
188 0, /* Source Mask. */
189 0, /* Dest Mask. */
190 false), /* PC relative offset? */
192 /* This reloc does nothing. Used for relaxation. */
193 HOWTO (R_MICROBLAZE_64_NONE, /* Type. */
194 0, /* Rightshift. */
195 0, /* Size. */
196 0, /* Bitsize. */
197 true, /* PC_relative. */
198 0, /* Bitpos. */
199 complain_overflow_dont, /* Complain on overflow. */
200 NULL, /* Special Function. */
201 "R_MICROBLAZE_64_NONE",/* Name. */
202 false, /* Partial Inplace. */
203 0, /* Source Mask. */
204 0, /* Dest Mask. */
205 false), /* PC relative offset? */
207 /* Symbol Op Symbol relocation. */
208 HOWTO (R_MICROBLAZE_32_SYM_OP_SYM, /* Type. */
209 0, /* Rightshift. */
210 4, /* Size. */
211 32, /* Bitsize. */
212 false, /* PC_relative. */
213 0, /* Bitpos. */
214 complain_overflow_bitfield, /* Complain on overflow. */
215 bfd_elf_generic_reloc,/* Special Function. */
216 "R_MICROBLAZE_32_SYM_OP_SYM", /* Name. */
217 false, /* Partial Inplace. */
218 0, /* Source Mask. */
219 0xffffffff, /* Dest Mask. */
220 false), /* PC relative offset? */
222 /* GNU extension to record C++ vtable hierarchy. */
223 HOWTO (R_MICROBLAZE_GNU_VTINHERIT, /* Type. */
224 0, /* Rightshift. */
225 4, /* Size. */
226 0, /* Bitsize. */
227 false, /* PC_relative. */
228 0, /* Bitpos. */
229 complain_overflow_dont,/* Complain on overflow. */
230 NULL, /* Special Function. */
231 "R_MICROBLAZE_GNU_VTINHERIT", /* Name. */
232 false, /* Partial Inplace. */
233 0, /* Source Mask. */
234 0, /* Dest Mask. */
235 false), /* PC relative offset? */
237 /* GNU extension to record C++ vtable member usage. */
238 HOWTO (R_MICROBLAZE_GNU_VTENTRY, /* Type. */
239 0, /* Rightshift. */
240 4, /* Size. */
241 0, /* Bitsize. */
242 false, /* PC_relative. */
243 0, /* Bitpos. */
244 complain_overflow_dont,/* Complain on overflow. */
245 _bfd_elf_rel_vtable_reloc_fn, /* Special Function. */
246 "R_MICROBLAZE_GNU_VTENTRY", /* Name. */
247 false, /* Partial Inplace. */
248 0, /* Source Mask. */
249 0, /* Dest Mask. */
250 false), /* PC relative offset? */
252 /* A 64 bit GOTPC relocation. Table-entry not really used. */
253 HOWTO (R_MICROBLAZE_GOTPC_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_GOTPC_64", /* Name. */
262 false, /* Partial Inplace. */
263 0, /* Source Mask. */
264 0x0000ffff, /* Dest Mask. */
265 true), /* PC relative offset? */
267 /* A 64 bit TEXTPCREL relocation. Table-entry not really used. */
268 HOWTO (R_MICROBLAZE_TEXTPCREL_64, /* Type. */
269 0, /* Rightshift. */
270 4, /* Size. */
271 16, /* Bitsize. */
272 true, /* PC_relative. */
273 0, /* Bitpos. */
274 complain_overflow_dont, /* Complain on overflow. */
275 bfd_elf_generic_reloc, /* Special Function. */
276 "R_MICROBLAZE_TEXTPCREL_64", /* Name. */
277 false, /* Partial Inplace. */
278 0, /* Source Mask. */
279 0x0000ffff, /* Dest Mask. */
280 true), /* PC relative offset? */
282 /* A 64 bit GOT relocation. Table-entry not really used. */
283 HOWTO (R_MICROBLAZE_GOT_64, /* Type. */
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_GOT_64",/* Name. */
292 false, /* Partial Inplace. */
293 0, /* Source Mask. */
294 0x0000ffff, /* Dest Mask. */
295 false), /* PC relative offset? */
297 /* A 64 bit TEXTREL relocation. Table-entry not really used. */
298 HOWTO (R_MICROBLAZE_TEXTREL_64, /* Type. */
299 0, /* Rightshift. */
300 4, /* Size. */
301 16, /* Bitsize. */
302 false, /* PC_relative. */
303 0, /* Bitpos. */
304 complain_overflow_dont, /* Complain on overflow. */
305 bfd_elf_generic_reloc,/* Special Function. */
306 "R_MICROBLAZE_TEXTREL_64",/* Name. */
307 false, /* Partial Inplace. */
308 0, /* Source Mask. */
309 0x0000ffff, /* Dest Mask. */
310 false), /* PC relative offset? */
312 /* A 64 bit PLT relocation. Table-entry not really used. */
313 HOWTO (R_MICROBLAZE_PLT_64, /* Type. */
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_PLT_64",/* Name. */
322 false, /* Partial Inplace. */
323 0, /* Source Mask. */
324 0x0000ffff, /* Dest Mask. */
325 true), /* PC relative offset? */
327 /* Table-entry not really used. */
328 HOWTO (R_MICROBLAZE_REL, /* Type. */
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_REL", /* Name. */
337 false, /* Partial Inplace. */
338 0, /* Source Mask. */
339 0x0000ffff, /* Dest Mask. */
340 true), /* PC relative offset? */
342 /* Table-entry not really used. */
343 HOWTO (R_MICROBLAZE_JUMP_SLOT,/* Type. */
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_JUMP_SLOT", /* Name. */
352 false, /* Partial Inplace. */
353 0, /* Source Mask. */
354 0x0000ffff, /* Dest Mask. */
355 true), /* PC relative offset? */
357 /* Table-entry not really used. */
358 HOWTO (R_MICROBLAZE_GLOB_DAT,/* Type. */
359 0, /* Rightshift. */
360 4, /* Size. */
361 16, /* Bitsize. */
362 true, /* PC_relative. */
363 0, /* Bitpos. */
364 complain_overflow_dont, /* Complain on overflow. */
365 bfd_elf_generic_reloc,/* Special Function. */
366 "R_MICROBLAZE_GLOB_DAT", /* Name. */
367 false, /* Partial Inplace. */
368 0, /* Source Mask. */
369 0x0000ffff, /* Dest Mask. */
370 true), /* PC relative offset? */
372 /* A 64 bit GOT relative relocation. Table-entry not really used. */
373 HOWTO (R_MICROBLAZE_GOTOFF_64, /* Type. */
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_64", /* Name. */
382 false, /* Partial Inplace. */
383 0, /* Source Mask. */
384 0x0000ffff, /* Dest Mask. */
385 false), /* PC relative offset? */
387 /* A 32 bit GOT relative relocation. Table-entry not really used. */
388 HOWTO (R_MICROBLAZE_GOTOFF_32, /* Type. */
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_GOTOFF_32", /* Name. */
397 false, /* Partial Inplace. */
398 0, /* Source Mask. */
399 0x0000ffff, /* Dest Mask. */
400 false), /* PC relative offset? */
402 /* COPY relocation. Table-entry not really used. */
403 HOWTO (R_MICROBLAZE_COPY, /* Type. */
404 0, /* Rightshift. */
405 4, /* Size. */
406 16, /* 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_COPY", /* Name. */
412 false, /* Partial Inplace. */
413 0, /* Source Mask. */
414 0x0000ffff, /* Dest Mask. */
415 false), /* PC relative offset? */
417 /* Marker relocs for TLS. */
418 HOWTO (R_MICROBLAZE_TLS,
419 0, /* rightshift */
420 4, /* size */
421 32, /* bitsize */
422 false, /* pc_relative */
423 0, /* bitpos */
424 complain_overflow_dont, /* complain_on_overflow */
425 bfd_elf_generic_reloc, /* special_function */
426 "R_MICROBLAZE_TLS", /* name */
427 false, /* partial_inplace */
428 0, /* src_mask */
429 0x0000ffff, /* dst_mask */
430 false), /* pcrel_offset */
432 HOWTO (R_MICROBLAZE_TLSGD,
433 0, /* rightshift */
434 4, /* size */
435 32, /* bitsize */
436 false, /* pc_relative */
437 0, /* bitpos */
438 complain_overflow_dont, /* complain_on_overflow */
439 bfd_elf_generic_reloc, /* special_function */
440 "R_MICROBLAZE_TLSGD", /* name */
441 false, /* partial_inplace */
442 0, /* src_mask */
443 0x0000ffff, /* dst_mask */
444 false), /* pcrel_offset */
446 HOWTO (R_MICROBLAZE_TLSLD,
447 0, /* rightshift */
448 4, /* size */
449 32, /* bitsize */
450 false, /* pc_relative */
451 0, /* bitpos */
452 complain_overflow_dont, /* complain_on_overflow */
453 bfd_elf_generic_reloc, /* special_function */
454 "R_MICROBLAZE_TLSLD", /* name */
455 false, /* partial_inplace */
456 0, /* src_mask */
457 0x0000ffff, /* dst_mask */
458 false), /* pcrel_offset */
460 /* Computes the load module index of the load module that contains the
461 definition of its TLS sym. */
462 HOWTO (R_MICROBLAZE_TLSDTPMOD32,
463 0, /* rightshift */
464 4, /* size */
465 32, /* bitsize */
466 false, /* pc_relative */
467 0, /* bitpos */
468 complain_overflow_dont, /* complain_on_overflow */
469 bfd_elf_generic_reloc, /* special_function */
470 "R_MICROBLAZE_TLSDTPMOD32", /* name */
471 false, /* partial_inplace */
472 0, /* src_mask */
473 0x0000ffff, /* dst_mask */
474 false), /* pcrel_offset */
476 /* Computes a dtv-relative displacement, the difference between the value
477 of sym+add and the base address of the thread-local storage block that
478 contains the definition of sym, minus 0x8000. Used for initializing GOT */
479 HOWTO (R_MICROBLAZE_TLSDTPREL32,
480 0, /* rightshift */
481 4, /* size */
482 32, /* bitsize */
483 false, /* pc_relative */
484 0, /* bitpos */
485 complain_overflow_dont, /* complain_on_overflow */
486 bfd_elf_generic_reloc, /* special_function */
487 "R_MICROBLAZE_TLSDTPREL32", /* name */
488 false, /* partial_inplace */
489 0, /* src_mask */
490 0x0000ffff, /* dst_mask */
491 false), /* pcrel_offset */
493 /* Computes a dtv-relative displacement, the difference between the value
494 of sym+add and the base address of the thread-local storage block that
495 contains the definition of sym, minus 0x8000. */
496 HOWTO (R_MICROBLAZE_TLSDTPREL64,
497 0, /* rightshift */
498 4, /* size */
499 32, /* bitsize */
500 false, /* pc_relative */
501 0, /* bitpos */
502 complain_overflow_dont, /* complain_on_overflow */
503 bfd_elf_generic_reloc, /* special_function */
504 "R_MICROBLAZE_TLSDTPREL64", /* name */
505 false, /* partial_inplace */
506 0, /* src_mask */
507 0x0000ffff, /* dst_mask */
508 false), /* pcrel_offset */
510 /* Computes a tp-relative displacement, the difference between the value of
511 sym+add and the value of the thread pointer (r13). */
512 HOWTO (R_MICROBLAZE_TLSGOTTPREL32,
513 0, /* rightshift */
514 4, /* size */
515 32, /* bitsize */
516 false, /* pc_relative */
517 0, /* bitpos */
518 complain_overflow_dont, /* complain_on_overflow */
519 bfd_elf_generic_reloc, /* special_function */
520 "R_MICROBLAZE_TLSGOTTPREL32", /* name */
521 false, /* partial_inplace */
522 0, /* src_mask */
523 0x0000ffff, /* dst_mask */
524 false), /* pcrel_offset */
526 /* Computes a tp-relative displacement, the difference between the value of
527 sym+add and the value of the thread pointer (r13). */
528 HOWTO (R_MICROBLAZE_TLSTPREL32,
529 0, /* rightshift */
530 4, /* size */
531 32, /* bitsize */
532 false, /* pc_relative */
533 0, /* bitpos */
534 complain_overflow_dont, /* complain_on_overflow */
535 bfd_elf_generic_reloc, /* special_function */
536 "R_MICROBLAZE_TLSTPREL32", /* name */
537 false, /* partial_inplace */
538 0, /* src_mask */
539 0x0000ffff, /* dst_mask */
540 false), /* pcrel_offset */
544 #ifndef NUM_ELEM
545 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
546 #endif
548 /* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */
550 static void
551 microblaze_elf_howto_init (void)
553 unsigned int i;
555 for (i = NUM_ELEM (microblaze_elf_howto_raw); i--;)
557 unsigned int type;
559 type = microblaze_elf_howto_raw[i].type;
561 BFD_ASSERT (type < NUM_ELEM (microblaze_elf_howto_table));
563 microblaze_elf_howto_table [type] = & microblaze_elf_howto_raw [i];
567 static reloc_howto_type *
568 microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
569 bfd_reloc_code_real_type code)
571 enum elf_microblaze_reloc_type microblaze_reloc = R_MICROBLAZE_NONE;
573 switch (code)
575 case BFD_RELOC_NONE:
576 microblaze_reloc = R_MICROBLAZE_NONE;
577 break;
578 case BFD_RELOC_MICROBLAZE_32_NONE:
579 microblaze_reloc = R_MICROBLAZE_32_NONE;
580 break;
581 case BFD_RELOC_MICROBLAZE_64_NONE:
582 microblaze_reloc = R_MICROBLAZE_64_NONE;
583 break;
584 case BFD_RELOC_32:
585 microblaze_reloc = R_MICROBLAZE_32;
586 break;
587 /* RVA is treated the same as 32 */
588 case BFD_RELOC_RVA:
589 microblaze_reloc = R_MICROBLAZE_32;
590 break;
591 case BFD_RELOC_32_PCREL:
592 microblaze_reloc = R_MICROBLAZE_32_PCREL;
593 break;
594 case BFD_RELOC_64_PCREL:
595 microblaze_reloc = R_MICROBLAZE_64_PCREL;
596 break;
597 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
598 microblaze_reloc = R_MICROBLAZE_32_PCREL_LO;
599 break;
600 case BFD_RELOC_64:
601 microblaze_reloc = R_MICROBLAZE_64;
602 break;
603 case BFD_RELOC_MICROBLAZE_32_LO:
604 microblaze_reloc = R_MICROBLAZE_32_LO;
605 break;
606 case BFD_RELOC_MICROBLAZE_32_ROSDA:
607 microblaze_reloc = R_MICROBLAZE_SRO32;
608 break;
609 case BFD_RELOC_MICROBLAZE_32_RWSDA:
610 microblaze_reloc = R_MICROBLAZE_SRW32;
611 break;
612 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
613 microblaze_reloc = R_MICROBLAZE_32_SYM_OP_SYM;
614 break;
615 case BFD_RELOC_VTABLE_INHERIT:
616 microblaze_reloc = R_MICROBLAZE_GNU_VTINHERIT;
617 break;
618 case BFD_RELOC_VTABLE_ENTRY:
619 microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
620 break;
621 case BFD_RELOC_MICROBLAZE_64_GOTPC:
622 microblaze_reloc = R_MICROBLAZE_GOTPC_64;
623 break;
624 case BFD_RELOC_MICROBLAZE_64_GOT:
625 microblaze_reloc = R_MICROBLAZE_GOT_64;
626 break;
627 case BFD_RELOC_MICROBLAZE_64_TEXTPCREL:
628 microblaze_reloc = R_MICROBLAZE_TEXTPCREL_64;
629 break;
630 case BFD_RELOC_MICROBLAZE_64_TEXTREL:
631 microblaze_reloc = R_MICROBLAZE_TEXTREL_64;
632 break;
633 case BFD_RELOC_MICROBLAZE_64_PLT:
634 microblaze_reloc = R_MICROBLAZE_PLT_64;
635 break;
636 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
637 microblaze_reloc = R_MICROBLAZE_GOTOFF_64;
638 break;
639 case BFD_RELOC_MICROBLAZE_32_GOTOFF:
640 microblaze_reloc = R_MICROBLAZE_GOTOFF_32;
641 break;
642 case BFD_RELOC_MICROBLAZE_64_TLSGD:
643 microblaze_reloc = R_MICROBLAZE_TLSGD;
644 break;
645 case BFD_RELOC_MICROBLAZE_64_TLSLD:
646 microblaze_reloc = R_MICROBLAZE_TLSLD;
647 break;
648 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL:
649 microblaze_reloc = R_MICROBLAZE_TLSDTPREL32;
650 break;
651 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL:
652 microblaze_reloc = R_MICROBLAZE_TLSDTPREL64;
653 break;
654 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD:
655 microblaze_reloc = R_MICROBLAZE_TLSDTPMOD32;
656 break;
657 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL:
658 microblaze_reloc = R_MICROBLAZE_TLSGOTTPREL32;
659 break;
660 case BFD_RELOC_MICROBLAZE_64_TLSTPREL:
661 microblaze_reloc = R_MICROBLAZE_TLSTPREL32;
662 break;
663 case BFD_RELOC_MICROBLAZE_COPY:
664 microblaze_reloc = R_MICROBLAZE_COPY;
665 break;
666 default:
667 return (reloc_howto_type *) NULL;
670 if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
671 /* Initialize howto table if needed. */
672 microblaze_elf_howto_init ();
674 return microblaze_elf_howto_table [(int) microblaze_reloc];
677 static reloc_howto_type *
678 microblaze_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
679 const char *r_name)
681 unsigned int i;
683 for (i = 0; i < NUM_ELEM (microblaze_elf_howto_raw); i++)
684 if (microblaze_elf_howto_raw[i].name != NULL
685 && strcasecmp (microblaze_elf_howto_raw[i].name, r_name) == 0)
686 return &microblaze_elf_howto_raw[i];
688 return NULL;
691 /* Set the howto pointer for a RCE ELF reloc. */
693 static bool
694 microblaze_elf_info_to_howto (bfd * abfd,
695 arelent * cache_ptr,
696 Elf_Internal_Rela * dst)
698 unsigned int r_type;
700 if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
701 /* Initialize howto table if needed. */
702 microblaze_elf_howto_init ();
704 r_type = ELF32_R_TYPE (dst->r_info);
705 if (r_type >= R_MICROBLAZE_max)
707 /* xgettext:c-format */
708 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
709 abfd, r_type);
710 bfd_set_error (bfd_error_bad_value);
711 return false;
714 cache_ptr->howto = microblaze_elf_howto_table [r_type];
715 return true;
718 /* Relax table contains information about instructions which can
719 be removed by relaxation -- replacing a long address with a
720 short address. */
721 struct relax_table
723 /* Address where bytes may be deleted. */
724 bfd_vma addr;
726 /* Number of bytes to be deleted. */
727 size_t size;
730 struct _microblaze_elf_section_data
732 struct bfd_elf_section_data elf;
733 /* Count of used relaxation table entries. */
734 size_t relax_count;
735 /* Relaxation table. */
736 struct relax_table *relax;
739 #define microblaze_elf_section_data(sec) \
740 ((struct _microblaze_elf_section_data *) elf_section_data (sec))
742 static bool
743 microblaze_elf_new_section_hook (bfd *abfd, asection *sec)
745 struct _microblaze_elf_section_data *sdata;
747 sdata = bfd_zalloc (abfd, sizeof (*sdata));
748 if (sdata == NULL)
749 return false;
750 sec->used_by_bfd = sdata;
752 return _bfd_elf_new_section_hook (abfd, sec);
755 /* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
757 static bool
758 microblaze_elf_is_local_label_name (bfd *abfd, const char *name)
760 if (name[0] == 'L' && name[1] == '.')
761 return true;
763 if (name[0] == '$' && name[1] == 'L')
764 return true;
766 /* With gcc, the labels go back to starting with '.', so we accept
767 the generic ELF local label syntax as well. */
768 return _bfd_elf_is_local_label_name (abfd, name);
771 /* ELF linker hash entry. */
773 struct elf32_mb_link_hash_entry
775 struct elf_link_hash_entry elf;
777 /* TLS Reference Types for the symbol; Updated by check_relocs */
778 #define TLS_GD 1 /* GD reloc. */
779 #define TLS_LD 2 /* LD reloc. */
780 #define TLS_TPREL 4 /* TPREL reloc, => IE. */
781 #define TLS_DTPREL 8 /* DTPREL reloc, => LD. */
782 #define TLS_TLS 16 /* Any TLS reloc. */
783 unsigned char tls_mask;
787 #define IS_TLS_GD(x) (x == (TLS_TLS | TLS_GD))
788 #define IS_TLS_LD(x) (x == (TLS_TLS | TLS_LD))
789 #define IS_TLS_DTPREL(x) (x == (TLS_TLS | TLS_DTPREL))
790 #define IS_TLS_NONE(x) (x == 0)
792 #define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent))
794 /* ELF linker hash table. */
796 struct elf32_mb_link_hash_table
798 struct elf_link_hash_table elf;
800 /* TLS Local Dynamic GOT Entry */
801 union {
802 bfd_signed_vma refcount;
803 bfd_vma offset;
804 } tlsld_got;
807 /* Nonzero if this section has TLS related relocations. */
808 #define has_tls_reloc sec_flg0
810 /* Get the ELF linker hash table from a link_info structure. */
812 #define elf32_mb_hash_table(p) \
813 ((is_elf_hash_table ((p)->hash) \
814 && elf_hash_table_id (elf_hash_table (p)) == MICROBLAZE_ELF_DATA) \
815 ? (struct elf32_mb_link_hash_table *) (p)->hash : NULL)
817 /* Create an entry in a microblaze ELF linker hash table. */
819 static struct bfd_hash_entry *
820 link_hash_newfunc (struct bfd_hash_entry *entry,
821 struct bfd_hash_table *table,
822 const char *string)
824 /* Allocate the structure if it has not already been allocated by a
825 subclass. */
826 if (entry == NULL)
828 entry = bfd_hash_allocate (table,
829 sizeof (struct elf32_mb_link_hash_entry));
830 if (entry == NULL)
831 return entry;
834 /* Call the allocation method of the superclass. */
835 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
836 if (entry != NULL)
838 struct elf32_mb_link_hash_entry *eh;
840 eh = (struct elf32_mb_link_hash_entry *) entry;
841 eh->tls_mask = 0;
844 return entry;
847 /* Create a mb ELF linker hash table. */
849 static struct bfd_link_hash_table *
850 microblaze_elf_link_hash_table_create (bfd *abfd)
852 struct elf32_mb_link_hash_table *ret;
853 size_t amt = sizeof (struct elf32_mb_link_hash_table);
855 ret = (struct elf32_mb_link_hash_table *) bfd_zmalloc (amt);
856 if (ret == NULL)
857 return NULL;
859 if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
860 sizeof (struct elf32_mb_link_hash_entry)))
862 free (ret);
863 return NULL;
866 return &ret->elf.root;
869 /* Set the values of the small data pointers. */
871 static void
872 microblaze_elf_final_sdp (struct bfd_link_info *info)
874 struct bfd_link_hash_entry *h;
876 h = bfd_link_hash_lookup (info->hash, RO_SDA_ANCHOR_NAME, false, false, true);
877 if (h != (struct bfd_link_hash_entry *) NULL
878 && h->type == bfd_link_hash_defined)
879 ro_small_data_pointer = (h->u.def.value
880 + h->u.def.section->output_section->vma
881 + h->u.def.section->output_offset);
883 h = bfd_link_hash_lookup (info->hash, RW_SDA_ANCHOR_NAME, false, false, true);
884 if (h != (struct bfd_link_hash_entry *) NULL
885 && h->type == bfd_link_hash_defined)
886 rw_small_data_pointer = (h->u.def.value
887 + h->u.def.section->output_section->vma
888 + h->u.def.section->output_offset);
891 static bfd_vma
892 dtprel_base (struct bfd_link_info *info)
894 /* If tls_sec is NULL, we should have signalled an error already. */
895 if (elf_hash_table (info)->tls_sec == NULL)
896 return 0;
897 return elf_hash_table (info)->tls_sec->vma;
900 /* The size of the thread control block. */
901 #define TCB_SIZE 8
903 /* Output a simple dynamic relocation into SRELOC. */
905 static void
906 microblaze_elf_output_dynamic_relocation (bfd *output_bfd,
907 asection *sreloc,
908 unsigned long reloc_index,
909 unsigned long indx,
910 int r_type,
911 bfd_vma offset,
912 bfd_vma addend)
915 Elf_Internal_Rela rel;
917 rel.r_info = ELF32_R_INFO (indx, r_type);
918 rel.r_offset = offset;
919 rel.r_addend = addend;
921 bfd_elf32_swap_reloca_out (output_bfd, &rel,
922 (sreloc->contents + reloc_index * sizeof (Elf32_External_Rela)));
925 /* This code is taken from elf32-m32r.c
926 There is some attempt to make this function usable for many architectures,
927 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
928 if only to serve as a learning tool.
930 The RELOCATE_SECTION function is called by the new ELF backend linker
931 to handle the relocations for a section.
933 The relocs are always passed as Rela structures; if the section
934 actually uses Rel structures, the r_addend field will always be
935 zero.
937 This function is responsible for adjust the section contents as
938 necessary, and (if using Rela relocs and generating a
939 relocatable output file) adjusting the reloc addend as
940 necessary.
942 This function does not have to worry about setting the reloc
943 address or the reloc symbol index.
945 LOCAL_SYMS is a pointer to the swapped in local symbols.
947 LOCAL_SECTIONS is an array giving the section in the input file
948 corresponding to the st_shndx field of each local symbol.
950 The global hash table entry for the global symbols can be found
951 via elf_sym_hashes (input_bfd).
953 When generating relocatable output, this function must handle
954 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
955 going to be the section symbol corresponding to the output
956 section, which means that the addend must be adjusted
957 accordingly. */
959 static int
960 microblaze_elf_relocate_section (bfd *output_bfd,
961 struct bfd_link_info *info,
962 bfd *input_bfd,
963 asection *input_section,
964 bfd_byte *contents,
965 Elf_Internal_Rela *relocs,
966 Elf_Internal_Sym *local_syms,
967 asection **local_sections)
969 struct elf32_mb_link_hash_table *htab;
970 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
971 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
972 Elf_Internal_Rela *rel, *relend;
973 int endian = (bfd_little_endian (output_bfd)) ? 0 : 2;
974 /* Assume success. */
975 bool ret = true;
976 asection *sreloc;
977 bfd_vma *local_got_offsets;
978 unsigned int tls_type;
980 if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1])
981 microblaze_elf_howto_init ();
983 htab = elf32_mb_hash_table (info);
984 if (htab == NULL)
985 return false;
987 local_got_offsets = elf_local_got_offsets (input_bfd);
989 sreloc = elf_section_data (input_section)->sreloc;
991 rel = relocs;
992 relend = relocs + input_section->reloc_count;
993 for (; rel < relend; rel++)
995 int r_type;
996 reloc_howto_type *howto;
997 unsigned long r_symndx;
998 bfd_vma addend = rel->r_addend;
999 bfd_vma offset = rel->r_offset;
1000 struct elf_link_hash_entry *h;
1001 Elf_Internal_Sym *sym;
1002 asection *sec;
1003 const char *sym_name;
1004 bfd_reloc_status_type r = bfd_reloc_ok;
1005 const char *errmsg = NULL;
1006 bool unresolved_reloc = false;
1008 h = NULL;
1009 r_type = ELF32_R_TYPE (rel->r_info);
1010 tls_type = 0;
1012 if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max)
1014 /* xgettext:c-format */
1015 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
1016 input_bfd, (int) r_type);
1017 bfd_set_error (bfd_error_bad_value);
1018 ret = false;
1019 continue;
1022 howto = microblaze_elf_howto_table[r_type];
1023 r_symndx = ELF32_R_SYM (rel->r_info);
1025 if (bfd_link_relocatable (info))
1027 /* This is a relocatable link. We don't have to change
1028 anything, unless the reloc is against a section symbol,
1029 in which case we have to adjust according to where the
1030 section symbol winds up in the output section. */
1031 sec = NULL;
1032 if (r_symndx >= symtab_hdr->sh_info)
1033 /* External symbol. */
1034 continue;
1036 /* Local symbol. */
1037 sym = local_syms + r_symndx;
1038 sym_name = "<local symbol>";
1039 /* STT_SECTION: symbol is associated with a section. */
1040 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
1041 /* Symbol isn't associated with a section. Nothing to do. */
1042 continue;
1044 sec = local_sections[r_symndx];
1045 addend += sec->output_offset + sym->st_value;
1046 #ifndef USE_REL
1047 /* This can't be done for USE_REL because it doesn't mean anything
1048 and elf_link_input_bfd asserts this stays zero. */
1049 /* rel->r_addend = addend; */
1050 #endif
1052 #ifndef USE_REL
1053 /* Addends are stored with relocs. We're done. */
1054 continue;
1055 #else /* USE_REL */
1056 /* If partial_inplace, we need to store any additional addend
1057 back in the section. */
1058 if (!howto->partial_inplace)
1059 continue;
1060 /* ??? Here is a nice place to call a special_function like handler. */
1061 r = _bfd_relocate_contents (howto, input_bfd, addend,
1062 contents + offset);
1063 #endif /* USE_REL */
1065 else
1067 bfd_vma relocation;
1068 bool resolved_to_zero;
1070 /* This is a final link. */
1071 sym = NULL;
1072 sec = NULL;
1073 unresolved_reloc = false;
1075 if (r_symndx < symtab_hdr->sh_info)
1077 /* Local symbol. */
1078 sym = local_syms + r_symndx;
1079 sec = local_sections[r_symndx];
1080 if (sec == 0)
1081 continue;
1082 sym_name = "<local symbol>";
1083 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1084 /* r_addend may have changed if the reference section was
1085 a merge section. */
1086 addend = rel->r_addend;
1088 else
1090 /* External symbol. */
1091 bool warned ATTRIBUTE_UNUSED;
1092 bool ignored ATTRIBUTE_UNUSED;
1094 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1095 r_symndx, symtab_hdr, sym_hashes,
1096 h, sec, relocation,
1097 unresolved_reloc, warned, ignored);
1098 sym_name = h->root.root.string;
1101 /* Sanity check the address. */
1102 if (offset > bfd_get_section_limit (input_bfd, input_section))
1104 r = bfd_reloc_outofrange;
1105 goto check_reloc;
1108 resolved_to_zero = (h != NULL
1109 && UNDEFWEAK_NO_DYNAMIC_RELOC (info, h));
1111 switch ((int) r_type)
1113 case (int) R_MICROBLAZE_SRO32 :
1115 const char *name;
1117 /* Only relocate if the symbol is defined. */
1118 if (sec)
1120 name = bfd_section_name (sec);
1122 if (strcmp (name, ".sdata2") == 0
1123 || strcmp (name, ".sbss2") == 0)
1125 if (ro_small_data_pointer == 0)
1126 microblaze_elf_final_sdp (info);
1127 if (ro_small_data_pointer == 0)
1129 ret = false;
1130 r = bfd_reloc_undefined;
1131 goto check_reloc;
1134 /* At this point `relocation' contains the object's
1135 address. */
1136 relocation -= ro_small_data_pointer;
1137 /* Now it contains the offset from _SDA2_BASE_. */
1138 r = _bfd_final_link_relocate (howto, input_bfd,
1139 input_section,
1140 contents, offset,
1141 relocation, addend);
1143 else
1145 _bfd_error_handler
1146 /* xgettext:c-format */
1147 (_("%pB: the target (%s) of an %s relocation"
1148 " is in the wrong section (%pA)"),
1149 input_bfd,
1150 sym_name,
1151 microblaze_elf_howto_table[(int) r_type]->name,
1152 sec);
1153 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1154 ret = false;
1155 continue;
1159 break;
1161 case (int) R_MICROBLAZE_SRW32 :
1163 const char *name;
1165 /* Only relocate if the symbol is defined. */
1166 if (sec)
1168 name = bfd_section_name (sec);
1170 if (strcmp (name, ".sdata") == 0
1171 || strcmp (name, ".sbss") == 0)
1173 if (rw_small_data_pointer == 0)
1174 microblaze_elf_final_sdp (info);
1175 if (rw_small_data_pointer == 0)
1177 ret = false;
1178 r = bfd_reloc_undefined;
1179 goto check_reloc;
1182 /* At this point `relocation' contains the object's
1183 address. */
1184 relocation -= rw_small_data_pointer;
1185 /* Now it contains the offset from _SDA_BASE_. */
1186 r = _bfd_final_link_relocate (howto, input_bfd,
1187 input_section,
1188 contents, offset,
1189 relocation, addend);
1191 else
1193 _bfd_error_handler
1194 /* xgettext:c-format */
1195 (_("%pB: the target (%s) of an %s relocation"
1196 " is in the wrong section (%pA)"),
1197 input_bfd,
1198 sym_name,
1199 microblaze_elf_howto_table[(int) r_type]->name,
1200 sec);
1201 /*bfd_set_error (bfd_error_bad_value); ??? why? */
1202 ret = false;
1203 continue;
1207 break;
1209 case (int) R_MICROBLAZE_32_SYM_OP_SYM:
1210 break; /* Do nothing. */
1212 case (int) R_MICROBLAZE_GOTPC_64:
1213 relocation = (htab->elf.sgotplt->output_section->vma
1214 + htab->elf.sgotplt->output_offset);
1215 relocation -= (input_section->output_section->vma
1216 + input_section->output_offset
1217 + offset + INST_WORD_SIZE);
1218 relocation += addend;
1219 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1220 contents + offset + endian);
1221 bfd_put_16 (input_bfd, relocation & 0xffff,
1222 contents + offset + endian + INST_WORD_SIZE);
1223 break;
1225 case (int) R_MICROBLAZE_TEXTPCREL_64:
1226 relocation = input_section->output_section->vma;
1227 relocation -= (input_section->output_section->vma
1228 + input_section->output_offset
1229 + offset + INST_WORD_SIZE);
1230 relocation += addend;
1231 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1232 contents + offset + endian);
1233 bfd_put_16 (input_bfd, relocation & 0xffff,
1234 contents + offset + endian + INST_WORD_SIZE);
1235 break;
1237 case (int) R_MICROBLAZE_PLT_64:
1239 bfd_vma immediate;
1240 if (htab->elf.splt != NULL && h != NULL
1241 && h->plt.offset != (bfd_vma) -1)
1243 relocation = (htab->elf.splt->output_section->vma
1244 + htab->elf.splt->output_offset
1245 + h->plt.offset);
1246 unresolved_reloc = false;
1247 immediate = relocation - (input_section->output_section->vma
1248 + input_section->output_offset
1249 + offset + INST_WORD_SIZE);
1250 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
1251 contents + offset + endian);
1252 bfd_put_16 (input_bfd, immediate & 0xffff,
1253 contents + offset + endian + INST_WORD_SIZE);
1255 else
1257 relocation -= (input_section->output_section->vma
1258 + input_section->output_offset
1259 + offset + INST_WORD_SIZE);
1260 immediate = relocation;
1261 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
1262 contents + offset + endian);
1263 bfd_put_16 (input_bfd, immediate & 0xffff,
1264 contents + offset + endian + INST_WORD_SIZE);
1266 break;
1269 case (int) R_MICROBLAZE_TLSGD:
1270 tls_type = (TLS_TLS | TLS_GD);
1271 goto dogot;
1272 case (int) R_MICROBLAZE_TLSLD:
1273 tls_type = (TLS_TLS | TLS_LD);
1274 /* Fall through. */
1275 dogot:
1276 case (int) R_MICROBLAZE_GOT_64:
1278 bfd_vma *offp;
1279 bfd_vma off, off2;
1280 unsigned long indx;
1281 bfd_vma static_value;
1283 bool need_relocs = false;
1284 if (htab->elf.sgot == NULL)
1285 abort ();
1287 indx = 0;
1288 offp = NULL;
1290 /* 1. Identify GOT Offset;
1291 2. Compute Static Values
1292 3. Process Module Id, Process Offset
1293 4. Fixup Relocation with GOT offset value. */
1295 /* 1. Determine GOT Offset to use : TLS_LD, global, local */
1296 if (IS_TLS_LD (tls_type))
1297 offp = &htab->tlsld_got.offset;
1298 else if (h != NULL)
1300 if (htab->elf.sgotplt != NULL
1301 && h->got.offset != (bfd_vma) -1)
1302 offp = &h->got.offset;
1303 else
1304 abort ();
1306 else
1308 if (local_got_offsets == NULL)
1309 abort ();
1310 offp = &local_got_offsets[r_symndx];
1313 if (!offp)
1314 abort ();
1316 off = (*offp) & ~1;
1317 off2 = off;
1319 if (IS_TLS_LD(tls_type) || IS_TLS_GD(tls_type))
1320 off2 = off + 4;
1322 /* Symbol index to use for relocs */
1323 if (h != NULL)
1325 bool dyn =
1326 elf_hash_table (info)->dynamic_sections_created;
1328 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn,
1329 bfd_link_pic (info),
1331 && (!bfd_link_pic (info)
1332 || !SYMBOL_REFERENCES_LOCAL (info, h)))
1333 indx = h->dynindx;
1336 /* Need to generate relocs ? */
1337 if ((bfd_link_pic (info) || indx != 0)
1338 && (h == NULL
1339 || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1340 && !resolved_to_zero)
1341 || h->root.type != bfd_link_hash_undefweak))
1342 need_relocs = true;
1344 /* 2. Compute/Emit Static value of r-expression */
1345 static_value = relocation + addend;
1347 /* 3. Process module-id and offset */
1348 if (! ((*offp) & 1) )
1350 bfd_vma got_offset;
1352 got_offset = (htab->elf.sgot->output_section->vma
1353 + htab->elf.sgot->output_offset
1354 + off);
1356 /* Process module-id */
1357 if (IS_TLS_LD(tls_type))
1359 if (! bfd_link_pic (info))
1360 bfd_put_32 (output_bfd, 1,
1361 htab->elf.sgot->contents + off);
1362 else
1363 microblaze_elf_output_dynamic_relocation
1364 (output_bfd,
1365 htab->elf.srelgot,
1366 htab->elf.srelgot->reloc_count++,
1367 /* symindex= */ 0, R_MICROBLAZE_TLSDTPMOD32,
1368 got_offset, 0);
1370 else if (IS_TLS_GD(tls_type))
1372 if (! need_relocs)
1373 bfd_put_32 (output_bfd, 1,
1374 htab->elf.sgot->contents + off);
1375 else
1376 microblaze_elf_output_dynamic_relocation
1377 (output_bfd,
1378 htab->elf.srelgot,
1379 htab->elf.srelgot->reloc_count++,
1380 /* symindex= */ indx, R_MICROBLAZE_TLSDTPMOD32,
1381 got_offset, indx ? 0 : static_value);
1384 /* Process Offset */
1385 if (htab->elf.srelgot == NULL)
1386 abort ();
1388 got_offset = (htab->elf.sgot->output_section->vma
1389 + htab->elf.sgot->output_offset
1390 + off2);
1391 if (IS_TLS_LD(tls_type))
1393 /* For LD, offset should be 0 */
1394 *offp |= 1;
1395 bfd_put_32 (output_bfd, 0,
1396 htab->elf.sgot->contents + off2);
1398 else if (IS_TLS_GD(tls_type))
1400 *offp |= 1;
1401 static_value -= dtprel_base(info);
1402 if (need_relocs)
1403 microblaze_elf_output_dynamic_relocation
1404 (output_bfd,
1405 htab->elf.srelgot,
1406 htab->elf.srelgot->reloc_count++,
1407 /* symindex= */ indx, R_MICROBLAZE_TLSDTPREL32,
1408 got_offset, indx ? 0 : static_value);
1409 else
1410 bfd_put_32 (output_bfd, static_value,
1411 htab->elf.sgot->contents + off2);
1413 else
1415 bfd_put_32 (output_bfd, static_value,
1416 htab->elf.sgot->contents + off2);
1418 /* Relocs for dyn symbols generated by
1419 finish_dynamic_symbols */
1420 if (bfd_link_pic (info) && h == NULL)
1422 *offp |= 1;
1423 microblaze_elf_output_dynamic_relocation
1424 (output_bfd,
1425 htab->elf.srelgot,
1426 htab->elf.srelgot->reloc_count++,
1427 /* symindex= */ indx, R_MICROBLAZE_REL,
1428 got_offset, static_value);
1433 /* 4. Fixup Relocation with GOT offset value
1434 Compute relative address of GOT entry for applying
1435 the current relocation */
1436 relocation = htab->elf.sgot->output_section->vma
1437 + htab->elf.sgot->output_offset
1438 + off
1439 - htab->elf.sgotplt->output_section->vma
1440 - htab->elf.sgotplt->output_offset;
1442 /* Apply Current Relocation */
1443 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1444 contents + offset + endian);
1445 bfd_put_16 (input_bfd, relocation & 0xffff,
1446 contents + offset + endian + INST_WORD_SIZE);
1448 unresolved_reloc = false;
1449 break;
1452 case (int) R_MICROBLAZE_GOTOFF_64:
1454 bfd_vma immediate;
1455 unsigned short lo, high;
1456 relocation += addend;
1457 relocation -= (htab->elf.sgotplt->output_section->vma
1458 + htab->elf.sgotplt->output_offset);
1459 /* Write this value into correct location. */
1460 immediate = relocation;
1461 lo = immediate & 0x0000ffff;
1462 high = (immediate >> 16) & 0x0000ffff;
1463 bfd_put_16 (input_bfd, high, contents + offset + endian);
1464 bfd_put_16 (input_bfd, lo,
1465 contents + offset + INST_WORD_SIZE + endian);
1466 break;
1469 case (int) R_MICROBLAZE_GOTOFF_32:
1471 relocation += addend;
1472 relocation -= (htab->elf.sgotplt->output_section->vma
1473 + htab->elf.sgotplt->output_offset);
1474 /* Write this value into correct location. */
1475 bfd_put_32 (input_bfd, relocation, contents + offset);
1476 break;
1479 case (int) R_MICROBLAZE_TLSDTPREL64:
1480 relocation += addend;
1481 relocation -= dtprel_base(info);
1482 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1483 contents + offset + endian);
1484 bfd_put_16 (input_bfd, relocation & 0xffff,
1485 contents + offset + endian + INST_WORD_SIZE);
1486 break;
1487 case (int) R_MICROBLAZE_TEXTREL_64:
1488 case (int) R_MICROBLAZE_TEXTREL_32_LO:
1489 case (int) R_MICROBLAZE_64_PCREL :
1490 case (int) R_MICROBLAZE_64:
1491 case (int) R_MICROBLAZE_32:
1493 /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
1494 from removed linkonce sections, or sections discarded by
1495 a linker script. */
1496 if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
1498 relocation += addend;
1499 if (r_type == R_MICROBLAZE_32)
1500 bfd_put_32 (input_bfd, relocation, contents + offset);
1501 else
1503 if (r_type == R_MICROBLAZE_64_PCREL)
1504 relocation -= (input_section->output_section->vma
1505 + input_section->output_offset
1506 + offset + INST_WORD_SIZE);
1507 else if (r_type == R_MICROBLAZE_TEXTREL_64
1508 || r_type == R_MICROBLAZE_TEXTREL_32_LO)
1509 relocation -= input_section->output_section->vma;
1511 if (r_type == R_MICROBLAZE_TEXTREL_32_LO)
1512 bfd_put_16 (input_bfd, relocation & 0xffff,
1513 contents + offset + endian);
1515 else
1517 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1518 contents + offset + endian);
1519 bfd_put_16 (input_bfd, relocation & 0xffff,
1520 contents + offset + endian + INST_WORD_SIZE);
1523 break;
1526 if ((bfd_link_pic (info)
1527 && (h == NULL
1528 || (ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1529 && !resolved_to_zero)
1530 || h->root.type != bfd_link_hash_undefweak)
1531 && (!howto->pc_relative
1532 || (h != NULL
1533 && h->dynindx != -1
1534 && (!info->symbolic
1535 || !h->def_regular))))
1536 || (!bfd_link_pic (info)
1537 && h != NULL
1538 && h->dynindx != -1
1539 && !h->non_got_ref
1540 && ((h->def_dynamic
1541 && !h->def_regular)
1542 || h->root.type == bfd_link_hash_undefweak
1543 || h->root.type == bfd_link_hash_undefined)))
1545 Elf_Internal_Rela outrel;
1546 bfd_byte *loc;
1547 bool skip;
1549 /* When generating a shared object, these relocations
1550 are copied into the output file to be resolved at run
1551 time. */
1553 BFD_ASSERT (sreloc != NULL);
1555 skip = false;
1557 outrel.r_offset =
1558 _bfd_elf_section_offset (output_bfd, info, input_section,
1559 rel->r_offset);
1560 if (outrel.r_offset == (bfd_vma) -1)
1561 skip = true;
1562 else if (outrel.r_offset == (bfd_vma) -2)
1563 skip = true;
1564 outrel.r_offset += (input_section->output_section->vma
1565 + input_section->output_offset);
1567 if (skip)
1568 memset (&outrel, 0, sizeof outrel);
1569 /* h->dynindx may be -1 if the symbol was marked to
1570 become local. */
1571 else if (h != NULL
1572 && ((! info->symbolic && h->dynindx != -1)
1573 || !h->def_regular))
1575 BFD_ASSERT (h->dynindx != -1);
1576 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1577 outrel.r_addend = addend;
1579 else
1581 if (r_type == R_MICROBLAZE_32)
1583 outrel.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL);
1584 outrel.r_addend = relocation + addend;
1586 else
1588 BFD_FAIL ();
1589 _bfd_error_handler
1590 (_("%pB: probably compiled without -fPIC?"),
1591 input_bfd);
1592 bfd_set_error (bfd_error_bad_value);
1593 return false;
1597 loc = sreloc->contents;
1598 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
1599 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1600 break;
1602 else
1604 relocation += addend;
1605 if (r_type == R_MICROBLAZE_32)
1606 bfd_put_32 (input_bfd, relocation, contents + offset);
1607 else
1609 if (r_type == R_MICROBLAZE_64_PCREL)
1610 relocation -= (input_section->output_section->vma
1611 + input_section->output_offset
1612 + offset + INST_WORD_SIZE);
1613 else if (r_type == R_MICROBLAZE_TEXTREL_64
1614 || r_type == R_MICROBLAZE_TEXTREL_32_LO)
1615 relocation -= input_section->output_section->vma;
1617 if (r_type == R_MICROBLAZE_TEXTREL_32_LO)
1619 bfd_put_16 (input_bfd, relocation & 0xffff,
1620 contents + offset + endian);
1622 else
1624 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1625 contents + offset + endian);
1626 bfd_put_16 (input_bfd, relocation & 0xffff,
1627 contents + offset + endian
1628 + INST_WORD_SIZE);
1631 break;
1635 default :
1636 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1637 contents, offset,
1638 relocation, addend);
1639 break;
1643 check_reloc:
1645 if (r != bfd_reloc_ok)
1647 /* FIXME: This should be generic enough to go in a utility. */
1648 const char *name;
1650 if (h != NULL)
1651 name = h->root.root.string;
1652 else
1654 name = (bfd_elf_string_from_elf_section
1655 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1656 if (name == NULL || *name == '\0')
1657 name = bfd_section_name (sec);
1660 if (errmsg != NULL)
1661 goto common_error;
1663 switch (r)
1665 case bfd_reloc_overflow:
1666 (*info->callbacks->reloc_overflow)
1667 (info, (h ? &h->root : NULL), name, howto->name,
1668 (bfd_vma) 0, input_bfd, input_section, offset);
1669 break;
1671 case bfd_reloc_undefined:
1672 (*info->callbacks->undefined_symbol)
1673 (info, name, input_bfd, input_section, offset, true);
1674 break;
1676 case bfd_reloc_outofrange:
1677 errmsg = _("internal error: out of range error");
1678 goto common_error;
1680 case bfd_reloc_notsupported:
1681 errmsg = _("internal error: unsupported relocation error");
1682 goto common_error;
1684 case bfd_reloc_dangerous:
1685 errmsg = _("internal error: dangerous error");
1686 goto common_error;
1688 default:
1689 errmsg = _("internal error: unknown error");
1690 /* Fall through. */
1691 common_error:
1692 (*info->callbacks->warning) (info, errmsg, name, input_bfd,
1693 input_section, offset);
1694 break;
1699 return ret;
1702 /* Calculate fixup value for reference. */
1704 static size_t
1705 calc_fixup (bfd_vma start, bfd_vma size, asection *sec)
1707 bfd_vma end = start + size;
1708 size_t i, fixup = 0;
1709 struct _microblaze_elf_section_data *sdata;
1711 if (sec == NULL || (sdata = microblaze_elf_section_data (sec)) == NULL)
1712 return 0;
1714 /* Look for addr in relax table, total fixup value. */
1715 for (i = 0; i < sdata->relax_count; i++)
1717 if (end <= sdata->relax[i].addr)
1718 break;
1719 if (end != start && start > sdata->relax[i].addr)
1720 continue;
1721 fixup += sdata->relax[i].size;
1723 return fixup;
1726 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1727 a 32-bit instruction. */
1728 static void
1729 microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1731 unsigned long instr = bfd_get_32 (abfd, bfd_addr);
1732 instr &= ~0x0000ffff;
1733 instr |= (val & 0x0000ffff);
1734 bfd_put_32 (abfd, instr, bfd_addr);
1737 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1738 two consecutive 32-bit instructions. */
1739 static void
1740 microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1742 unsigned long instr_hi;
1743 unsigned long instr_lo;
1745 instr_hi = bfd_get_32 (abfd, bfd_addr);
1746 instr_hi &= ~0x0000ffff;
1747 instr_hi |= ((val >> 16) & 0x0000ffff);
1748 bfd_put_32 (abfd, instr_hi, bfd_addr);
1750 instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE);
1751 instr_lo &= ~0x0000ffff;
1752 instr_lo |= (val & 0x0000ffff);
1753 bfd_put_32 (abfd, instr_lo, bfd_addr + INST_WORD_SIZE);
1756 static bool
1757 microblaze_elf_relax_section (bfd *abfd,
1758 asection *sec,
1759 struct bfd_link_info *link_info,
1760 bool *again)
1762 Elf_Internal_Shdr *symtab_hdr;
1763 Elf_Internal_Rela *internal_relocs;
1764 Elf_Internal_Rela *free_relocs = NULL;
1765 Elf_Internal_Rela *irel, *irelend;
1766 bfd_byte *contents = NULL;
1767 bfd_byte *free_contents = NULL;
1768 int rel_count;
1769 unsigned int shndx;
1770 size_t i, sym_index;
1771 asection *o;
1772 struct elf_link_hash_entry *sym_hash;
1773 Elf_Internal_Sym *isymbuf, *isymend;
1774 Elf_Internal_Sym *isym;
1775 size_t symcount;
1776 size_t offset;
1777 bfd_vma src, dest;
1778 struct _microblaze_elf_section_data *sdata;
1780 /* We only do this once per section. We may be able to delete some code
1781 by running multiple passes, but it is not worth it. */
1782 *again = false;
1784 /* Only do this for a text section. */
1785 if (bfd_link_relocatable (link_info)
1786 || (sec->flags & SEC_RELOC) == 0
1787 || (sec->flags & SEC_CODE) == 0
1788 || sec->reloc_count == 0
1789 || (sdata = microblaze_elf_section_data (sec)) == NULL)
1790 return true;
1792 BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0));
1794 /* If this is the first time we have been called for this section,
1795 initialize the cooked size. */
1796 if (sec->size == 0)
1797 sec->size = sec->rawsize;
1799 /* Get symbols for this section. */
1800 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1801 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1802 symcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
1803 if (isymbuf == NULL)
1804 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount,
1805 0, NULL, NULL, NULL);
1806 BFD_ASSERT (isymbuf != NULL);
1808 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
1809 if (internal_relocs == NULL)
1810 goto error_return;
1811 if (! link_info->keep_memory)
1812 free_relocs = internal_relocs;
1814 sdata->relax_count = 0;
1815 sdata->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
1816 * sizeof (*sdata->relax));
1817 if (sdata->relax == NULL)
1818 goto error_return;
1820 irelend = internal_relocs + sec->reloc_count;
1821 rel_count = 0;
1822 for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1824 bfd_vma symval;
1825 if ((ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL)
1826 && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64)
1827 && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_TEXTREL_64))
1828 continue; /* Can't delete this reloc. */
1830 /* Get the section contents. */
1831 if (contents == NULL)
1833 if (elf_section_data (sec)->this_hdr.contents != NULL)
1834 contents = elf_section_data (sec)->this_hdr.contents;
1835 else
1837 contents = (bfd_byte *) bfd_malloc (sec->size);
1838 if (contents == NULL)
1839 goto error_return;
1840 free_contents = contents;
1842 if (!bfd_get_section_contents (abfd, sec, contents,
1843 (file_ptr) 0, sec->size))
1844 goto error_return;
1845 elf_section_data (sec)->this_hdr.contents = contents;
1849 /* Get the value of the symbol referred to by the reloc. */
1850 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1852 /* A local symbol. */
1853 asection *sym_sec;
1855 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1856 if (isym->st_shndx == SHN_UNDEF)
1857 sym_sec = bfd_und_section_ptr;
1858 else if (isym->st_shndx == SHN_ABS)
1859 sym_sec = bfd_abs_section_ptr;
1860 else if (isym->st_shndx == SHN_COMMON)
1861 sym_sec = bfd_com_section_ptr;
1862 else
1863 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1865 symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
1867 else
1869 unsigned long indx;
1870 struct elf_link_hash_entry *h;
1872 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1873 h = elf_sym_hashes (abfd)[indx];
1874 BFD_ASSERT (h != NULL);
1876 if (h->root.type != bfd_link_hash_defined
1877 && h->root.type != bfd_link_hash_defweak)
1878 /* This appears to be a reference to an undefined
1879 symbol. Just ignore it--it will be caught by the
1880 regular reloc processing. */
1881 continue;
1883 symval = (h->root.u.def.value
1884 + h->root.u.def.section->output_section->vma
1885 + h->root.u.def.section->output_offset);
1888 /* If this is a PC-relative reloc, subtract the instr offset from
1889 the symbol value. */
1890 if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_64_PCREL)
1892 symval = symval + irel->r_addend
1893 - (irel->r_offset
1894 + sec->output_section->vma
1895 + sec->output_offset);
1897 else if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_TEXTREL_64)
1899 symval = symval + irel->r_addend - (sec->output_section->vma);
1901 else
1902 symval += irel->r_addend;
1904 if ((symval & 0xffff8000) == 0
1905 || (symval & 0xffff8000) == 0xffff8000)
1907 /* We can delete this instruction. */
1908 sdata->relax[sdata->relax_count].addr = irel->r_offset;
1909 sdata->relax[sdata->relax_count].size = INST_WORD_SIZE;
1910 sdata->relax_count++;
1912 /* Rewrite relocation type. */
1913 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1915 case R_MICROBLAZE_64_PCREL:
1916 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1917 (int) R_MICROBLAZE_32_PCREL_LO);
1918 break;
1919 case R_MICROBLAZE_64:
1920 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1921 (int) R_MICROBLAZE_32_LO);
1922 break;
1923 case R_MICROBLAZE_TEXTREL_64:
1924 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1925 (int) R_MICROBLAZE_TEXTREL_32_LO);
1926 break;
1927 default:
1928 /* Cannot happen. */
1929 BFD_ASSERT (false);
1932 } /* Loop through all relocations. */
1934 /* Loop through the relocs again, and see if anything needs to change. */
1935 if (sdata->relax_count > 0)
1937 shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1938 rel_count = 0;
1939 sdata->relax[sdata->relax_count].addr = sec->size;
1941 for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1943 bfd_vma nraddr;
1945 /* Get the new reloc address. */
1946 nraddr = irel->r_offset - calc_fixup (irel->r_offset, 0, sec);
1947 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1949 default:
1950 break;
1951 case R_MICROBLAZE_64_PCREL:
1952 break;
1953 case R_MICROBLAZE_TEXTREL_64:
1954 case R_MICROBLAZE_TEXTREL_32_LO:
1955 case R_MICROBLAZE_64:
1956 case R_MICROBLAZE_32_LO:
1957 /* If this reloc is against a symbol defined in this
1958 section, we must check the addend to see it will put the value in
1959 range to be adjusted, and hence must be changed. */
1960 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1962 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1963 /* Only handle relocs against .text. */
1964 if (isym->st_shndx == shndx
1965 && ELF32_ST_TYPE (isym->st_info) == STT_SECTION)
1966 irel->r_addend -= calc_fixup (irel->r_addend, 0, sec);
1968 break;
1969 case R_MICROBLAZE_NONE:
1970 case R_MICROBLAZE_32_NONE:
1972 /* This was a PC-relative instruction that was
1973 completely resolved. */
1974 size_t sfix, efix;
1975 bfd_vma target_address;
1976 target_address = irel->r_addend + irel->r_offset;
1977 sfix = calc_fixup (irel->r_offset, 0, sec);
1978 efix = calc_fixup (target_address, 0, sec);
1979 irel->r_addend -= (efix - sfix);
1980 /* Should use HOWTO. */
1981 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
1982 irel->r_addend);
1984 break;
1985 case R_MICROBLAZE_64_NONE:
1987 /* This was a PC-relative 64-bit instruction that was
1988 completely resolved. */
1989 size_t sfix, efix;
1990 bfd_vma target_address;
1991 target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE;
1992 sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, 0, sec);
1993 efix = calc_fixup (target_address, 0, sec);
1994 irel->r_addend -= (efix - sfix);
1995 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset
1996 + INST_WORD_SIZE, irel->r_addend);
1998 break;
2000 irel->r_offset = nraddr;
2001 } /* Change all relocs in this section. */
2003 /* Look through all other sections. */
2004 for (o = abfd->sections; o != NULL; o = o->next)
2006 Elf_Internal_Rela *irelocs;
2007 Elf_Internal_Rela *irelscan, *irelscanend;
2008 bfd_byte *ocontents;
2010 if (o == sec
2011 || (o->flags & SEC_RELOC) == 0
2012 || o->reloc_count == 0)
2013 continue;
2015 /* We always cache the relocs. Perhaps, if info->keep_memory is
2016 FALSE, we should free them, if we are permitted to. */
2018 irelocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, true);
2019 if (irelocs == NULL)
2020 goto error_return;
2022 ocontents = NULL;
2023 irelscanend = irelocs + o->reloc_count;
2024 for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
2026 if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
2027 || (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_NONE))
2029 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2031 /* Look at the reloc only if the value has been resolved. */
2032 if (isym->st_shndx == shndx
2033 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2035 if (ocontents == NULL)
2037 if (elf_section_data (o)->this_hdr.contents != NULL)
2038 ocontents = elf_section_data (o)->this_hdr.contents;
2039 else
2041 /* We always cache the section contents.
2042 Perhaps, if info->keep_memory is FALSE, we
2043 should free them, if we are permitted to. */
2044 if (o->rawsize == 0)
2045 o->rawsize = o->size;
2046 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2047 if (ocontents == NULL)
2048 goto error_return;
2049 if (!bfd_get_section_contents (abfd, o, ocontents,
2050 (file_ptr) 0,
2051 o->rawsize))
2052 goto error_return;
2053 elf_section_data (o)->this_hdr.contents = ocontents;
2057 irelscan->r_addend -= calc_fixup (irelscan->r_addend, 0, sec);
2059 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
2061 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2063 /* Look at the reloc only if the value has been resolved. */
2064 if (ocontents == NULL)
2066 if (elf_section_data (o)->this_hdr.contents != NULL)
2067 ocontents = elf_section_data (o)->this_hdr.contents;
2068 else
2070 /* We always cache the section contents.
2071 Perhaps, if info->keep_memory is FALSE, we
2072 should free them, if we are permitted to. */
2074 if (o->rawsize == 0)
2075 o->rawsize = o->size;
2076 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2077 if (ocontents == NULL)
2078 goto error_return;
2079 if (!bfd_get_section_contents (abfd, o, ocontents,
2080 (file_ptr) 0,
2081 o->rawsize))
2082 goto error_return;
2083 elf_section_data (o)->this_hdr.contents = ocontents;
2086 irelscan->r_addend -= calc_fixup (irelscan->r_addend
2087 + isym->st_value,
2089 sec);
2092 else if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO)
2093 || (ELF32_R_TYPE (irelscan->r_info)
2094 == (int) R_MICROBLAZE_32_LO)
2095 || (ELF32_R_TYPE (irelscan->r_info)
2096 == (int) R_MICROBLAZE_TEXTREL_32_LO))
2098 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2100 /* Look at the reloc only if the value has been resolved. */
2101 if (isym->st_shndx == shndx
2102 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2104 bfd_vma immediate;
2105 bfd_vma target_address;
2107 if (ocontents == NULL)
2109 if (elf_section_data (o)->this_hdr.contents != NULL)
2110 ocontents = elf_section_data (o)->this_hdr.contents;
2111 else
2113 /* We always cache the section contents.
2114 Perhaps, if info->keep_memory is FALSE, we
2115 should free them, if we are permitted to. */
2116 if (o->rawsize == 0)
2117 o->rawsize = o->size;
2118 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2119 if (ocontents == NULL)
2120 goto error_return;
2121 if (!bfd_get_section_contents (abfd, o, ocontents,
2122 (file_ptr) 0,
2123 o->rawsize))
2124 goto error_return;
2125 elf_section_data (o)->this_hdr.contents = ocontents;
2129 unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
2130 immediate = instr & 0x0000ffff;
2131 target_address = immediate;
2132 offset = calc_fixup (target_address, 0, sec);
2133 immediate -= offset;
2134 irelscan->r_addend -= offset;
2135 microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
2136 irelscan->r_addend);
2140 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64
2141 || (ELF32_R_TYPE (irelscan->r_info)
2142 == (int) R_MICROBLAZE_TEXTREL_64))
2144 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2146 /* Look at the reloc only if the value has been resolved. */
2147 if (isym->st_shndx == shndx
2148 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2150 if (ocontents == NULL)
2152 if (elf_section_data (o)->this_hdr.contents != NULL)
2153 ocontents = elf_section_data (o)->this_hdr.contents;
2154 else
2156 /* We always cache the section contents.
2157 Perhaps, if info->keep_memory is FALSE, we
2158 should free them, if we are permitted to. */
2160 if (o->rawsize == 0)
2161 o->rawsize = o->size;
2162 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2163 if (ocontents == NULL)
2164 goto error_return;
2165 if (!bfd_get_section_contents (abfd, o, ocontents,
2166 (file_ptr) 0,
2167 o->rawsize))
2168 goto error_return;
2169 elf_section_data (o)->this_hdr.contents = ocontents;
2172 offset = calc_fixup (irelscan->r_addend, 0, sec);
2173 irelscan->r_addend -= offset;
2176 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
2178 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
2180 /* Look at the reloc only if the value has been resolved. */
2181 if (isym->st_shndx == shndx
2182 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
2184 bfd_vma immediate;
2185 bfd_vma target_address;
2187 if (ocontents == NULL)
2189 if (elf_section_data (o)->this_hdr.contents != NULL)
2190 ocontents = elf_section_data (o)->this_hdr.contents;
2191 else
2193 /* We always cache the section contents.
2194 Perhaps, if info->keep_memory is FALSE, we
2195 should free them, if we are permitted to. */
2196 if (o->rawsize == 0)
2197 o->rawsize = o->size;
2198 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
2199 if (ocontents == NULL)
2200 goto error_return;
2201 if (!bfd_get_section_contents (abfd, o, ocontents,
2202 (file_ptr) 0,
2203 o->rawsize))
2204 goto error_return;
2205 elf_section_data (o)->this_hdr.contents = ocontents;
2208 unsigned long instr_hi = bfd_get_32 (abfd, ocontents
2209 + irelscan->r_offset);
2210 unsigned long instr_lo = bfd_get_32 (abfd, ocontents
2211 + irelscan->r_offset
2212 + INST_WORD_SIZE);
2213 immediate = (instr_hi & 0x0000ffff) << 16;
2214 immediate |= (instr_lo & 0x0000ffff);
2215 target_address = immediate;
2216 offset = calc_fixup (target_address, 0, sec);
2217 immediate -= offset;
2218 irelscan->r_addend -= offset;
2219 microblaze_bfd_write_imm_value_64 (abfd, ocontents
2220 + irelscan->r_offset, immediate);
2226 /* Adjust the local symbols defined in this section. */
2227 isymend = isymbuf + symtab_hdr->sh_info;
2228 for (isym = isymbuf; isym < isymend; isym++)
2230 if (isym->st_shndx == shndx)
2232 isym->st_value -= calc_fixup (isym->st_value, 0, sec);
2233 if (isym->st_size)
2234 isym->st_size -= calc_fixup (isym->st_value, isym->st_size, sec);
2238 /* Now adjust the global symbols defined in this section. */
2239 isym = isymbuf + symtab_hdr->sh_info;
2240 symcount = (symtab_hdr->sh_size / sizeof (Elf32_External_Sym)) - symtab_hdr->sh_info;
2241 for (sym_index = 0; sym_index < symcount; sym_index++)
2243 sym_hash = elf_sym_hashes (abfd)[sym_index];
2244 if ((sym_hash->root.type == bfd_link_hash_defined
2245 || sym_hash->root.type == bfd_link_hash_defweak)
2246 && sym_hash->root.u.def.section == sec)
2248 sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value,
2249 0, sec);
2250 if (sym_hash->size)
2251 sym_hash->size -= calc_fixup (sym_hash->root.u.def.value,
2252 sym_hash->size, sec);
2256 /* Physically move the code and change the cooked size. */
2257 dest = sdata->relax[0].addr;
2258 for (i = 0; i < sdata->relax_count; i++)
2260 size_t len;
2261 src = sdata->relax[i].addr + sdata->relax[i].size;
2262 len = (sdata->relax[i+1].addr - sdata->relax[i].addr
2263 - sdata->relax[i].size);
2265 memmove (contents + dest, contents + src, len);
2266 sec->size -= sdata->relax[i].size;
2267 dest += len;
2270 elf_section_data (sec)->relocs = internal_relocs;
2271 free_relocs = NULL;
2273 elf_section_data (sec)->this_hdr.contents = contents;
2274 free_contents = NULL;
2276 symtab_hdr->contents = (bfd_byte *) isymbuf;
2279 free (free_relocs);
2280 free_relocs = NULL;
2282 if (free_contents != NULL)
2284 if (!link_info->keep_memory)
2285 free (free_contents);
2286 else
2287 /* Cache the section contents for elf_link_input_bfd. */
2288 elf_section_data (sec)->this_hdr.contents = contents;
2289 free_contents = NULL;
2292 if (sdata->relax_count == 0)
2294 *again = false;
2295 free (sdata->relax);
2296 sdata->relax = NULL;
2298 else
2299 *again = true;
2300 return true;
2302 error_return:
2303 free (free_relocs);
2304 free (free_contents);
2305 free (sdata->relax);
2306 sdata->relax = NULL;
2307 sdata->relax_count = 0;
2308 return false;
2311 /* Return the section that should be marked against GC for a given
2312 relocation. */
2314 static asection *
2315 microblaze_elf_gc_mark_hook (asection *sec,
2316 struct bfd_link_info * info,
2317 Elf_Internal_Rela * rel,
2318 struct elf_link_hash_entry * h,
2319 Elf_Internal_Sym * sym)
2321 if (h != NULL)
2322 switch (ELF32_R_TYPE (rel->r_info))
2324 case R_MICROBLAZE_GNU_VTINHERIT:
2325 case R_MICROBLAZE_GNU_VTENTRY:
2326 return NULL;
2329 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
2332 /* PIC support. */
2334 #define PLT_ENTRY_SIZE 16
2336 #define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
2337 #define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
2338 #define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
2339 #define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
2340 #define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
2342 static bool
2343 update_local_sym_info (bfd *abfd,
2344 Elf_Internal_Shdr *symtab_hdr,
2345 unsigned long r_symndx,
2346 unsigned int tls_type)
2348 bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
2349 unsigned char *local_got_tls_masks;
2351 if (local_got_refcounts == NULL)
2353 bfd_size_type size = symtab_hdr->sh_info;
2355 size *= (sizeof (*local_got_refcounts) + sizeof (*local_got_tls_masks));
2356 local_got_refcounts = bfd_zalloc (abfd, size);
2357 if (local_got_refcounts == NULL)
2358 return false;
2359 elf_local_got_refcounts (abfd) = local_got_refcounts;
2362 local_got_tls_masks =
2363 (unsigned char *) (local_got_refcounts + symtab_hdr->sh_info);
2364 local_got_tls_masks[r_symndx] |= tls_type;
2365 local_got_refcounts[r_symndx] += 1;
2367 return true;
2369 /* Look through the relocs for a section during the first phase. */
2371 static bool
2372 microblaze_elf_check_relocs (bfd * abfd,
2373 struct bfd_link_info * info,
2374 asection * sec,
2375 const Elf_Internal_Rela * relocs)
2377 Elf_Internal_Shdr * symtab_hdr;
2378 struct elf_link_hash_entry ** sym_hashes;
2379 const Elf_Internal_Rela * rel;
2380 const Elf_Internal_Rela * rel_end;
2381 struct elf32_mb_link_hash_table *htab;
2382 asection *sreloc = NULL;
2384 if (bfd_link_relocatable (info))
2385 return true;
2387 htab = elf32_mb_hash_table (info);
2388 if (htab == NULL)
2389 return false;
2391 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
2392 sym_hashes = elf_sym_hashes (abfd);
2394 rel_end = relocs + sec->reloc_count;
2396 for (rel = relocs; rel < rel_end; rel++)
2398 unsigned int r_type;
2399 struct elf_link_hash_entry * h;
2400 unsigned long r_symndx;
2401 unsigned char tls_type = 0;
2403 r_symndx = ELF32_R_SYM (rel->r_info);
2404 r_type = ELF32_R_TYPE (rel->r_info);
2406 if (r_symndx < symtab_hdr->sh_info)
2407 h = NULL;
2408 else
2410 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
2411 while (h->root.type == bfd_link_hash_indirect
2412 || h->root.type == bfd_link_hash_warning)
2413 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2416 switch (r_type)
2418 /* This relocation describes the C++ object vtable hierarchy.
2419 Reconstruct it for later use during GC. */
2420 case R_MICROBLAZE_GNU_VTINHERIT:
2421 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
2422 return false;
2423 break;
2425 /* This relocation describes which C++ vtable entries are actually
2426 used. Record for later use during GC. */
2427 case R_MICROBLAZE_GNU_VTENTRY:
2428 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
2429 return false;
2430 break;
2432 /* This relocation requires .plt entry. */
2433 case R_MICROBLAZE_PLT_64:
2434 if (h != NULL)
2436 h->needs_plt = 1;
2437 h->plt.refcount += 1;
2439 break;
2441 /* This relocation requires .got entry. */
2442 case R_MICROBLAZE_TLSGD:
2443 tls_type |= (TLS_TLS | TLS_GD);
2444 goto dogottls;
2445 case R_MICROBLAZE_TLSLD:
2446 tls_type |= (TLS_TLS | TLS_LD);
2447 /* Fall through. */
2448 dogottls:
2449 sec->has_tls_reloc = 1;
2450 /* Fall through. */
2451 case R_MICROBLAZE_GOT_64:
2452 if (htab->elf.sgot == NULL)
2454 if (htab->elf.dynobj == NULL)
2455 htab->elf.dynobj = abfd;
2456 if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
2457 return false;
2459 if (h != NULL)
2461 h->got.refcount += 1;
2462 elf32_mb_hash_entry (h)->tls_mask |= tls_type;
2464 else
2466 if (! update_local_sym_info(abfd, symtab_hdr, r_symndx, tls_type) )
2467 return false;
2469 break;
2471 case R_MICROBLAZE_GOTOFF_64:
2472 case R_MICROBLAZE_GOTOFF_32:
2473 if (htab->elf.sgot == NULL)
2475 if (htab->elf.dynobj == NULL)
2476 htab->elf.dynobj = abfd;
2477 if (!_bfd_elf_create_got_section (htab->elf.dynobj, info))
2478 return false;
2480 break;
2482 case R_MICROBLAZE_64:
2483 case R_MICROBLAZE_64_PCREL:
2484 case R_MICROBLAZE_32:
2486 if (h != NULL && !bfd_link_pic (info))
2488 /* we may need a copy reloc. */
2489 h->non_got_ref = 1;
2491 /* we may also need a .plt entry. */
2492 h->plt.refcount += 1;
2493 if (ELF32_R_TYPE (rel->r_info) != R_MICROBLAZE_64_PCREL)
2494 h->pointer_equality_needed = 1;
2498 /* If we are creating a shared library, and this is a reloc
2499 against a global symbol, or a non PC relative reloc
2500 against a local symbol, then we need to copy the reloc
2501 into the shared library. However, if we are linking with
2502 -Bsymbolic, we do not need to copy a reloc against a
2503 global symbol which is defined in an object we are
2504 including in the link (i.e., DEF_REGULAR is set). At
2505 this point we have not seen all the input files, so it is
2506 possible that DEF_REGULAR is not set now but will be set
2507 later (it is never cleared). In case of a weak definition,
2508 DEF_REGULAR may be cleared later by a strong definition in
2509 a shared library. We account for that possibility below by
2510 storing information in the relocs_copied field of the hash
2511 table entry. A similar situation occurs when creating
2512 shared libraries and symbol visibility changes render the
2513 symbol local.
2515 If on the other hand, we are creating an executable, we
2516 may need to keep relocations for symbols satisfied by a
2517 dynamic library if we manage to avoid copy relocs for the
2518 symbol. */
2520 if ((bfd_link_pic (info)
2521 && (sec->flags & SEC_ALLOC) != 0
2522 && (r_type != R_MICROBLAZE_64_PCREL
2523 || (h != NULL
2524 && (! info->symbolic
2525 || h->root.type == bfd_link_hash_defweak
2526 || !h->def_regular))))
2527 || (!bfd_link_pic (info)
2528 && (sec->flags & SEC_ALLOC) != 0
2529 && h != NULL
2530 && (h->root.type == bfd_link_hash_defweak
2531 || !h->def_regular)))
2533 struct elf_dyn_relocs *p;
2534 struct elf_dyn_relocs **head;
2536 /* When creating a shared object, we must copy these
2537 relocs into the output file. We create a reloc
2538 section in dynobj and make room for the reloc. */
2540 if (sreloc == NULL)
2542 bfd *dynobj;
2544 if (htab->elf.dynobj == NULL)
2545 htab->elf.dynobj = abfd;
2546 dynobj = htab->elf.dynobj;
2548 sreloc = _bfd_elf_make_dynamic_reloc_section (sec, dynobj,
2549 2, abfd, 1);
2550 if (sreloc == NULL)
2551 return false;
2554 /* If this is a global symbol, we count the number of
2555 relocations we need for this symbol. */
2556 if (h != NULL)
2557 head = &h->dyn_relocs;
2558 else
2560 /* Track dynamic relocs needed for local syms too.
2561 We really need local syms available to do this
2562 easily. Oh well. */
2564 asection *s;
2565 Elf_Internal_Sym *isym;
2566 void *vpp;
2568 isym = bfd_sym_from_r_symndx (&htab->elf.sym_cache,
2569 abfd, r_symndx);
2570 if (isym == NULL)
2571 return false;
2573 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2574 if (s == NULL)
2575 return false;
2577 vpp = &elf_section_data (s)->local_dynrel;
2578 head = (struct elf_dyn_relocs **) vpp;
2581 p = *head;
2582 if (p == NULL || p->sec != sec)
2584 size_t amt = sizeof *p;
2585 p = ((struct elf_dyn_relocs *)
2586 bfd_alloc (htab->elf.dynobj, amt));
2587 if (p == NULL)
2588 return false;
2589 p->next = *head;
2590 *head = p;
2591 p->sec = sec;
2592 p->count = 0;
2593 p->pc_count = 0;
2596 p->count += 1;
2597 if (r_type == R_MICROBLAZE_64_PCREL)
2598 p->pc_count += 1;
2601 break;
2605 return true;
2608 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2610 static void
2611 microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
2612 struct elf_link_hash_entry *dir,
2613 struct elf_link_hash_entry *ind)
2615 struct elf32_mb_link_hash_entry *edir, *eind;
2617 edir = (struct elf32_mb_link_hash_entry *) dir;
2618 eind = (struct elf32_mb_link_hash_entry *) ind;
2620 edir->tls_mask |= eind->tls_mask;
2622 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
2625 static bool
2626 microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2627 struct elf_link_hash_entry *h)
2629 struct elf32_mb_link_hash_table *htab;
2630 asection *s, *srel;
2631 unsigned int power_of_two;
2633 htab = elf32_mb_hash_table (info);
2634 if (htab == NULL)
2635 return false;
2637 /* If this is a function, put it in the procedure linkage table. We
2638 will fill in the contents of the procedure linkage table later,
2639 when we know the address of the .got section. */
2640 if (h->type == STT_FUNC
2641 || h->needs_plt)
2643 if (h->plt.refcount <= 0
2644 || SYMBOL_CALLS_LOCAL (info, h)
2645 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
2646 && h->root.type == bfd_link_hash_undefweak))
2648 /* This case can occur if we saw a PLT reloc in an input
2649 file, but the symbol was never referred to by a dynamic
2650 object, or if all references were garbage collected. In
2651 such a case, we don't actually need to build a procedure
2652 linkage table, and we can just do a PC32 reloc instead. */
2653 h->plt.offset = (bfd_vma) -1;
2654 h->needs_plt = 0;
2657 return true;
2659 else
2660 /* It's possible that we incorrectly decided a .plt reloc was
2661 needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
2662 check_relocs. We can't decide accurately between function and
2663 non-function syms in check-relocs; Objects loaded later in
2664 the link may change h->type. So fix it now. */
2665 h->plt.offset = (bfd_vma) -1;
2667 /* If this is a weak symbol, and there is a real definition, the
2668 processor independent code will have arranged for us to see the
2669 real definition first, and we can just use the same value. */
2670 if (h->is_weakalias)
2672 struct elf_link_hash_entry *def = weakdef (h);
2673 BFD_ASSERT (def->root.type == bfd_link_hash_defined);
2674 h->root.u.def.section = def->root.u.def.section;
2675 h->root.u.def.value = def->root.u.def.value;
2676 return true;
2679 /* This is a reference to a symbol defined by a dynamic object which
2680 is not a function. */
2682 /* If we are creating a shared library, we must presume that the
2683 only references to the symbol are via the global offset table.
2684 For such cases we need not do anything here; the relocations will
2685 be handled correctly by relocate_section. */
2686 if (bfd_link_pic (info))
2687 return true;
2689 /* If there are no references to this symbol that do not use the
2690 GOT, we don't need to generate a copy reloc. */
2691 if (!h->non_got_ref)
2692 return true;
2694 /* If -z nocopyreloc was given, we won't generate them either. */
2695 if (info->nocopyreloc)
2697 h->non_got_ref = 0;
2698 return true;
2701 /* If we don't find any dynamic relocs in read-only sections, then
2702 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
2703 if (!_bfd_elf_readonly_dynrelocs (h))
2705 h->non_got_ref = 0;
2706 return true;
2709 /* We must allocate the symbol in our .dynbss section, which will
2710 become part of the .bss section of the executable. There will be
2711 an entry for this symbol in the .dynsym section. The dynamic
2712 object will contain position independent code, so all references
2713 from the dynamic object to this symbol will go through the global
2714 offset table. The dynamic linker will use the .dynsym entry to
2715 determine the address it must put in the global offset table, so
2716 both the dynamic object and the regular object will refer to the
2717 same memory location for the variable. */
2719 /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
2720 to copy the initial value out of the dynamic object and into the
2721 runtime process image. */
2722 if ((h->root.u.def.section->flags & SEC_READONLY) != 0)
2724 s = htab->elf.sdynrelro;
2725 srel = htab->elf.sreldynrelro;
2727 else
2729 s = htab->elf.sdynbss;
2730 srel = htab->elf.srelbss;
2732 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2734 srel->size += sizeof (Elf32_External_Rela);
2735 h->needs_copy = 1;
2738 /* We need to figure out the alignment required for this symbol. I
2739 have no idea how ELF linkers handle this. */
2740 power_of_two = bfd_log2 (h->size);
2741 if (power_of_two > 3)
2742 power_of_two = 3;
2744 /* Apply the required alignment. */
2745 s->size = BFD_ALIGN (s->size, (bfd_size_type) (1 << power_of_two));
2746 if (power_of_two > s->alignment_power)
2748 if (!bfd_set_section_alignment (s, power_of_two))
2749 return false;
2752 /* Define the symbol as being at this point in the section. */
2753 h->root.u.def.section = s;
2754 h->root.u.def.value = s->size;
2756 /* Increment the section size to make room for the symbol. */
2757 s->size += h->size;
2758 return true;
2761 /* Allocate space in .plt, .got and associated reloc sections for
2762 dynamic relocs. */
2764 static bool
2765 allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
2767 struct bfd_link_info *info;
2768 struct elf32_mb_link_hash_table *htab;
2769 struct elf32_mb_link_hash_entry *eh;
2770 struct elf_dyn_relocs *p;
2772 if (h->root.type == bfd_link_hash_indirect)
2773 return true;
2775 info = (struct bfd_link_info *) dat;
2776 htab = elf32_mb_hash_table (info);
2777 if (htab == NULL)
2778 return false;
2780 if (htab->elf.dynamic_sections_created
2781 && h->plt.refcount > 0)
2783 /* Make sure this symbol is output as a dynamic symbol.
2784 Undefined weak syms won't yet be marked as dynamic. */
2785 if (h->dynindx == -1
2786 && !h->forced_local)
2788 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2789 return false;
2792 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, bfd_link_pic (info), h))
2794 asection *s = htab->elf.splt;
2796 /* The first entry in .plt is reserved. */
2797 if (s->size == 0)
2798 s->size = PLT_ENTRY_SIZE;
2800 h->plt.offset = s->size;
2802 /* If this symbol is not defined in a regular file, and we are
2803 not generating a shared library, then set the symbol to this
2804 location in the .plt. This is required to make function
2805 pointers compare as equal between the normal executable and
2806 the shared library. */
2807 if (! bfd_link_pic (info)
2808 && !h->def_regular)
2810 h->root.u.def.section = s;
2811 h->root.u.def.value = h->plt.offset;
2814 /* Make room for this entry. */
2815 s->size += PLT_ENTRY_SIZE;
2817 /* We also need to make an entry in the .got.plt section, which
2818 will be placed in the .got section by the linker script. */
2819 htab->elf.sgotplt->size += 4;
2821 /* We also need to make an entry in the .rel.plt section. */
2822 htab->elf.srelplt->size += sizeof (Elf32_External_Rela);
2824 else
2826 h->plt.offset = (bfd_vma) -1;
2827 h->needs_plt = 0;
2830 else
2832 h->plt.offset = (bfd_vma) -1;
2833 h->needs_plt = 0;
2836 eh = (struct elf32_mb_link_hash_entry *) h;
2837 if (h->got.refcount > 0)
2839 unsigned int need;
2840 asection *s;
2842 /* Make sure this symbol is output as a dynamic symbol.
2843 Undefined weak syms won't yet be marked as dynamic. */
2844 if (h->dynindx == -1
2845 && !h->forced_local)
2847 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2848 return false;
2851 need = 0;
2852 if ((eh->tls_mask & TLS_TLS) != 0)
2854 /* Handle TLS Symbol */
2855 if ((eh->tls_mask & TLS_LD) != 0)
2857 if (!eh->elf.def_dynamic)
2858 /* We'll just use htab->tlsld_got.offset. This should
2859 always be the case. It's a little odd if we have
2860 a local dynamic reloc against a non-local symbol. */
2861 htab->tlsld_got.refcount += 1;
2862 else
2863 need += 8;
2865 if ((eh->tls_mask & TLS_GD) != 0)
2866 need += 8;
2868 else
2870 /* Regular (non-TLS) symbol */
2871 need += 4;
2873 if (need == 0)
2875 h->got.offset = (bfd_vma) -1;
2877 else
2879 s = htab->elf.sgot;
2880 h->got.offset = s->size;
2881 s->size += need;
2882 htab->elf.srelgot->size += need * (sizeof (Elf32_External_Rela) / 4);
2885 else
2886 h->got.offset = (bfd_vma) -1;
2888 if (h->dyn_relocs == NULL)
2889 return true;
2891 /* In the shared -Bsymbolic case, discard space allocated for
2892 dynamic pc-relative relocs against symbols which turn out to be
2893 defined in regular objects. For the normal shared case, discard
2894 space for pc-relative relocs that have become local due to symbol
2895 visibility changes. */
2897 if (bfd_link_pic (info))
2899 if (h->def_regular
2900 && (h->forced_local
2901 || info->symbolic))
2903 struct elf_dyn_relocs **pp;
2905 for (pp = &h->dyn_relocs; (p = *pp) != NULL; )
2907 p->count -= p->pc_count;
2908 p->pc_count = 0;
2909 if (p->count == 0)
2910 *pp = p->next;
2911 else
2912 pp = &p->next;
2915 else if (UNDEFWEAK_NO_DYNAMIC_RELOC (info, h))
2916 h->dyn_relocs = NULL;
2918 else
2920 /* For the non-shared case, discard space for relocs against
2921 symbols which turn out to need copy relocs or are not
2922 dynamic. */
2924 if (!h->non_got_ref
2925 && ((h->def_dynamic
2926 && !h->def_regular)
2927 || (htab->elf.dynamic_sections_created
2928 && (h->root.type == bfd_link_hash_undefweak
2929 || h->root.type == bfd_link_hash_undefined))))
2931 /* Make sure this symbol is output as a dynamic symbol.
2932 Undefined weak syms won't yet be marked as dynamic. */
2933 if (h->dynindx == -1
2934 && !h->forced_local)
2936 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2937 return false;
2940 /* If that succeeded, we know we'll be keeping all the
2941 relocs. */
2942 if (h->dynindx != -1)
2943 goto keep;
2946 h->dyn_relocs = NULL;
2948 keep: ;
2951 /* Finally, allocate space. */
2952 for (p = h->dyn_relocs; p != NULL; p = p->next)
2954 asection *sreloc = elf_section_data (p->sec)->sreloc;
2955 sreloc->size += p->count * sizeof (Elf32_External_Rela);
2958 return true;
2961 /* Set the sizes of the dynamic sections. */
2963 static bool
2964 microblaze_elf_late_size_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2965 struct bfd_link_info *info)
2967 struct elf32_mb_link_hash_table *htab;
2968 bfd *dynobj;
2969 asection *s;
2970 bfd *ibfd;
2972 htab = elf32_mb_hash_table (info);
2973 if (htab == NULL)
2974 return false;
2976 dynobj = htab->elf.dynobj;
2977 if (dynobj == NULL)
2978 return true;
2980 /* Set up .got offsets for local syms, and space for local dynamic
2981 relocs. */
2982 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
2984 bfd_signed_vma *local_got;
2985 bfd_signed_vma *end_local_got;
2986 bfd_size_type locsymcount;
2987 Elf_Internal_Shdr *symtab_hdr;
2988 unsigned char *lgot_masks;
2989 asection *srel;
2991 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
2992 continue;
2994 for (s = ibfd->sections; s != NULL; s = s->next)
2996 struct elf_dyn_relocs *p;
2998 for (p = ((struct elf_dyn_relocs *)
2999 elf_section_data (s)->local_dynrel);
3000 p != NULL;
3001 p = p->next)
3003 if (!bfd_is_abs_section (p->sec)
3004 && bfd_is_abs_section (p->sec->output_section))
3006 /* Input section has been discarded, either because
3007 it is a copy of a linkonce section or due to
3008 linker script /DISCARD/, so we'll be discarding
3009 the relocs too. */
3011 else if (p->count != 0)
3013 srel = elf_section_data (p->sec)->sreloc;
3014 srel->size += p->count * sizeof (Elf32_External_Rela);
3015 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
3016 info->flags |= DF_TEXTREL;
3021 local_got = elf_local_got_refcounts (ibfd);
3022 if (!local_got)
3023 continue;
3025 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
3026 locsymcount = symtab_hdr->sh_info;
3027 end_local_got = local_got + locsymcount;
3028 lgot_masks = (unsigned char *) end_local_got;
3029 s = htab->elf.sgot;
3030 srel = htab->elf.srelgot;
3032 for (; local_got < end_local_got; ++local_got, ++lgot_masks)
3034 if (*local_got > 0)
3036 unsigned int need = 0;
3037 if ((*lgot_masks & TLS_TLS) != 0)
3039 if ((*lgot_masks & TLS_GD) != 0)
3040 need += 8;
3041 if ((*lgot_masks & TLS_LD) != 0)
3042 htab->tlsld_got.refcount += 1;
3044 else
3045 need += 4;
3047 if (need == 0)
3049 *local_got = (bfd_vma) -1;
3051 else
3053 *local_got = s->size;
3054 s->size += need;
3055 if (bfd_link_pic (info))
3056 srel->size += need * (sizeof (Elf32_External_Rela) / 4);
3059 else
3060 *local_got = (bfd_vma) -1;
3064 /* Allocate global sym .plt and .got entries, and space for global
3065 sym dynamic relocs. */
3066 elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
3068 if (htab->tlsld_got.refcount > 0)
3070 htab->tlsld_got.offset = htab->elf.sgot->size;
3071 htab->elf.sgot->size += 8;
3072 if (bfd_link_pic (info))
3073 htab->elf.srelgot->size += sizeof (Elf32_External_Rela);
3075 else
3076 htab->tlsld_got.offset = (bfd_vma) -1;
3078 if (elf_hash_table (info)->dynamic_sections_created)
3080 /* Make space for the trailing nop in .plt. */
3081 if (htab->elf.splt->size > 0)
3082 htab->elf.splt->size += 4;
3085 /* The check_relocs and adjust_dynamic_symbol entry points have
3086 determined the sizes of the various dynamic sections. Allocate
3087 memory for them. */
3088 for (s = dynobj->sections; s != NULL; s = s->next)
3090 const char *name;
3091 bool strip = false;
3093 if ((s->flags & SEC_LINKER_CREATED) == 0)
3094 continue;
3096 /* It's OK to base decisions on the section name, because none
3097 of the dynobj section names depend upon the input files. */
3098 name = bfd_section_name (s);
3100 if (startswith (name, ".rela"))
3102 if (s->size == 0)
3104 /* If we don't need this section, strip it from the
3105 output file. This is to handle .rela.bss and
3106 .rela.plt. We must create it in
3107 create_dynamic_sections, because it must be created
3108 before the linker maps input sections to output
3109 sections. The linker does that before
3110 adjust_dynamic_symbol is called, and it is that
3111 function which decides whether anything needs to go
3112 into these sections. */
3113 strip = true;
3115 else
3117 /* We use the reloc_count field as a counter if we need
3118 to copy relocs into the output file. */
3119 s->reloc_count = 0;
3122 else if (s != htab->elf.splt
3123 && s != htab->elf.sgot
3124 && s != htab->elf.sgotplt
3125 && s != htab->elf.sdynbss
3126 && s != htab->elf.sdynrelro)
3128 /* It's not one of our sections, so don't allocate space. */
3129 continue;
3132 if (strip)
3134 s->flags |= SEC_EXCLUDE;
3135 continue;
3138 /* Allocate memory for the section contents. */
3139 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
3140 Unused entries should be reclaimed before the section's contents
3141 are written out, but at the moment this does not happen. Thus in
3142 order to prevent writing out garbage, we initialise the section's
3143 contents to zero. */
3144 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
3145 if (s->contents == NULL && s->size != 0)
3146 return false;
3149 /* ??? Force DF_BIND_NOW? */
3150 info->flags |= DF_BIND_NOW;
3151 return _bfd_elf_add_dynamic_tags (output_bfd, info, true);
3154 /* Finish up dynamic symbol handling. We set the contents of various
3155 dynamic sections here. */
3157 static bool
3158 microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
3159 struct bfd_link_info *info,
3160 struct elf_link_hash_entry *h,
3161 Elf_Internal_Sym *sym)
3163 struct elf32_mb_link_hash_table *htab;
3164 struct elf32_mb_link_hash_entry *eh = elf32_mb_hash_entry(h);
3166 htab = elf32_mb_hash_table (info);
3168 if (h->plt.offset != (bfd_vma) -1)
3170 asection *splt;
3171 asection *srela;
3172 asection *sgotplt;
3173 Elf_Internal_Rela rela;
3174 bfd_byte *loc;
3175 bfd_vma plt_index;
3176 bfd_vma got_offset;
3177 bfd_vma got_addr;
3179 /* This symbol has an entry in the procedure linkage table. Set
3180 it up. */
3181 BFD_ASSERT (h->dynindx != -1);
3183 splt = htab->elf.splt;
3184 srela = htab->elf.srelplt;
3185 sgotplt = htab->elf.sgotplt;
3186 BFD_ASSERT (splt != NULL && srela != NULL && sgotplt != NULL);
3188 plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* first entry reserved. */
3189 got_offset = (plt_index + 3) * 4; /* 3 reserved ??? */
3190 got_addr = got_offset;
3192 /* For non-PIC objects we need absolute address of the GOT entry. */
3193 if (!bfd_link_pic (info))
3194 got_addr += sgotplt->output_section->vma + sgotplt->output_offset;
3196 /* Fill in the entry in the procedure linkage table. */
3197 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_0 + ((got_addr >> 16) & 0xffff),
3198 splt->contents + h->plt.offset);
3199 if (bfd_link_pic (info))
3200 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1 + (got_addr & 0xffff),
3201 splt->contents + h->plt.offset + 4);
3202 else
3203 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1_NOPIC + (got_addr & 0xffff),
3204 splt->contents + h->plt.offset + 4);
3205 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_2,
3206 splt->contents + h->plt.offset + 8);
3207 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_3,
3208 splt->contents + h->plt.offset + 12);
3210 /* Any additions to the .got section??? */
3211 /* bfd_put_32 (output_bfd,
3212 splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
3213 sgotplt->contents + got_offset); */
3215 /* Fill in the entry in the .rela.plt section. */
3216 rela.r_offset = (sgotplt->output_section->vma
3217 + sgotplt->output_offset
3218 + got_offset);
3219 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_JUMP_SLOT);
3220 rela.r_addend = 0;
3221 loc = srela->contents;
3222 loc += plt_index * sizeof (Elf32_External_Rela);
3223 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
3225 if (!h->def_regular)
3227 /* Mark the symbol as undefined, rather than as defined in
3228 the .plt section. Zero the value. */
3229 sym->st_shndx = SHN_UNDEF;
3230 sym->st_value = 0;
3234 /* h->got.refcount to be checked ? */
3235 if ((h->got.offset != (bfd_vma) -1)
3236 && ! ((h->got.offset & 1)
3237 || IS_TLS_LD(eh->tls_mask) || IS_TLS_GD(eh->tls_mask)))
3239 asection *sgot;
3240 asection *srela;
3241 bfd_vma offset;
3243 /* This symbol has an entry in the global offset table. Set it
3244 up. */
3246 sgot = htab->elf.sgot;
3247 srela = htab->elf.srelgot;
3248 BFD_ASSERT (sgot != NULL && srela != NULL);
3250 offset = (sgot->output_section->vma + sgot->output_offset
3251 + (h->got.offset &~ (bfd_vma) 1));
3253 /* If this is a -Bsymbolic link, and the symbol is defined
3254 locally, we just want to emit a RELATIVE reloc. Likewise if
3255 the symbol was forced to be local because of a version file.
3256 The entry in the global offset table will already have been
3257 initialized in the relocate_section function. */
3258 if (bfd_link_pic (info)
3259 && ((info->symbolic && h->def_regular)
3260 || h->dynindx == -1))
3262 asection *sec = h->root.u.def.section;
3263 bfd_vma value;
3265 value = h->root.u.def.value;
3266 if (sec->output_section != NULL)
3267 /* PR 21180: If the output section is NULL, then the symbol is no
3268 longer needed, and in theory the GOT entry is redundant. But
3269 it is too late to change our minds now... */
3270 value += sec->output_section->vma + sec->output_offset;
3272 microblaze_elf_output_dynamic_relocation (output_bfd,
3273 srela, srela->reloc_count++,
3274 /* symindex= */ 0,
3275 R_MICROBLAZE_REL, offset,
3276 value);
3278 else
3280 microblaze_elf_output_dynamic_relocation (output_bfd,
3281 srela, srela->reloc_count++,
3282 h->dynindx,
3283 R_MICROBLAZE_GLOB_DAT,
3284 offset, 0);
3287 bfd_put_32 (output_bfd, (bfd_vma) 0,
3288 sgot->contents + (h->got.offset &~ (bfd_vma) 1));
3291 if (h->needs_copy)
3293 asection *s;
3294 Elf_Internal_Rela rela;
3295 bfd_byte *loc;
3297 /* This symbols needs a copy reloc. Set it up. */
3299 BFD_ASSERT (h->dynindx != -1);
3301 rela.r_offset = (h->root.u.def.value
3302 + h->root.u.def.section->output_section->vma
3303 + h->root.u.def.section->output_offset);
3304 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_COPY);
3305 rela.r_addend = 0;
3306 if (h->root.u.def.section == htab->elf.sdynrelro)
3307 s = htab->elf.sreldynrelro;
3308 else
3309 s = htab->elf.srelbss;
3310 loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
3311 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
3314 /* Mark some specially defined symbols as absolute. */
3315 if (h == htab->elf.hdynamic
3316 || h == htab->elf.hgot
3317 || h == htab->elf.hplt)
3318 sym->st_shndx = SHN_ABS;
3320 return true;
3324 /* Finish up the dynamic sections. */
3326 static bool
3327 microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
3328 struct bfd_link_info *info)
3330 bfd *dynobj;
3331 asection *sdyn, *sgot;
3332 struct elf32_mb_link_hash_table *htab;
3334 htab = elf32_mb_hash_table (info);
3335 if (htab == NULL)
3336 return false;
3338 dynobj = htab->elf.dynobj;
3340 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
3342 if (htab->elf.dynamic_sections_created)
3344 asection *splt;
3345 Elf32_External_Dyn *dyncon, *dynconend;
3347 dyncon = (Elf32_External_Dyn *) sdyn->contents;
3348 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
3349 for (; dyncon < dynconend; dyncon++)
3351 Elf_Internal_Dyn dyn;
3352 asection *s;
3353 bool size;
3355 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
3357 switch (dyn.d_tag)
3359 case DT_PLTGOT:
3360 s = htab->elf.sgotplt;
3361 size = false;
3362 break;
3364 case DT_PLTRELSZ:
3365 s = htab->elf.srelplt;
3366 size = true;
3367 break;
3369 case DT_JMPREL:
3370 s = htab->elf.srelplt;
3371 size = false;
3372 break;
3374 default:
3375 continue;
3378 if (s == NULL)
3379 dyn.d_un.d_val = 0;
3380 else
3382 if (!size)
3383 dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
3384 else
3385 dyn.d_un.d_val = s->size;
3387 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
3390 splt = htab->elf.splt;
3391 BFD_ASSERT (splt != NULL && sdyn != NULL);
3393 /* Clear the first entry in the procedure linkage table,
3394 and put a nop in the last four bytes. */
3395 if (splt->size > 0)
3397 memset (splt->contents, 0, PLT_ENTRY_SIZE);
3398 bfd_put_32 (output_bfd, (bfd_vma) 0x80000000 /* nop. */,
3399 splt->contents + splt->size - 4);
3401 if (splt->output_section != bfd_abs_section_ptr)
3402 elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
3406 /* Set the first entry in the global offset table to the address of
3407 the dynamic section. */
3408 sgot = htab->elf.sgotplt;
3409 if (sgot && sgot->size > 0)
3411 if (sdyn == NULL)
3412 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
3413 else
3414 bfd_put_32 (output_bfd,
3415 sdyn->output_section->vma + sdyn->output_offset,
3416 sgot->contents);
3417 elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
3420 if (htab->elf.sgot && htab->elf.sgot->size > 0)
3421 elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize = 4;
3423 return true;
3426 /* Hook called by the linker routine which adds symbols from an object
3427 file. We use it to put .comm items in .sbss, and not .bss. */
3429 static bool
3430 microblaze_elf_add_symbol_hook (bfd *abfd,
3431 struct bfd_link_info *info,
3432 Elf_Internal_Sym *sym,
3433 const char **namep ATTRIBUTE_UNUSED,
3434 flagword *flagsp ATTRIBUTE_UNUSED,
3435 asection **secp,
3436 bfd_vma *valp)
3438 if (sym->st_shndx == SHN_COMMON
3439 && !bfd_link_relocatable (info)
3440 && sym->st_size <= elf_gp_size (abfd))
3442 /* Common symbols less than or equal to -G nn bytes are automatically
3443 put into .sbss. */
3444 *secp = bfd_make_section_old_way (abfd, ".sbss");
3445 if (*secp == NULL
3446 || !bfd_set_section_flags (*secp, SEC_IS_COMMON | SEC_SMALL_DATA))
3447 return false;
3449 *valp = sym->st_size;
3452 return true;
3455 #define TARGET_LITTLE_SYM microblaze_elf32_le_vec
3456 #define TARGET_LITTLE_NAME "elf32-microblazeel"
3458 #define TARGET_BIG_SYM microblaze_elf32_vec
3459 #define TARGET_BIG_NAME "elf32-microblaze"
3461 #define ELF_ARCH bfd_arch_microblaze
3462 #define ELF_TARGET_ID MICROBLAZE_ELF_DATA
3463 #define ELF_MACHINE_CODE EM_MICROBLAZE
3464 #define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
3465 #define ELF_MAXPAGESIZE 0x1000
3466 #define elf_info_to_howto microblaze_elf_info_to_howto
3467 #define elf_info_to_howto_rel NULL
3469 #define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
3470 #define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name
3471 #define bfd_elf32_new_section_hook microblaze_elf_new_section_hook
3472 #define elf_backend_relocate_section microblaze_elf_relocate_section
3473 #define bfd_elf32_bfd_relax_section microblaze_elf_relax_section
3474 #define bfd_elf32_bfd_merge_private_bfd_data _bfd_generic_verify_endian_match
3475 #define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
3477 #define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
3478 #define elf_backend_check_relocs microblaze_elf_check_relocs
3479 #define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
3480 #define bfd_elf32_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
3481 #define elf_backend_can_gc_sections 1
3482 #define elf_backend_can_refcount 1
3483 #define elf_backend_want_got_plt 1
3484 #define elf_backend_plt_readonly 1
3485 #define elf_backend_got_header_size 12
3486 #define elf_backend_want_dynrelro 1
3487 #define elf_backend_rela_normal 1
3488 #define elf_backend_dtrel_excludes_plt 1
3490 #define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
3491 #define elf_backend_create_dynamic_sections _bfd_elf_create_dynamic_sections
3492 #define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
3493 #define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
3494 #define elf_backend_late_size_sections microblaze_elf_late_size_sections
3495 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
3497 #include "elf32-target.h"