1 /* Xilinx MicroBlaze-specific support for 32-bit ELF
3 Copyright 2009, 2010, 2011, 2012 Free Software Foundation, Inc.
5 This file is part of BFD, the Binary File Descriptor library.
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the
19 Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
20 Boston, MA 02110-1301, USA. */
30 #include "elf/microblaze.h"
33 #define USE_RELA /* Only USE_REL is actually significant, but this is
34 here are a reminder... */
35 #define INST_WORD_SIZE 4
37 static int ro_small_data_pointer = 0;
38 static int rw_small_data_pointer = 0;
40 static reloc_howto_type * microblaze_elf_howto_table [(int) R_MICROBLAZE_max];
42 static reloc_howto_type microblaze_elf_howto_raw[] =
44 /* This reloc does nothing. */
45 HOWTO (R_MICROBLAZE_NONE, /* Type. */
47 2, /* Size (0 = byte, 1 = short, 2 = long). */
49 FALSE, /* PC_relative. */
51 complain_overflow_bitfield, /* Complain on overflow. */
52 NULL, /* Special Function. */
53 "R_MICROBLAZE_NONE", /* Name. */
54 FALSE, /* Partial Inplace. */
57 FALSE), /* PC relative offset? */
59 /* A standard 32 bit relocation. */
60 HOWTO (R_MICROBLAZE_32, /* Type. */
62 2, /* Size (0 = byte, 1 = short, 2 = long). */
64 FALSE, /* PC_relative. */
66 complain_overflow_bitfield, /* Complain on overflow. */
67 bfd_elf_generic_reloc,/* Special Function. */
68 "R_MICROBLAZE_32", /* Name. */
69 FALSE, /* Partial Inplace. */
71 0xffffffff, /* Dest Mask. */
72 FALSE), /* PC relative offset? */
74 /* A standard PCREL 32 bit relocation. */
75 HOWTO (R_MICROBLAZE_32_PCREL,/* Type. */
77 2, /* Size (0 = byte, 1 = short, 2 = long). */
79 TRUE, /* PC_relative. */
81 complain_overflow_bitfield, /* Complain on overflow. */
82 bfd_elf_generic_reloc,/* Special Function. */
83 "R_MICROBLAZE_32_PCREL", /* Name. */
84 TRUE, /* Partial Inplace. */
86 0xffffffff, /* Dest Mask. */
87 TRUE), /* PC relative offset? */
89 /* A 64 bit PCREL relocation. Table-entry not really used. */
90 HOWTO (R_MICROBLAZE_64_PCREL,/* Type. */
92 2, /* Size (0 = byte, 1 = short, 2 = long). */
94 TRUE, /* PC_relative. */
96 complain_overflow_dont, /* Complain on overflow. */
97 bfd_elf_generic_reloc,/* Special Function. */
98 "R_MICROBLAZE_64_PCREL", /* Name. */
99 FALSE, /* Partial Inplace. */
100 0, /* Source Mask. */
101 0x0000ffff, /* Dest Mask. */
102 TRUE), /* PC relative offset? */
104 /* The low half of a PCREL 32 bit relocation. */
105 HOWTO (R_MICROBLAZE_32_PCREL_LO, /* Type. */
107 2, /* Size (0 = byte, 1 = short, 2 = long). */
109 TRUE, /* PC_relative. */
111 complain_overflow_signed, /* Complain on overflow. */
112 bfd_elf_generic_reloc, /* Special Function. */
113 "R_MICROBLAZE_32_PCREL_LO", /* Name. */
114 FALSE, /* Partial Inplace. */
115 0, /* Source Mask. */
116 0x0000ffff, /* Dest Mask. */
117 TRUE), /* PC relative offset? */
119 /* A 64 bit relocation. Table entry not really used. */
120 HOWTO (R_MICROBLAZE_64, /* Type. */
122 2, /* Size (0 = byte, 1 = short, 2 = long). */
124 FALSE, /* PC_relative. */
126 complain_overflow_dont, /* Complain on overflow. */
127 bfd_elf_generic_reloc,/* Special Function. */
128 "R_MICROBLAZE_64", /* Name. */
129 FALSE, /* Partial Inplace. */
130 0, /* Source Mask. */
131 0x0000ffff, /* Dest Mask. */
132 FALSE), /* PC relative offset? */
134 /* The low half of a 32 bit relocation. */
135 HOWTO (R_MICROBLAZE_32_LO, /* Type. */
137 2, /* Size (0 = byte, 1 = short, 2 = long). */
139 FALSE, /* PC_relative. */
141 complain_overflow_signed, /* Complain on overflow. */
142 bfd_elf_generic_reloc,/* Special Function. */
143 "R_MICROBLAZE_32_LO", /* Name. */
144 FALSE, /* Partial Inplace. */
145 0, /* Source Mask. */
146 0x0000ffff, /* Dest Mask. */
147 FALSE), /* PC relative offset? */
149 /* Read-only small data section relocation. */
150 HOWTO (R_MICROBLAZE_SRO32, /* Type. */
152 2, /* Size (0 = byte, 1 = short, 2 = long). */
154 FALSE, /* PC_relative. */
156 complain_overflow_bitfield, /* Complain on overflow. */
157 bfd_elf_generic_reloc,/* Special Function. */
158 "R_MICROBLAZE_SRO32", /* Name. */
159 FALSE, /* Partial Inplace. */
160 0, /* Source Mask. */
161 0x0000ffff, /* Dest Mask. */
162 FALSE), /* PC relative offset? */
164 /* Read-write small data area relocation. */
165 HOWTO (R_MICROBLAZE_SRW32, /* Type. */
167 2, /* Size (0 = byte, 1 = short, 2 = long). */
169 FALSE, /* PC_relative. */
171 complain_overflow_bitfield, /* Complain on overflow. */
172 bfd_elf_generic_reloc,/* Special Function. */
173 "R_MICROBLAZE_SRW32", /* Name. */
174 FALSE, /* Partial Inplace. */
175 0, /* Source Mask. */
176 0x0000ffff, /* Dest Mask. */
177 FALSE), /* PC relative offset? */
179 /* This reloc does nothing. Used for relaxation. */
180 HOWTO (R_MICROBLAZE_64_NONE, /* Type. */
182 2, /* Size (0 = byte, 1 = short, 2 = long). */
184 TRUE, /* PC_relative. */
186 complain_overflow_bitfield, /* Complain on overflow. */
187 NULL, /* Special Function. */
188 "R_MICROBLAZE_64_NONE",/* Name. */
189 FALSE, /* Partial Inplace. */
190 0, /* Source Mask. */
192 FALSE), /* PC relative offset? */
194 /* Symbol Op Symbol relocation. */
195 HOWTO (R_MICROBLAZE_32_SYM_OP_SYM, /* Type. */
197 2, /* Size (0 = byte, 1 = short, 2 = long). */
199 FALSE, /* PC_relative. */
201 complain_overflow_bitfield, /* Complain on overflow. */
202 bfd_elf_generic_reloc,/* Special Function. */
203 "R_MICROBLAZE_32_SYM_OP_SYM", /* Name. */
204 FALSE, /* Partial Inplace. */
205 0, /* Source Mask. */
206 0xffffffff, /* Dest Mask. */
207 FALSE), /* PC relative offset? */
209 /* GNU extension to record C++ vtable hierarchy. */
210 HOWTO (R_MICROBLAZE_GNU_VTINHERIT, /* Type. */
212 2, /* Size (0 = byte, 1 = short, 2 = long). */
214 FALSE, /* PC_relative. */
216 complain_overflow_dont,/* Complain on overflow. */
217 NULL, /* Special Function. */
218 "R_MICROBLAZE_GNU_VTINHERIT", /* Name. */
219 FALSE, /* Partial Inplace. */
220 0, /* Source Mask. */
222 FALSE), /* PC relative offset? */
224 /* GNU extension to record C++ vtable member usage. */
225 HOWTO (R_MICROBLAZE_GNU_VTENTRY, /* Type. */
227 2, /* Size (0 = byte, 1 = short, 2 = long). */
229 FALSE, /* PC_relative. */
231 complain_overflow_dont,/* Complain on overflow. */
232 _bfd_elf_rel_vtable_reloc_fn, /* Special Function. */
233 "R_MICROBLAZE_GNU_VTENTRY", /* Name. */
234 FALSE, /* Partial Inplace. */
235 0, /* Source Mask. */
237 FALSE), /* PC relative offset? */
239 /* A 64 bit GOTPC relocation. Table-entry not really used. */
240 HOWTO (R_MICROBLAZE_GOTPC_64, /* Type. */
242 2, /* Size (0 = byte, 1 = short, 2 = long). */
244 TRUE, /* PC_relative. */
246 complain_overflow_dont, /* Complain on overflow. */
247 bfd_elf_generic_reloc, /* Special Function. */
248 "R_MICROBLAZE_GOTPC_64", /* Name. */
249 FALSE, /* Partial Inplace. */
250 0, /* Source Mask. */
251 0x0000ffff, /* Dest Mask. */
252 TRUE), /* PC relative offset? */
254 /* A 64 bit GOT relocation. Table-entry not really used. */
255 HOWTO (R_MICROBLAZE_GOT_64, /* Type. */
257 2, /* Size (0 = byte, 1 = short, 2 = long). */
259 FALSE, /* PC_relative. */
261 complain_overflow_dont, /* Complain on overflow. */
262 bfd_elf_generic_reloc,/* Special Function. */
263 "R_MICROBLAZE_GOT_64",/* Name. */
264 FALSE, /* Partial Inplace. */
265 0, /* Source Mask. */
266 0x0000ffff, /* Dest Mask. */
267 FALSE), /* PC relative offset? */
269 /* A 64 bit PLT relocation. Table-entry not really used. */
270 HOWTO (R_MICROBLAZE_PLT_64, /* Type. */
272 2, /* Size (0 = byte, 1 = short, 2 = long). */
274 TRUE, /* PC_relative. */
276 complain_overflow_dont, /* Complain on overflow. */
277 bfd_elf_generic_reloc,/* Special Function. */
278 "R_MICROBLAZE_PLT_64",/* Name. */
279 FALSE, /* Partial Inplace. */
280 0, /* Source Mask. */
281 0x0000ffff, /* Dest Mask. */
282 TRUE), /* PC relative offset? */
284 /* Table-entry not really used. */
285 HOWTO (R_MICROBLAZE_REL, /* Type. */
287 2, /* Size (0 = byte, 1 = short, 2 = long). */
289 TRUE, /* PC_relative. */
291 complain_overflow_dont, /* Complain on overflow. */
292 bfd_elf_generic_reloc,/* Special Function. */
293 "R_MICROBLAZE_REL", /* Name. */
294 FALSE, /* Partial Inplace. */
295 0, /* Source Mask. */
296 0x0000ffff, /* Dest Mask. */
297 TRUE), /* PC relative offset? */
299 /* Table-entry not really used. */
300 HOWTO (R_MICROBLAZE_JUMP_SLOT,/* Type. */
302 2, /* Size (0 = byte, 1 = short, 2 = long). */
304 TRUE, /* PC_relative. */
306 complain_overflow_dont, /* Complain on overflow. */
307 bfd_elf_generic_reloc,/* Special Function. */
308 "R_MICROBLAZE_JUMP_SLOT", /* Name. */
309 FALSE, /* Partial Inplace. */
310 0, /* Source Mask. */
311 0x0000ffff, /* Dest Mask. */
312 TRUE), /* PC relative offset? */
314 /* Table-entry not really used. */
315 HOWTO (R_MICROBLAZE_GLOB_DAT,/* Type. */
317 2, /* Size (0 = byte, 1 = short, 2 = long). */
319 TRUE, /* PC_relative. */
321 complain_overflow_dont, /* Complain on overflow. */
322 bfd_elf_generic_reloc,/* Special Function. */
323 "R_MICROBLAZE_GLOB_DAT", /* Name. */
324 FALSE, /* Partial Inplace. */
325 0, /* Source Mask. */
326 0x0000ffff, /* Dest Mask. */
327 TRUE), /* PC relative offset? */
329 /* A 64 bit GOT relative relocation. Table-entry not really used. */
330 HOWTO (R_MICROBLAZE_GOTOFF_64, /* Type. */
332 2, /* Size (0 = byte, 1 = short, 2 = long). */
334 FALSE, /* PC_relative. */
336 complain_overflow_dont, /* Complain on overflow. */
337 bfd_elf_generic_reloc,/* Special Function. */
338 "R_MICROBLAZE_GOTOFF_64", /* Name. */
339 FALSE, /* Partial Inplace. */
340 0, /* Source Mask. */
341 0x0000ffff, /* Dest Mask. */
342 FALSE), /* PC relative offset? */
344 /* A 32 bit GOT relative relocation. Table-entry not really used. */
345 HOWTO (R_MICROBLAZE_GOTOFF_32, /* Type. */
347 2, /* Size (0 = byte, 1 = short, 2 = long). */
349 FALSE, /* PC_relative. */
351 complain_overflow_dont, /* Complain on overflow. */
352 bfd_elf_generic_reloc, /* Special Function. */
353 "R_MICROBLAZE_GOTOFF_32", /* Name. */
354 FALSE, /* Partial Inplace. */
355 0, /* Source Mask. */
356 0x0000ffff, /* Dest Mask. */
357 FALSE), /* PC relative offset? */
359 /* COPY relocation. Table-entry not really used. */
360 HOWTO (R_MICROBLAZE_COPY, /* Type. */
362 2, /* Size (0 = byte, 1 = short, 2 = long). */
364 FALSE, /* PC_relative. */
366 complain_overflow_dont, /* Complain on overflow. */
367 bfd_elf_generic_reloc,/* Special Function. */
368 "R_MICROBLAZE_COPY", /* Name. */
369 FALSE, /* Partial Inplace. */
370 0, /* Source Mask. */
371 0x0000ffff, /* Dest Mask. */
372 FALSE), /* PC relative offset? */
376 #define NUM_ELEM(a) (sizeof (a) / sizeof (a)[0])
379 /* Initialize the microblaze_elf_howto_table, so that linear accesses can be done. */
382 microblaze_elf_howto_init (void)
386 for (i = NUM_ELEM (microblaze_elf_howto_raw); i--;)
390 type = microblaze_elf_howto_raw[i].type;
392 BFD_ASSERT (type < NUM_ELEM (microblaze_elf_howto_table));
394 microblaze_elf_howto_table [type] = & microblaze_elf_howto_raw [i];
398 static reloc_howto_type *
399 microblaze_elf_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
400 bfd_reloc_code_real_type code)
402 enum elf_microblaze_reloc_type microblaze_reloc = R_MICROBLAZE_NONE;
407 microblaze_reloc = R_MICROBLAZE_NONE;
409 case BFD_RELOC_MICROBLAZE_64_NONE:
410 microblaze_reloc = R_MICROBLAZE_64_NONE;
413 microblaze_reloc = R_MICROBLAZE_32;
415 /* RVA is treated the same as 32 */
417 microblaze_reloc = R_MICROBLAZE_32;
419 case BFD_RELOC_32_PCREL:
420 microblaze_reloc = R_MICROBLAZE_32_PCREL;
422 case BFD_RELOC_64_PCREL:
423 microblaze_reloc = R_MICROBLAZE_64_PCREL;
425 case BFD_RELOC_MICROBLAZE_32_LO_PCREL:
426 microblaze_reloc = R_MICROBLAZE_32_PCREL_LO;
429 microblaze_reloc = R_MICROBLAZE_64;
431 case BFD_RELOC_MICROBLAZE_32_LO:
432 microblaze_reloc = R_MICROBLAZE_32_LO;
434 case BFD_RELOC_MICROBLAZE_32_ROSDA:
435 microblaze_reloc = R_MICROBLAZE_SRO32;
437 case BFD_RELOC_MICROBLAZE_32_RWSDA:
438 microblaze_reloc = R_MICROBLAZE_SRW32;
440 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM:
441 microblaze_reloc = R_MICROBLAZE_32_SYM_OP_SYM;
443 case BFD_RELOC_VTABLE_INHERIT:
444 microblaze_reloc = R_MICROBLAZE_GNU_VTINHERIT;
446 case BFD_RELOC_VTABLE_ENTRY:
447 microblaze_reloc = R_MICROBLAZE_GNU_VTENTRY;
449 case BFD_RELOC_MICROBLAZE_64_GOTPC:
450 microblaze_reloc = R_MICROBLAZE_GOTPC_64;
452 case BFD_RELOC_MICROBLAZE_64_GOT:
453 microblaze_reloc = R_MICROBLAZE_GOT_64;
455 case BFD_RELOC_MICROBLAZE_64_PLT:
456 microblaze_reloc = R_MICROBLAZE_PLT_64;
458 case BFD_RELOC_MICROBLAZE_64_GOTOFF:
459 microblaze_reloc = R_MICROBLAZE_GOTOFF_64;
461 case BFD_RELOC_MICROBLAZE_32_GOTOFF:
462 microblaze_reloc = R_MICROBLAZE_GOTOFF_32;
464 case BFD_RELOC_MICROBLAZE_COPY:
465 microblaze_reloc = R_MICROBLAZE_COPY;
468 return (reloc_howto_type *) NULL;
471 if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
472 /* Initialize howto table if needed. */
473 microblaze_elf_howto_init ();
475 return microblaze_elf_howto_table [(int) microblaze_reloc];
478 static reloc_howto_type *
479 microblaze_elf_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
484 for (i = 0; i < NUM_ELEM (microblaze_elf_howto_raw); i++)
485 if (microblaze_elf_howto_raw[i].name != NULL
486 && strcasecmp (microblaze_elf_howto_raw[i].name, r_name) == 0)
487 return µblaze_elf_howto_raw[i];
492 /* Set the howto pointer for a RCE ELF reloc. */
495 microblaze_elf_info_to_howto (bfd * abfd ATTRIBUTE_UNUSED,
497 Elf_Internal_Rela * dst)
499 if (!microblaze_elf_howto_table [R_MICROBLAZE_32])
500 /* Initialize howto table if needed. */
501 microblaze_elf_howto_init ();
503 BFD_ASSERT (ELF32_R_TYPE (dst->r_info) < (unsigned int) R_MICROBLAZE_max);
505 cache_ptr->howto = microblaze_elf_howto_table [ELF32_R_TYPE (dst->r_info)];
508 /* Microblaze ELF local labels start with 'L.' or '$L', not '.L'. */
511 microblaze_elf_is_local_label_name (bfd *abfd, const char *name)
513 if (name[0] == 'L' && name[1] == '.')
516 if (name[0] == '$' && name[1] == 'L')
519 /* With gcc, the labels go back to starting with '.', so we accept
520 the generic ELF local label syntax as well. */
521 return _bfd_elf_is_local_label_name (abfd, name);
524 /* The microblaze linker (like many others) needs to keep track of
525 the number of relocs that it decides to copy as dynamic relocs in
526 check_relocs for each symbol. This is so that it can later discard
527 them if they are found to be unnecessary. We store the information
528 in a field extending the regular ELF linker hash table. */
530 struct elf32_mb_dyn_relocs
532 struct elf32_mb_dyn_relocs *next;
534 /* The input section of the reloc. */
537 /* Total number of relocs copied for the input section. */
540 /* Number of pc-relative relocs copied for the input section. */
541 bfd_size_type pc_count;
544 /* ELF linker hash entry. */
546 struct elf32_mb_link_hash_entry
548 struct elf_link_hash_entry elf;
550 /* Track dynamic relocs copied for this symbol. */
551 struct elf32_mb_dyn_relocs *dyn_relocs;
555 #define elf32_mb_hash_entry(ent) ((struct elf32_mb_link_hash_entry *)(ent))
557 /* ELF linker hash table. */
559 struct elf32_mb_link_hash_table
561 struct elf_link_hash_table elf;
563 /* Short-cuts to get to dynamic linker sections. */
572 /* Small local sym to section mapping cache. */
573 struct sym_cache sym_sec;
576 /* Get the ELF linker hash table from a link_info structure. */
578 #define elf32_mb_hash_table(p) \
579 (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
580 == MICROBLAZE_ELF_DATA ? ((struct elf32_mb_link_hash_table *) ((p)->hash)) : NULL)
582 /* Create an entry in a microblaze ELF linker hash table. */
584 static struct bfd_hash_entry *
585 link_hash_newfunc (struct bfd_hash_entry *entry,
586 struct bfd_hash_table *table,
589 /* Allocate the structure if it has not already been allocated by a
593 entry = bfd_hash_allocate (table,
594 sizeof (struct elf32_mb_link_hash_entry));
599 /* Call the allocation method of the superclass. */
600 entry = _bfd_elf_link_hash_newfunc (entry, table, string);
603 struct elf32_mb_link_hash_entry *eh;
605 eh = (struct elf32_mb_link_hash_entry *) entry;
606 eh->dyn_relocs = NULL;
612 /* Create a mb ELF linker hash table. */
614 static struct bfd_link_hash_table *
615 microblaze_elf_link_hash_table_create (bfd *abfd)
617 struct elf32_mb_link_hash_table *ret;
618 bfd_size_type amt = sizeof (struct elf32_mb_link_hash_table);
620 ret = (struct elf32_mb_link_hash_table *) bfd_zmalloc (amt);
624 if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
625 sizeof (struct elf32_mb_link_hash_entry),
626 MICROBLAZE_ELF_DATA))
632 return &ret->elf.root;
635 /* Set the values of the small data pointers. */
638 microblaze_elf_final_sdp (struct bfd_link_info *info)
640 struct bfd_link_hash_entry *h;
642 h = bfd_link_hash_lookup (info->hash, RO_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE);
643 if (h != (struct bfd_link_hash_entry *) NULL
644 && h->type == bfd_link_hash_defined)
645 ro_small_data_pointer = (h->u.def.value
646 + h->u.def.section->output_section->vma
647 + h->u.def.section->output_offset);
649 h = bfd_link_hash_lookup (info->hash, RW_SDA_ANCHOR_NAME, FALSE, FALSE, TRUE);
650 if (h != (struct bfd_link_hash_entry *) NULL
651 && h->type == bfd_link_hash_defined)
652 rw_small_data_pointer = (h->u.def.value
653 + h->u.def.section->output_section->vma
654 + h->u.def.section->output_offset);
657 /* This code is taken from elf32-m32r.c
658 There is some attempt to make this function usable for many architectures,
659 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
660 if only to serve as a learning tool.
662 The RELOCATE_SECTION function is called by the new ELF backend linker
663 to handle the relocations for a section.
665 The relocs are always passed as Rela structures; if the section
666 actually uses Rel structures, the r_addend field will always be
669 This function is responsible for adjust the section contents as
670 necessary, and (if using Rela relocs and generating a
671 relocatable output file) adjusting the reloc addend as
674 This function does not have to worry about setting the reloc
675 address or the reloc symbol index.
677 LOCAL_SYMS is a pointer to the swapped in local symbols.
679 LOCAL_SECTIONS is an array giving the section in the input file
680 corresponding to the st_shndx field of each local symbol.
682 The global hash table entry for the global symbols can be found
683 via elf_sym_hashes (input_bfd).
685 When generating relocatable output, this function must handle
686 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
687 going to be the section symbol corresponding to the output
688 section, which means that the addend must be adjusted
692 microblaze_elf_relocate_section (bfd *output_bfd,
693 struct bfd_link_info *info,
695 asection *input_section,
697 Elf_Internal_Rela *relocs,
698 Elf_Internal_Sym *local_syms,
699 asection **local_sections)
701 struct elf32_mb_link_hash_table *htab;
702 Elf_Internal_Shdr *symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
703 struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
704 Elf_Internal_Rela *rel, *relend;
705 int endian = (bfd_little_endian (output_bfd)) ? 0 : 2;
706 /* Assume success. */
707 bfd_boolean ret = TRUE;
709 bfd_vma *local_got_offsets;
711 if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1])
712 microblaze_elf_howto_init ();
714 htab = elf32_mb_hash_table (info);
718 local_got_offsets = elf_local_got_offsets (input_bfd);
720 sreloc = elf_section_data (input_section)->sreloc;
723 relend = relocs + input_section->reloc_count;
724 for (; rel < relend; rel++)
727 reloc_howto_type *howto;
728 unsigned long r_symndx;
729 bfd_vma addend = rel->r_addend;
730 bfd_vma offset = rel->r_offset;
731 struct elf_link_hash_entry *h;
732 Elf_Internal_Sym *sym;
734 const char *sym_name;
735 bfd_reloc_status_type r = bfd_reloc_ok;
736 const char *errmsg = NULL;
737 bfd_boolean unresolved_reloc = FALSE;
740 r_type = ELF32_R_TYPE (rel->r_info);
741 if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max)
743 (*_bfd_error_handler) (_("%s: unknown relocation type %d"),
744 bfd_get_filename (input_bfd), (int) r_type);
745 bfd_set_error (bfd_error_bad_value);
750 howto = microblaze_elf_howto_table[r_type];
751 r_symndx = ELF32_R_SYM (rel->r_info);
753 if (info->relocatable)
755 /* This is a relocatable link. We don't have to change
756 anything, unless the reloc is against a section symbol,
757 in which case we have to adjust according to where the
758 section symbol winds up in the output section. */
760 if (r_symndx >= symtab_hdr->sh_info)
761 /* External symbol. */
765 sym = local_syms + r_symndx;
766 sym_name = "<local symbol>";
767 /* STT_SECTION: symbol is associated with a section. */
768 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
769 /* Symbol isn't associated with a section. Nothing to do. */
772 sec = local_sections[r_symndx];
773 addend += sec->output_offset + sym->st_value;
775 /* This can't be done for USE_REL because it doesn't mean anything
776 and elf_link_input_bfd asserts this stays zero. */
777 /* rel->r_addend = addend; */
781 /* Addends are stored with relocs. We're done. */
784 /* If partial_inplace, we need to store any additional addend
785 back in the section. */
786 if (!howto->partial_inplace)
788 /* ??? Here is a nice place to call a special_function like handler. */
789 r = _bfd_relocate_contents (howto, input_bfd, addend,
797 /* This is a final link. */
800 unresolved_reloc = FALSE;
802 if (r_symndx < symtab_hdr->sh_info)
805 sym = local_syms + r_symndx;
806 sec = local_sections[r_symndx];
809 sym_name = "<local symbol>";
810 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
811 /* r_addend may have changed if the reference section was
813 addend = rel->r_addend;
817 /* External symbol. */
818 bfd_boolean warned ATTRIBUTE_UNUSED;
820 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
821 r_symndx, symtab_hdr, sym_hashes,
823 unresolved_reloc, warned);
824 sym_name = h->root.root.string;
827 /* Sanity check the address. */
828 if (offset > bfd_get_section_limit (input_bfd, input_section))
830 r = bfd_reloc_outofrange;
834 switch ((int) r_type)
836 case (int) R_MICROBLAZE_SRO32 :
840 /* Only relocate if the symbol is defined. */
843 name = bfd_get_section_name (sec->owner, sec);
845 if (strcmp (name, ".sdata2") == 0
846 || strcmp (name, ".sbss2") == 0)
848 if (ro_small_data_pointer == 0)
849 microblaze_elf_final_sdp (info);
850 if (ro_small_data_pointer == 0)
853 r = bfd_reloc_undefined;
857 /* At this point `relocation' contains the object's
859 relocation -= ro_small_data_pointer;
860 /* Now it contains the offset from _SDA2_BASE_. */
861 r = _bfd_final_link_relocate (howto, input_bfd,
868 (*_bfd_error_handler) (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"),
869 bfd_get_filename (input_bfd),
871 microblaze_elf_howto_table[(int) r_type]->name,
872 bfd_get_section_name (sec->owner, sec));
873 /*bfd_set_error (bfd_error_bad_value); ??? why? */
881 case (int) R_MICROBLAZE_SRW32 :
885 /* Only relocate if the symbol is defined. */
888 name = bfd_get_section_name (sec->owner, sec);
890 if (strcmp (name, ".sdata") == 0
891 || strcmp (name, ".sbss") == 0)
893 if (rw_small_data_pointer == 0)
894 microblaze_elf_final_sdp (info);
895 if (rw_small_data_pointer == 0)
898 r = bfd_reloc_undefined;
902 /* At this point `relocation' contains the object's
904 relocation -= rw_small_data_pointer;
905 /* Now it contains the offset from _SDA_BASE_. */
906 r = _bfd_final_link_relocate (howto, input_bfd,
913 (*_bfd_error_handler) (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"),
914 bfd_get_filename (input_bfd),
916 microblaze_elf_howto_table[(int) r_type]->name,
917 bfd_get_section_name (sec->owner, sec));
918 /*bfd_set_error (bfd_error_bad_value); ??? why? */
926 case (int) R_MICROBLAZE_32_SYM_OP_SYM:
927 break; /* Do nothing. */
929 case (int) R_MICROBLAZE_GOTPC_64:
930 relocation = htab->sgotplt->output_section->vma
931 + htab->sgotplt->output_offset;
932 relocation -= (input_section->output_section->vma
933 + input_section->output_offset
934 + offset + INST_WORD_SIZE);
935 relocation += addend;
936 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
937 contents + offset + endian);
938 bfd_put_16 (input_bfd, relocation & 0xffff,
939 contents + offset + endian + INST_WORD_SIZE);
942 case (int) R_MICROBLAZE_PLT_64:
945 if (htab->splt != NULL && h != NULL
946 && h->plt.offset != (bfd_vma) -1)
948 relocation = (htab->splt->output_section->vma
949 + htab->splt->output_offset
951 unresolved_reloc = FALSE;
952 immediate = relocation - (input_section->output_section->vma
953 + input_section->output_offset
954 + offset + INST_WORD_SIZE);
955 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
956 contents + offset + endian);
957 bfd_put_16 (input_bfd, immediate & 0xffff,
958 contents + offset + endian + INST_WORD_SIZE);
962 relocation -= (input_section->output_section->vma
963 + input_section->output_offset
964 + offset + INST_WORD_SIZE);
965 immediate = relocation;
966 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
967 contents + offset + endian);
968 bfd_put_16 (input_bfd, immediate & 0xffff,
969 contents + offset + endian + INST_WORD_SIZE);
974 case (int) R_MICROBLAZE_GOT_64:
976 if (htab->sgot == NULL)
981 if (local_got_offsets == NULL)
983 off = local_got_offsets[r_symndx];
984 /* The LSB indicates whether we've already
985 created relocation. */
990 bfd_put_32 (output_bfd, relocation + addend,
991 htab->sgot->contents + off);
995 Elf_Internal_Rela outrel;
997 if (htab->srelgot == NULL)
999 outrel.r_offset = (htab->sgot->output_section->vma
1000 + htab->sgot->output_offset
1002 outrel.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL);
1003 outrel.r_addend = relocation + addend;
1004 loc = htab->srelgot->contents;
1005 loc += htab->srelgot->reloc_count++
1006 * sizeof (Elf32_External_Rela);
1007 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1009 local_got_offsets[r_symndx] |= 1;
1011 relocation = htab->sgot->output_section->vma
1012 + htab->sgot->output_offset + off
1013 - htab->sgotplt->output_section->vma
1014 - htab->sgotplt->output_offset;
1015 unresolved_reloc = FALSE;
1019 if (htab->sgotplt != NULL && h != NULL
1020 && h->got.offset != (bfd_vma) -1)
1022 bfd_put_32 (output_bfd, relocation + addend,
1023 htab->sgot->contents + h->got.offset);
1024 relocation = htab->sgot->output_section->vma
1025 + htab->sgot->output_offset
1027 - htab->sgotplt->output_section->vma
1028 - htab->sgotplt->output_offset;
1029 unresolved_reloc = FALSE;
1034 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1035 contents + offset + endian);
1036 bfd_put_16 (input_bfd, relocation & 0xffff,
1037 contents + offset + endian + INST_WORD_SIZE);
1041 case (int) R_MICROBLAZE_GOTOFF_64:
1044 unsigned short lo, high;
1045 relocation += addend;
1046 relocation -= htab->sgotplt->output_section->vma
1047 + htab->sgotplt->output_offset;
1048 /* Write this value into correct location. */
1049 immediate = relocation;
1050 lo = immediate & 0x0000ffff;
1051 high = (immediate >> 16) & 0x0000ffff;
1052 bfd_put_16 (input_bfd, high, contents + offset + endian);
1053 bfd_put_16 (input_bfd, lo, contents + offset + INST_WORD_SIZE + endian);
1057 case (int) R_MICROBLAZE_GOTOFF_32:
1059 relocation += addend;
1060 relocation -= htab->sgotplt->output_section->vma
1061 + htab->sgotplt->output_offset;
1062 /* Write this value into correct location. */
1063 bfd_put_32 (input_bfd, relocation, contents + offset);
1067 case (int) R_MICROBLAZE_64_PCREL :
1068 case (int) R_MICROBLAZE_64:
1069 case (int) R_MICROBLAZE_32:
1071 /* r_symndx will be STN_UNDEF (zero) only for relocs against symbols
1072 from removed linkonce sections, or sections discarded by
1074 if (r_symndx == STN_UNDEF || (input_section->flags & SEC_ALLOC) == 0)
1076 relocation += addend;
1077 if (r_type == R_MICROBLAZE_32)
1078 bfd_put_32 (input_bfd, relocation, contents + offset);
1081 if (r_type == R_MICROBLAZE_64_PCREL)
1082 relocation -= (input_section->output_section->vma
1083 + input_section->output_offset
1084 + offset + INST_WORD_SIZE);
1085 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1086 contents + offset + endian);
1087 bfd_put_16 (input_bfd, relocation & 0xffff,
1088 contents + offset + endian + INST_WORD_SIZE);
1095 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1096 || h->root.type != bfd_link_hash_undefweak)
1097 && (!howto->pc_relative
1101 || !h->def_regular))))
1108 || h->root.type == bfd_link_hash_undefweak
1109 || h->root.type == bfd_link_hash_undefined)))
1111 Elf_Internal_Rela outrel;
1115 /* When generating a shared object, these relocations
1116 are copied into the output file to be resolved at run
1119 BFD_ASSERT (sreloc != NULL);
1124 _bfd_elf_section_offset (output_bfd, info, input_section,
1126 if (outrel.r_offset == (bfd_vma) -1)
1128 else if (outrel.r_offset == (bfd_vma) -2)
1130 outrel.r_offset += (input_section->output_section->vma
1131 + input_section->output_offset);
1134 memset (&outrel, 0, sizeof outrel);
1135 /* h->dynindx may be -1 if the symbol was marked to
1138 && ((! info->symbolic && h->dynindx != -1)
1139 || !h->def_regular))
1141 BFD_ASSERT (h->dynindx != -1);
1142 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1143 outrel.r_addend = addend;
1147 if (r_type == R_MICROBLAZE_32)
1149 outrel.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL);
1150 outrel.r_addend = relocation + addend;
1155 (*_bfd_error_handler)
1156 (_("%B: probably compiled without -fPIC?"),
1158 bfd_set_error (bfd_error_bad_value);
1163 loc = sreloc->contents;
1164 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
1165 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1170 relocation += addend;
1171 if (r_type == R_MICROBLAZE_32)
1172 bfd_put_32 (input_bfd, relocation, contents + offset);
1175 if (r_type == R_MICROBLAZE_64_PCREL)
1176 relocation -= (input_section->output_section->vma
1177 + input_section->output_offset
1178 + offset + INST_WORD_SIZE);
1179 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1180 contents + offset + endian);
1181 bfd_put_16 (input_bfd, relocation & 0xffff,
1182 contents + offset + endian + INST_WORD_SIZE);
1189 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1191 relocation, addend);
1198 if (r != bfd_reloc_ok)
1200 /* FIXME: This should be generic enough to go in a utility. */
1204 name = h->root.root.string;
1207 name = (bfd_elf_string_from_elf_section
1208 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1209 if (name == NULL || *name == '\0')
1210 name = bfd_section_name (input_bfd, sec);
1218 case bfd_reloc_overflow:
1219 if (!((*info->callbacks->reloc_overflow)
1220 (info, (h ? &h->root : NULL), name, howto->name,
1221 (bfd_vma) 0, input_bfd, input_section, offset)))
1225 case bfd_reloc_undefined:
1226 if (!((*info->callbacks->undefined_symbol)
1227 (info, name, input_bfd, input_section, offset, TRUE)))
1231 case bfd_reloc_outofrange:
1232 errmsg = _("internal error: out of range error");
1235 case bfd_reloc_notsupported:
1236 errmsg = _("internal error: unsupported relocation error");
1239 case bfd_reloc_dangerous:
1240 errmsg = _("internal error: dangerous error");
1244 errmsg = _("internal error: unknown error");
1247 if (!((*info->callbacks->warning)
1248 (info, errmsg, name, input_bfd, input_section, offset)))
1258 /* Merge backend specific data from an object file to the output
1259 object file when linking.
1261 Note: We only use this hook to catch endian mismatches. */
1263 microblaze_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
1265 /* Check if we have the same endianess. */
1266 if (! _bfd_generic_verify_endian_match (ibfd, obfd))
1273 /* Calculate fixup value for reference. */
1276 calc_fixup (bfd_vma addr, asection *sec)
1280 if (sec == NULL || sec->relax == NULL)
1283 /* Look for addr in relax table, total fixup value. */
1284 for (i = 0; i < sec->relax_count; i++)
1286 if (addr <= sec->relax[i].addr)
1288 fixup += sec->relax[i].size;
1294 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1295 a 32-bit instruction. */
1297 microblaze_bfd_write_imm_value_32 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1299 unsigned long instr = bfd_get_32 (abfd, bfd_addr);
1300 instr &= ~0x0000ffff;
1301 instr |= (val & 0x0000ffff);
1302 bfd_put_32 (abfd, instr, bfd_addr);
1305 /* Read-modify-write into the bfd, an immediate value into appropriate fields of
1306 two consecutive 32-bit instructions. */
1308 microblaze_bfd_write_imm_value_64 (bfd *abfd, bfd_byte *bfd_addr, bfd_vma val)
1310 unsigned long instr_hi;
1311 unsigned long instr_lo;
1313 instr_hi = bfd_get_32 (abfd, bfd_addr);
1314 instr_hi &= ~0x0000ffff;
1315 instr_hi |= ((val >> 16) & 0x0000ffff);
1316 bfd_put_32 (abfd, instr_hi, bfd_addr);
1318 instr_lo = bfd_get_32 (abfd, bfd_addr + INST_WORD_SIZE);
1319 instr_lo &= ~0x0000ffff;
1320 instr_lo |= (val & 0x0000ffff);
1321 bfd_put_32 (abfd, instr_lo, bfd_addr + INST_WORD_SIZE);
1325 microblaze_elf_relax_section (bfd *abfd,
1327 struct bfd_link_info *link_info,
1330 Elf_Internal_Shdr *symtab_hdr;
1331 Elf_Internal_Rela *internal_relocs;
1332 Elf_Internal_Rela *free_relocs = NULL;
1333 Elf_Internal_Rela *irel, *irelend;
1334 bfd_byte *contents = NULL;
1335 bfd_byte *free_contents = NULL;
1340 struct elf_link_hash_entry *sym_hash;
1341 Elf_Internal_Sym *isymbuf, *isymend;
1342 Elf_Internal_Sym *isym;
1347 /* We only do this once per section. We may be able to delete some code
1348 by running multiple passes, but it is not worth it. */
1351 /* Only do this for a text section. */
1352 if (link_info->relocatable
1353 || (sec->flags & SEC_RELOC) == 0
1354 || (sec->reloc_count == 0)
1355 || (sec->flags & SEC_CODE) == 0)
1358 BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0));
1360 /* If this is the first time we have been called for this section,
1361 initialize the cooked size. */
1363 sec->size = sec->rawsize;
1365 /* Get symbols for this section. */
1366 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1367 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1368 symcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
1369 if (isymbuf == NULL)
1370 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount,
1371 0, NULL, NULL, NULL);
1372 BFD_ASSERT (isymbuf != NULL);
1374 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
1375 if (internal_relocs == NULL)
1377 if (! link_info->keep_memory)
1378 free_relocs = internal_relocs;
1380 sec->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
1381 * sizeof (struct relax_table));
1382 if (sec->relax == NULL)
1384 sec->relax_count = 0;
1386 irelend = internal_relocs + sec->reloc_count;
1388 for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1391 if ((ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL)
1392 && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64 ))
1393 continue; /* Can't delete this reloc. */
1395 /* Get the section contents. */
1396 if (contents == NULL)
1398 if (elf_section_data (sec)->this_hdr.contents != NULL)
1399 contents = elf_section_data (sec)->this_hdr.contents;
1402 contents = (bfd_byte *) bfd_malloc (sec->size);
1403 if (contents == NULL)
1405 free_contents = contents;
1407 if (!bfd_get_section_contents (abfd, sec, contents,
1408 (file_ptr) 0, sec->size))
1410 elf_section_data (sec)->this_hdr.contents = contents;
1414 /* Get the value of the symbol referred to by the reloc. */
1415 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1417 /* A local symbol. */
1420 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1421 if (isym->st_shndx == SHN_UNDEF)
1422 sym_sec = bfd_und_section_ptr;
1423 else if (isym->st_shndx == SHN_ABS)
1424 sym_sec = bfd_abs_section_ptr;
1425 else if (isym->st_shndx == SHN_COMMON)
1426 sym_sec = bfd_com_section_ptr;
1428 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1430 symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
1435 struct elf_link_hash_entry *h;
1437 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1438 h = elf_sym_hashes (abfd)[indx];
1439 BFD_ASSERT (h != NULL);
1441 if (h->root.type != bfd_link_hash_defined
1442 && h->root.type != bfd_link_hash_defweak)
1443 /* This appears to be a reference to an undefined
1444 symbol. Just ignore it--it will be caught by the
1445 regular reloc processing. */
1448 symval = (h->root.u.def.value
1449 + h->root.u.def.section->output_section->vma
1450 + h->root.u.def.section->output_offset);
1453 /* If this is a PC-relative reloc, subtract the instr offset from
1454 the symbol value. */
1455 if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_64_PCREL)
1457 symval = symval + irel->r_addend
1459 + sec->output_section->vma
1460 + sec->output_offset);
1463 symval += irel->r_addend;
1465 if ((symval & 0xffff8000) == 0
1466 || (symval & 0xffff8000) == 0xffff8000)
1468 /* We can delete this instruction. */
1469 sec->relax[sec->relax_count].addr = irel->r_offset;
1470 sec->relax[sec->relax_count].size = INST_WORD_SIZE;
1473 /* Rewrite relocation type. */
1474 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1476 case R_MICROBLAZE_64_PCREL:
1477 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1478 (int) R_MICROBLAZE_32_PCREL_LO);
1480 case R_MICROBLAZE_64:
1481 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1482 (int) R_MICROBLAZE_32_LO);
1485 /* Cannot happen. */
1489 } /* Loop through all relocations. */
1491 /* Loop through the relocs again, and see if anything needs to change. */
1492 if (sec->relax_count > 0)
1494 shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1496 sec->relax[sec->relax_count].addr = sec->size;
1498 for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1502 /* Get the new reloc address. */
1503 nraddr = irel->r_offset - calc_fixup (irel->r_offset, sec);
1504 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1508 case R_MICROBLAZE_64_PCREL:
1510 case R_MICROBLAZE_64:
1511 case R_MICROBLAZE_32_LO:
1512 /* If this reloc is against a symbol defined in this
1513 section, we must check the addend to see it will put the value in
1514 range to be adjusted, and hence must be changed. */
1515 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1517 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1518 /* Only handle relocs against .text. */
1519 if (isym->st_shndx == shndx
1520 && ELF32_ST_TYPE (isym->st_info) == STT_SECTION)
1521 irel->r_addend -= calc_fixup (irel->r_addend, sec);
1524 case R_MICROBLAZE_NONE:
1526 /* This was a PC-relative instruction that was
1527 completely resolved. */
1529 bfd_vma target_address;
1530 target_address = irel->r_addend + irel->r_offset;
1531 sfix = calc_fixup (irel->r_offset, sec);
1532 efix = calc_fixup (target_address, sec);
1533 irel->r_addend -= (efix - sfix);
1534 /* Should use HOWTO. */
1535 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset,
1539 case R_MICROBLAZE_64_NONE:
1541 /* This was a PC-relative 64-bit instruction that was
1542 completely resolved. */
1544 bfd_vma target_address;
1545 target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE;
1546 sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, sec);
1547 efix = calc_fixup (target_address, sec);
1548 irel->r_addend -= (efix - sfix);
1549 microblaze_bfd_write_imm_value_32 (abfd, contents + irel->r_offset
1550 + INST_WORD_SIZE, irel->r_addend);
1554 irel->r_offset = nraddr;
1555 } /* Change all relocs in this section. */
1557 /* Look through all other sections. */
1558 for (o = abfd->sections; o != NULL; o = o->next)
1560 Elf_Internal_Rela *irelocs;
1561 Elf_Internal_Rela *irelscan, *irelscanend;
1562 bfd_byte *ocontents;
1565 || (o->flags & SEC_RELOC) == 0
1566 || o->reloc_count == 0)
1569 /* We always cache the relocs. Perhaps, if info->keep_memory is
1570 FALSE, we should free them, if we are permitted to. */
1572 irelocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, TRUE);
1573 if (irelocs == NULL)
1577 irelscanend = irelocs + o->reloc_count;
1578 for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
1580 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
1582 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1584 /* Look at the reloc only if the value has been resolved. */
1585 if (isym->st_shndx == shndx
1586 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
1588 if (ocontents == NULL)
1590 if (elf_section_data (o)->this_hdr.contents != NULL)
1591 ocontents = elf_section_data (o)->this_hdr.contents;
1594 /* We always cache the section contents.
1595 Perhaps, if info->keep_memory is FALSE, we
1596 should free them, if we are permitted to. */
1597 if (o->rawsize == 0)
1598 o->rawsize = o->size;
1599 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
1600 if (ocontents == NULL)
1602 if (!bfd_get_section_contents (abfd, o, ocontents,
1606 elf_section_data (o)->this_hdr.contents = ocontents;
1610 irelscan->r_addend -= calc_fixup (irelscan->r_addend, sec);
1612 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
1614 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1616 /* Look at the reloc only if the value has been resolved. */
1617 if (ocontents == NULL)
1619 if (elf_section_data (o)->this_hdr.contents != NULL)
1620 ocontents = elf_section_data (o)->this_hdr.contents;
1623 /* We always cache the section contents.
1624 Perhaps, if info->keep_memory is FALSE, we
1625 should free them, if we are permitted to. */
1627 if (o->rawsize == 0)
1628 o->rawsize = o->size;
1629 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
1630 if (ocontents == NULL)
1632 if (!bfd_get_section_contents (abfd, o, ocontents,
1636 elf_section_data (o)->this_hdr.contents = ocontents;
1639 irelscan->r_addend -= calc_fixup (irel->r_addend
1644 else if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO)
1645 || (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_LO))
1647 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1649 /* Look at the reloc only if the value has been resolved. */
1650 if (isym->st_shndx == shndx
1651 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
1654 bfd_vma target_address;
1656 if (ocontents == NULL)
1658 if (elf_section_data (o)->this_hdr.contents != NULL)
1659 ocontents = elf_section_data (o)->this_hdr.contents;
1662 /* We always cache the section contents.
1663 Perhaps, if info->keep_memory is FALSE, we
1664 should free them, if we are permitted to. */
1665 if (o->rawsize == 0)
1666 o->rawsize = o->size;
1667 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
1668 if (ocontents == NULL)
1670 if (!bfd_get_section_contents (abfd, o, ocontents,
1674 elf_section_data (o)->this_hdr.contents = ocontents;
1678 unsigned long instr = bfd_get_32 (abfd, ocontents + irelscan->r_offset);
1679 immediate = instr & 0x0000ffff;
1680 target_address = immediate;
1681 offset = calc_fixup (target_address, sec);
1682 immediate -= offset;
1683 irelscan->r_addend -= offset;
1684 microblaze_bfd_write_imm_value_32 (abfd, ocontents + irelscan->r_offset,
1685 irelscan->r_addend);
1689 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64)
1691 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1693 /* Look at the reloc only if the value has been resolved. */
1694 if (isym->st_shndx == shndx
1695 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
1699 if (ocontents == NULL)
1701 if (elf_section_data (o)->this_hdr.contents != NULL)
1702 ocontents = elf_section_data (o)->this_hdr.contents;
1705 /* We always cache the section contents.
1706 Perhaps, if info->keep_memory is FALSE, we
1707 should free them, if we are permitted to. */
1709 if (o->rawsize == 0)
1710 o->rawsize = o->size;
1711 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
1712 if (ocontents == NULL)
1714 if (!bfd_get_section_contents (abfd, o, ocontents,
1718 elf_section_data (o)->this_hdr.contents = ocontents;
1721 unsigned long instr_hi = bfd_get_32 (abfd, ocontents
1722 + irelscan->r_offset);
1723 unsigned long instr_lo = bfd_get_32 (abfd, ocontents
1724 + irelscan->r_offset
1726 immediate = (instr_hi & 0x0000ffff) << 16;
1727 immediate |= (instr_lo & 0x0000ffff);
1728 offset = calc_fixup (irelscan->r_addend, sec);
1729 immediate -= offset;
1730 irelscan->r_addend -= offset;
1733 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
1735 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1737 /* Look at the reloc only if the value has been resolved. */
1738 if (isym->st_shndx == shndx
1739 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
1742 bfd_vma target_address;
1744 if (ocontents == NULL)
1746 if (elf_section_data (o)->this_hdr.contents != NULL)
1747 ocontents = elf_section_data (o)->this_hdr.contents;
1750 /* We always cache the section contents.
1751 Perhaps, if info->keep_memory is FALSE, we
1752 should free them, if we are permitted to. */
1753 if (o->rawsize == 0)
1754 o->rawsize = o->size;
1755 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
1756 if (ocontents == NULL)
1758 if (!bfd_get_section_contents (abfd, o, ocontents,
1762 elf_section_data (o)->this_hdr.contents = ocontents;
1765 unsigned long instr_hi = bfd_get_32 (abfd, ocontents
1766 + irelscan->r_offset);
1767 unsigned long instr_lo = bfd_get_32 (abfd, ocontents
1768 + irelscan->r_offset
1770 immediate = (instr_hi & 0x0000ffff) << 16;
1771 immediate |= (instr_lo & 0x0000ffff);
1772 target_address = immediate;
1773 offset = calc_fixup (target_address, sec);
1774 immediate -= offset;
1775 irelscan->r_addend -= offset;
1776 microblaze_bfd_write_imm_value_64 (abfd, ocontents
1777 + irelscan->r_offset, immediate);
1783 /* Adjust the local symbols defined in this section. */
1784 isymend = isymbuf + symtab_hdr->sh_info;
1785 for (isym = isymbuf; isym < isymend; isym++)
1787 if (isym->st_shndx == shndx)
1788 isym->st_value =- calc_fixup (isym->st_value, sec);
1791 /* Now adjust the global symbols defined in this section. */
1792 isym = isymbuf + symtab_hdr->sh_info;
1793 isymend = isymbuf + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
1794 for (sym_index = 0; isym < isymend; isym++, sym_index++)
1796 sym_hash = elf_sym_hashes (abfd)[sym_index];
1797 if (isym->st_shndx == shndx
1798 && (sym_hash->root.type == bfd_link_hash_defined
1799 || sym_hash->root.type == bfd_link_hash_defweak)
1800 && sym_hash->root.u.def.section == sec)
1802 sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value,
1807 /* Physically move the code and change the cooked size. */
1808 dest = sec->relax[0].addr;
1809 for (i = 0; i < sec->relax_count; i++)
1812 src = sec->relax[i].addr + sec->relax[i].size;
1813 len = sec->relax[i+1].addr - sec->relax[i].addr - sec->relax[i].size;
1815 memmove (contents + dest, contents + src, len);
1816 sec->size -= sec->relax[i].size;
1820 elf_section_data (sec)->relocs = internal_relocs;
1823 elf_section_data (sec)->this_hdr.contents = contents;
1824 free_contents = NULL;
1826 symtab_hdr->contents = (bfd_byte *) isymbuf;
1829 if (free_relocs != NULL)
1835 if (free_contents != NULL)
1837 if (!link_info->keep_memory)
1838 free (free_contents);
1840 /* Cache the section contents for elf_link_input_bfd. */
1841 elf_section_data (sec)->this_hdr.contents = contents;
1842 free_contents = NULL;
1845 if (sec->relax_count == 0)
1856 if (free_relocs != NULL)
1858 if (free_contents != NULL)
1859 free (free_contents);
1860 if (sec->relax != NULL)
1864 sec->relax_count = 0;
1869 /* Return the section that should be marked against GC for a given
1873 microblaze_elf_gc_mark_hook (asection *sec,
1874 struct bfd_link_info * info,
1875 Elf_Internal_Rela * rel,
1876 struct elf_link_hash_entry * h,
1877 Elf_Internal_Sym * sym)
1880 switch (ELF32_R_TYPE (rel->r_info))
1882 case R_MICROBLAZE_GNU_VTINHERIT:
1883 case R_MICROBLAZE_GNU_VTENTRY:
1887 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
1890 /* Update the got entry reference counts for the section being removed. */
1893 microblaze_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
1894 struct bfd_link_info * info ATTRIBUTE_UNUSED,
1895 asection * sec ATTRIBUTE_UNUSED,
1896 const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
1903 #define PLT_ENTRY_SIZE 16
1905 #define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
1906 #define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
1907 #define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
1908 #define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
1909 #define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
1911 /* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
1912 shortcuts to them in our hash table. */
1915 create_got_section (bfd *dynobj, struct bfd_link_info *info)
1917 struct elf32_mb_link_hash_table *htab;
1919 if (! _bfd_elf_create_got_section (dynobj, info))
1921 htab = elf32_mb_hash_table (info);
1925 htab->sgot = bfd_get_linker_section (dynobj, ".got");
1926 htab->sgotplt = bfd_get_linker_section (dynobj, ".got.plt");
1927 if (!htab->sgot || !htab->sgotplt)
1930 if ((htab->srelgot = bfd_get_linker_section (dynobj, ".rela.got")) == NULL)
1931 htab->srelgot = bfd_make_section_anyway (dynobj, ".rela.got");
1932 if (htab->srelgot == NULL
1933 || ! bfd_set_section_flags (dynobj, htab->srelgot, SEC_ALLOC
1937 | SEC_LINKER_CREATED
1939 || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
1944 /* Look through the relocs for a section during the first phase. */
1947 microblaze_elf_check_relocs (bfd * abfd,
1948 struct bfd_link_info * info,
1950 const Elf_Internal_Rela * relocs)
1952 Elf_Internal_Shdr * symtab_hdr;
1953 struct elf_link_hash_entry ** sym_hashes;
1954 struct elf_link_hash_entry ** sym_hashes_end;
1955 const Elf_Internal_Rela * rel;
1956 const Elf_Internal_Rela * rel_end;
1957 struct elf32_mb_link_hash_table *htab;
1958 asection *sreloc = NULL;
1960 if (info->relocatable)
1963 htab = elf32_mb_hash_table (info);
1967 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1968 sym_hashes = elf_sym_hashes (abfd);
1969 sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
1970 if (!elf_bad_symtab (abfd))
1971 sym_hashes_end -= symtab_hdr->sh_info;
1973 rel_end = relocs + sec->reloc_count;
1975 for (rel = relocs; rel < rel_end; rel++)
1977 unsigned int r_type;
1978 struct elf_link_hash_entry * h;
1979 unsigned long r_symndx;
1981 r_symndx = ELF32_R_SYM (rel->r_info);
1982 r_type = ELF32_R_TYPE (rel->r_info);
1984 if (r_symndx < symtab_hdr->sh_info)
1987 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
1991 /* This relocation describes the C++ object vtable hierarchy.
1992 Reconstruct it for later use during GC. */
1993 case R_MICROBLAZE_GNU_VTINHERIT:
1994 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1998 /* This relocation describes which C++ vtable entries are actually
1999 used. Record for later use during GC. */
2000 case R_MICROBLAZE_GNU_VTENTRY:
2001 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
2005 /* This relocation requires .plt entry. */
2006 case R_MICROBLAZE_PLT_64:
2010 h->plt.refcount += 1;
2014 /* This relocation requires .got entry. */
2015 case R_MICROBLAZE_GOT_64:
2016 if (htab->sgot == NULL)
2018 if (htab->elf.dynobj == NULL)
2019 htab->elf.dynobj = abfd;
2020 if (!create_got_section (htab->elf.dynobj, info))
2025 h->got.refcount += 1;
2029 bfd_signed_vma *local_got_refcounts;
2031 /* This is a global offset table entry for a local symbol. */
2032 local_got_refcounts = elf_local_got_refcounts (abfd);
2033 if (local_got_refcounts == NULL)
2037 size = symtab_hdr->sh_info;
2038 size *= sizeof (bfd_signed_vma);
2039 local_got_refcounts = bfd_zalloc (abfd, size);
2040 if (local_got_refcounts == NULL)
2042 elf_local_got_refcounts (abfd) = local_got_refcounts;
2044 local_got_refcounts[r_symndx] += 1;
2048 case R_MICROBLAZE_64:
2049 case R_MICROBLAZE_64_PCREL:
2050 case R_MICROBLAZE_32:
2052 if (h != NULL && !info->shared)
2054 /* we may need a copy reloc. */
2057 /* we may also need a .plt entry. */
2058 h->plt.refcount += 1;
2059 if (ELF32_R_TYPE (rel->r_info) != R_MICROBLAZE_64_PCREL)
2060 h->pointer_equality_needed = 1;
2064 /* If we are creating a shared library, and this is a reloc
2065 against a global symbol, or a non PC relative reloc
2066 against a local symbol, then we need to copy the reloc
2067 into the shared library. However, if we are linking with
2068 -Bsymbolic, we do not need to copy a reloc against a
2069 global symbol which is defined in an object we are
2070 including in the link (i.e., DEF_REGULAR is set). At
2071 this point we have not seen all the input files, so it is
2072 possible that DEF_REGULAR is not set now but will be set
2073 later (it is never cleared). In case of a weak definition,
2074 DEF_REGULAR may be cleared later by a strong definition in
2075 a shared library. We account for that possibility below by
2076 storing information in the relocs_copied field of the hash
2077 table entry. A similar situation occurs when creating
2078 shared libraries and symbol visibility changes render the
2081 If on the other hand, we are creating an executable, we
2082 may need to keep relocations for symbols satisfied by a
2083 dynamic library if we manage to avoid copy relocs for the
2087 && (sec->flags & SEC_ALLOC) != 0
2088 && (r_type != R_MICROBLAZE_64_PCREL
2090 && (! info->symbolic
2091 || h->root.type == bfd_link_hash_defweak
2092 || !h->def_regular))))
2094 && (sec->flags & SEC_ALLOC) != 0
2096 && (h->root.type == bfd_link_hash_defweak
2097 || !h->def_regular)))
2099 struct elf32_mb_dyn_relocs *p;
2100 struct elf32_mb_dyn_relocs **head;
2102 /* When creating a shared object, we must copy these
2103 relocs into the output file. We create a reloc
2104 section in dynobj and make room for the reloc. */
2110 unsigned int strndx = elf_elfheader (abfd)->e_shstrndx;
2111 unsigned int shnam = _bfd_elf_single_rel_hdr (sec)->sh_name;
2113 name = bfd_elf_string_from_elf_section (abfd, strndx, shnam);
2117 if (strncmp (name, ".rela", 5) != 0
2118 || strcmp (bfd_get_section_name (abfd, sec),
2121 (*_bfd_error_handler)
2122 (_("%B: bad relocation section name `%s\'"),
2126 if (htab->elf.dynobj == NULL)
2127 htab->elf.dynobj = abfd;
2128 dynobj = htab->elf.dynobj;
2130 sreloc = bfd_get_linker_section (dynobj, name);
2135 flags = (SEC_HAS_CONTENTS | SEC_READONLY
2136 | SEC_IN_MEMORY | SEC_LINKER_CREATED);
2137 if ((sec->flags & SEC_ALLOC) != 0)
2138 flags |= SEC_ALLOC | SEC_LOAD;
2139 sreloc = bfd_make_section_anyway_with_flags (dynobj,
2143 || ! bfd_set_section_alignment (dynobj, sreloc, 2))
2146 elf_section_data (sec)->sreloc = sreloc;
2149 /* If this is a global symbol, we count the number of
2150 relocations we need for this symbol. */
2152 head = &((struct elf32_mb_link_hash_entry *) h)->dyn_relocs;
2155 /* Track dynamic relocs needed for local syms too.
2156 We really need local syms available to do this
2160 Elf_Internal_Sym *isym;
2163 isym = bfd_sym_from_r_symndx (&htab->sym_sec,
2168 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2172 vpp = &elf_section_data (s)->local_dynrel;
2173 head = (struct elf32_mb_dyn_relocs **) vpp;
2177 if (p == NULL || p->sec != sec)
2179 bfd_size_type amt = sizeof *p;
2180 p = ((struct elf32_mb_dyn_relocs *)
2181 bfd_alloc (htab->elf.dynobj, amt));
2192 if (r_type == R_MICROBLAZE_64_PCREL)
2204 microblaze_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
2206 struct elf32_mb_link_hash_table *htab;
2208 htab = elf32_mb_hash_table (info);
2212 if (!htab->sgot && !create_got_section (dynobj, info))
2215 if (!_bfd_elf_create_dynamic_sections (dynobj, info))
2218 htab->splt = bfd_get_linker_section (dynobj, ".plt");
2219 htab->srelplt = bfd_get_linker_section (dynobj, ".rela.plt");
2220 htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
2222 htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
2224 if (!htab->splt || !htab->srelplt || !htab->sdynbss
2225 || (!info->shared && !htab->srelbss))
2231 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2234 microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
2235 struct elf_link_hash_entry *dir,
2236 struct elf_link_hash_entry *ind)
2238 struct elf32_mb_link_hash_entry *edir, *eind;
2240 edir = (struct elf32_mb_link_hash_entry *) dir;
2241 eind = (struct elf32_mb_link_hash_entry *) ind;
2243 if (eind->dyn_relocs != NULL)
2245 if (edir->dyn_relocs != NULL)
2247 struct elf32_mb_dyn_relocs **pp;
2248 struct elf32_mb_dyn_relocs *p;
2250 if (ind->root.type == bfd_link_hash_indirect)
2253 /* Add reloc counts against the weak sym to the strong sym
2254 list. Merge any entries against the same section. */
2255 for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
2257 struct elf32_mb_dyn_relocs *q;
2259 for (q = edir->dyn_relocs; q != NULL; q = q->next)
2260 if (q->sec == p->sec)
2262 q->pc_count += p->pc_count;
2263 q->count += p->count;
2270 *pp = edir->dyn_relocs;
2273 edir->dyn_relocs = eind->dyn_relocs;
2274 eind->dyn_relocs = NULL;
2277 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
2281 microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2282 struct elf_link_hash_entry *h)
2284 struct elf32_mb_link_hash_table *htab;
2285 struct elf32_mb_link_hash_entry * eh;
2286 struct elf32_mb_dyn_relocs *p;
2287 asection *sdynbss, *s;
2288 unsigned int power_of_two;
2291 htab = elf32_mb_hash_table (info);
2295 /* If this is a function, put it in the procedure linkage table. We
2296 will fill in the contents of the procedure linkage table later,
2297 when we know the address of the .got section. */
2298 if (h->type == STT_FUNC
2301 if (h->plt.refcount <= 0
2302 || SYMBOL_CALLS_LOCAL (info, h)
2303 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
2304 && h->root.type == bfd_link_hash_undefweak))
2306 /* This case can occur if we saw a PLT reloc in an input
2307 file, but the symbol was never referred to by a dynamic
2308 object, or if all references were garbage collected. In
2309 such a case, we don't actually need to build a procedure
2310 linkage table, and we can just do a PC32 reloc instead. */
2311 h->plt.offset = (bfd_vma) -1;
2318 /* It's possible that we incorrectly decided a .plt reloc was
2319 needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
2320 check_relocs. We can't decide accurately between function and
2321 non-function syms in check-relocs; Objects loaded later in
2322 the link may change h->type. So fix it now. */
2323 h->plt.offset = (bfd_vma) -1;
2325 /* If this is a weak symbol, and there is a real definition, the
2326 processor independent code will have arranged for us to see the
2327 real definition first, and we can just use the same value. */
2328 if (h->u.weakdef != NULL)
2330 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2331 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2332 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2333 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2337 /* This is a reference to a symbol defined by a dynamic object which
2338 is not a function. */
2340 /* If we are creating a shared library, we must presume that the
2341 only references to the symbol are via the global offset table.
2342 For such cases we need not do anything here; the relocations will
2343 be handled correctly by relocate_section. */
2347 /* If there are no references to this symbol that do not use the
2348 GOT, we don't need to generate a copy reloc. */
2349 if (!h->non_got_ref)
2352 /* If -z nocopyreloc was given, we won't generate them either. */
2353 if (info->nocopyreloc)
2359 eh = (struct elf32_mb_link_hash_entry *) h;
2360 for (p = eh->dyn_relocs; p != NULL; p = p->next)
2362 s = p->sec->output_section;
2363 if (s != NULL && (s->flags & SEC_READONLY) != 0)
2367 /* If we didn't find any dynamic relocs in read-only sections, then
2368 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
2375 /* We must allocate the symbol in our .dynbss section, which will
2376 become part of the .bss section of the executable. There will be
2377 an entry for this symbol in the .dynsym section. The dynamic
2378 object will contain position independent code, so all references
2379 from the dynamic object to this symbol will go through the global
2380 offset table. The dynamic linker will use the .dynsym entry to
2381 determine the address it must put in the global offset table, so
2382 both the dynamic object and the regular object will refer to the
2383 same memory location for the variable. */
2385 /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
2386 to copy the initial value out of the dynamic object and into the
2387 runtime process image. */
2388 dynobj = elf_hash_table (info)->dynobj;
2389 BFD_ASSERT (dynobj != NULL);
2390 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2392 htab->srelbss->size += sizeof (Elf32_External_Rela);
2396 /* We need to figure out the alignment required for this symbol. I
2397 have no idea how ELF linkers handle this. */
2398 power_of_two = bfd_log2 (h->size);
2399 if (power_of_two > 3)
2402 sdynbss = htab->sdynbss;
2403 /* Apply the required alignment. */
2404 sdynbss->size = BFD_ALIGN (sdynbss->size, (bfd_size_type) (1 << power_of_two));
2405 if (power_of_two > bfd_get_section_alignment (dynobj, sdynbss))
2407 if (! bfd_set_section_alignment (dynobj, sdynbss, power_of_two))
2411 /* Define the symbol as being at this point in the section. */
2412 h->root.u.def.section = sdynbss;
2413 h->root.u.def.value = sdynbss->size;
2415 /* Increment the section size to make room for the symbol. */
2416 sdynbss->size += h->size;
2420 /* Allocate space in .plt, .got and associated reloc sections for
2424 allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
2426 struct bfd_link_info *info;
2427 struct elf32_mb_link_hash_table *htab;
2428 struct elf32_mb_link_hash_entry *eh;
2429 struct elf32_mb_dyn_relocs *p;
2431 if (h->root.type == bfd_link_hash_indirect)
2434 info = (struct bfd_link_info *) dat;
2435 htab = elf32_mb_hash_table (info);
2439 if (htab->elf.dynamic_sections_created
2440 && h->plt.refcount > 0)
2442 /* Make sure this symbol is output as a dynamic symbol.
2443 Undefined weak syms won't yet be marked as dynamic. */
2444 if (h->dynindx == -1
2445 && !h->forced_local)
2447 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2451 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
2453 asection *s = htab->splt;
2455 /* The first entry in .plt is reserved. */
2457 s->size = PLT_ENTRY_SIZE;
2459 h->plt.offset = s->size;
2461 /* If this symbol is not defined in a regular file, and we are
2462 not generating a shared library, then set the symbol to this
2463 location in the .plt. This is required to make function
2464 pointers compare as equal between the normal executable and
2465 the shared library. */
2469 h->root.u.def.section = s;
2470 h->root.u.def.value = h->plt.offset;
2473 /* Make room for this entry. */
2474 s->size += PLT_ENTRY_SIZE;
2476 /* We also need to make an entry in the .got.plt section, which
2477 will be placed in the .got section by the linker script. */
2478 htab->sgotplt->size += 4;
2480 /* We also need to make an entry in the .rel.plt section. */
2481 htab->srelplt->size += sizeof (Elf32_External_Rela);
2485 h->plt.offset = (bfd_vma) -1;
2491 h->plt.offset = (bfd_vma) -1;
2495 if (h->got.refcount > 0)
2499 /* Make sure this symbol is output as a dynamic symbol.
2500 Undefined weak syms won't yet be marked as dynamic. */
2501 if (h->dynindx == -1
2502 && !h->forced_local)
2504 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2509 h->got.offset = s->size;
2511 htab->srelgot->size += sizeof (Elf32_External_Rela);
2514 h->got.offset = (bfd_vma) -1;
2516 eh = (struct elf32_mb_link_hash_entry *) h;
2517 if (eh->dyn_relocs == NULL)
2520 /* In the shared -Bsymbolic case, discard space allocated for
2521 dynamic pc-relative relocs against symbols which turn out to be
2522 defined in regular objects. For the normal shared case, discard
2523 space for pc-relative relocs that have become local due to symbol
2524 visibility changes. */
2532 struct elf32_mb_dyn_relocs **pp;
2534 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
2536 p->count -= p->pc_count;
2547 /* For the non-shared case, discard space for relocs against
2548 symbols which turn out to need copy relocs or are not
2554 || (htab->elf.dynamic_sections_created
2555 && (h->root.type == bfd_link_hash_undefweak
2556 || h->root.type == bfd_link_hash_undefined))))
2558 /* Make sure this symbol is output as a dynamic symbol.
2559 Undefined weak syms won't yet be marked as dynamic. */
2560 if (h->dynindx == -1
2561 && !h->forced_local)
2563 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2567 /* If that succeeded, we know we'll be keeping all the
2569 if (h->dynindx != -1)
2573 eh->dyn_relocs = NULL;
2578 /* Finally, allocate space. */
2579 for (p = eh->dyn_relocs; p != NULL; p = p->next)
2581 asection *sreloc = elf_section_data (p->sec)->sreloc;
2582 sreloc->size += p->count * sizeof (Elf32_External_Rela);
2588 /* Set the sizes of the dynamic sections. */
2591 microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2592 struct bfd_link_info *info)
2594 struct elf32_mb_link_hash_table *htab;
2599 htab = elf32_mb_hash_table (info);
2603 dynobj = htab->elf.dynobj;
2604 BFD_ASSERT (dynobj != NULL);
2606 /* Set up .got offsets for local syms, and space for local dynamic
2608 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
2610 bfd_signed_vma *local_got;
2611 bfd_signed_vma *end_local_got;
2612 bfd_size_type locsymcount;
2613 Elf_Internal_Shdr *symtab_hdr;
2616 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
2619 for (s = ibfd->sections; s != NULL; s = s->next)
2621 struct elf32_mb_dyn_relocs *p;
2623 for (p = ((struct elf32_mb_dyn_relocs *)
2624 elf_section_data (s)->local_dynrel);
2628 if (!bfd_is_abs_section (p->sec)
2629 && bfd_is_abs_section (p->sec->output_section))
2631 /* Input section has been discarded, either because
2632 it is a copy of a linkonce section or due to
2633 linker script /DISCARD/, so we'll be discarding
2636 else if (p->count != 0)
2638 srel = elf_section_data (p->sec)->sreloc;
2639 srel->size += p->count * sizeof (Elf32_External_Rela);
2640 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
2641 info->flags |= DF_TEXTREL;
2646 local_got = elf_local_got_refcounts (ibfd);
2650 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
2651 locsymcount = symtab_hdr->sh_info;
2652 end_local_got = local_got + locsymcount;
2654 srel = htab->srelgot;
2656 for (; local_got < end_local_got; ++local_got)
2660 *local_got = s->size;
2663 srel->size += sizeof (Elf32_External_Rela);
2666 *local_got = (bfd_vma) -1;
2670 /* Allocate global sym .plt and .got entries, and space for global
2671 sym dynamic relocs. */
2672 elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
2674 if (elf_hash_table (info)->dynamic_sections_created)
2676 /* Make space for the trailing nop in .plt. */
2677 if (htab->splt->size > 0)
2678 htab->splt->size += 4;
2681 /* The check_relocs and adjust_dynamic_symbol entry points have
2682 determined the sizes of the various dynamic sections. Allocate
2684 for (s = dynobj->sections; s != NULL; s = s->next)
2687 bfd_boolean strip = FALSE;
2689 if ((s->flags & SEC_LINKER_CREATED) == 0)
2692 /* It's OK to base decisions on the section name, because none
2693 of the dynobj section names depend upon the input files. */
2694 name = bfd_get_section_name (dynobj, s);
2696 if (strncmp (name, ".rela", 5) == 0)
2700 /* If we don't need this section, strip it from the
2701 output file. This is to handle .rela.bss and
2702 .rela.plt. We must create it in
2703 create_dynamic_sections, because it must be created
2704 before the linker maps input sections to output
2705 sections. The linker does that before
2706 adjust_dynamic_symbol is called, and it is that
2707 function which decides whether anything needs to go
2708 into these sections. */
2713 /* We use the reloc_count field as a counter if we need
2714 to copy relocs into the output file. */
2718 else if (s != htab->splt && s != htab->sgot && s != htab->sgotplt)
2720 /* It's not one of our sections, so don't allocate space. */
2726 s->flags |= SEC_EXCLUDE;
2730 /* Allocate memory for the section contents. */
2731 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
2732 Unused entries should be reclaimed before the section's contents
2733 are written out, but at the moment this does not happen. Thus in
2734 order to prevent writing out garbage, we initialise the section's
2735 contents to zero. */
2736 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2737 if (s->contents == NULL && s->size != 0)
2741 if (elf_hash_table (info)->dynamic_sections_created)
2743 /* Add some entries to the .dynamic section. We fill in the
2744 values later, in microblaze_elf_finish_dynamic_sections, but we
2745 must add the entries now so that we get the correct size for
2746 the .dynamic section. The DT_DEBUG entry is filled in by the
2747 dynamic linker and used by the debugger. */
2748 #define add_dynamic_entry(TAG, VAL) \
2749 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
2751 if (info->executable)
2753 if (!add_dynamic_entry (DT_DEBUG, 0))
2757 if (!add_dynamic_entry (DT_RELA, 0)
2758 || !add_dynamic_entry (DT_RELASZ, 0)
2759 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
2762 if (htab->splt->size != 0)
2764 if (!add_dynamic_entry (DT_PLTGOT, 0)
2765 || !add_dynamic_entry (DT_PLTRELSZ, 0)
2766 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
2767 || !add_dynamic_entry (DT_JMPREL, 0)
2768 || !add_dynamic_entry (DT_BIND_NOW, 1))
2772 if (info->flags & DF_TEXTREL)
2774 if (!add_dynamic_entry (DT_TEXTREL, 0))
2778 #undef add_dynamic_entry
2782 /* Finish up dynamic symbol handling. We set the contents of various
2783 dynamic sections here. */
2786 microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
2787 struct bfd_link_info *info,
2788 struct elf_link_hash_entry *h,
2789 Elf_Internal_Sym *sym)
2791 struct elf32_mb_link_hash_table *htab;
2793 htab = elf32_mb_hash_table (info);
2797 if (h->plt.offset != (bfd_vma) -1)
2802 Elf_Internal_Rela rela;
2808 /* This symbol has an entry in the procedure linkage table. Set
2810 BFD_ASSERT (h->dynindx != -1);
2813 srela = htab->srelplt;
2814 sgotplt = htab->sgotplt;
2815 BFD_ASSERT (splt != NULL && srela != NULL && sgotplt != NULL);
2817 plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* first entry reserved. */
2818 got_offset = (plt_index + 3) * 4; /* 3 reserved ??? */
2819 got_addr = got_offset;
2821 /* For non-PIC objects we need absolute address of the GOT entry. */
2823 got_addr += htab->sgotplt->output_section->vma + sgotplt->output_offset;
2825 /* Fill in the entry in the procedure linkage table. */
2826 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_0 + ((got_addr >> 16) & 0xffff),
2827 splt->contents + h->plt.offset);
2829 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1 + (got_addr & 0xffff),
2830 splt->contents + h->plt.offset + 4);
2832 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1_NOPIC + (got_addr & 0xffff),
2833 splt->contents + h->plt.offset + 4);
2834 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_2,
2835 splt->contents + h->plt.offset + 8);
2836 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_3,
2837 splt->contents + h->plt.offset + 12);
2839 /* Any additions to the .got section??? */
2840 /* bfd_put_32 (output_bfd,
2841 splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
2842 sgotplt->contents + got_offset); */
2844 /* Fill in the entry in the .rela.plt section. */
2845 rela.r_offset = (sgotplt->output_section->vma
2846 + sgotplt->output_offset
2848 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_JUMP_SLOT);
2850 loc = srela->contents;
2851 loc += plt_index * sizeof (Elf32_External_Rela);
2852 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
2854 if (!h->def_regular)
2856 /* Mark the symbol as undefined, rather than as defined in
2857 the .plt section. Zero the value. */
2858 sym->st_shndx = SHN_UNDEF;
2863 if (h->got.offset != (bfd_vma) -1)
2867 Elf_Internal_Rela rela;
2870 /* This symbol has an entry in the global offset table. Set it
2874 srela = htab->srelgot;
2875 BFD_ASSERT (sgot != NULL && srela != NULL);
2877 rela.r_offset = (sgot->output_section->vma
2878 + sgot->output_offset
2879 + (h->got.offset &~ (bfd_vma) 1));
2881 /* If this is a -Bsymbolic link, and the symbol is defined
2882 locally, we just want to emit a RELATIVE reloc. Likewise if
2883 the symbol was forced to be local because of a version file.
2884 The entry in the global offset table will already have been
2885 initialized in the relocate_section function. */
2887 && (info->symbolic || h->dynindx == -1)
2890 asection *sec = h->root.u.def.section;
2891 rela.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL);
2892 rela.r_addend = (h->root.u.def.value
2893 + sec->output_section->vma
2894 + sec->output_offset);
2898 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_GLOB_DAT);
2902 bfd_put_32 (output_bfd, (bfd_vma) 0,
2903 sgot->contents + (h->got.offset &~ (bfd_vma) 1));
2904 loc = srela->contents;
2905 loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
2906 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
2912 Elf_Internal_Rela rela;
2915 /* This symbols needs a copy reloc. Set it up. */
2917 BFD_ASSERT (h->dynindx != -1);
2919 s = bfd_get_linker_section (htab->elf.dynobj, ".rela.bss");
2920 BFD_ASSERT (s != NULL);
2922 rela.r_offset = (h->root.u.def.value
2923 + h->root.u.def.section->output_section->vma
2924 + h->root.u.def.section->output_offset);
2925 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_COPY);
2927 loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
2928 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
2931 /* Mark some specially defined symbols as absolute. */
2932 if (h == htab->elf.hdynamic
2933 || h == htab->elf.hgot
2934 || h == htab->elf.hplt)
2935 sym->st_shndx = SHN_ABS;
2941 /* Finish up the dynamic sections. */
2944 microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
2945 struct bfd_link_info *info)
2948 asection *sdyn, *sgot;
2949 struct elf32_mb_link_hash_table *htab;
2951 htab = elf32_mb_hash_table (info);
2955 dynobj = htab->elf.dynobj;
2957 sdyn = bfd_get_linker_section (dynobj, ".dynamic");
2959 if (htab->elf.dynamic_sections_created)
2962 Elf32_External_Dyn *dyncon, *dynconend;
2964 splt = bfd_get_linker_section (dynobj, ".plt");
2965 BFD_ASSERT (splt != NULL && sdyn != NULL);
2967 dyncon = (Elf32_External_Dyn *) sdyn->contents;
2968 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
2969 for (; dyncon < dynconend; dyncon++)
2971 Elf_Internal_Dyn dyn;
2975 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
2979 case DT_PLTGOT: name = ".got.plt"; size = FALSE; break;
2980 case DT_PLTRELSZ: name = ".rela.plt"; size = TRUE; break;
2981 case DT_JMPREL: name = ".rela.plt"; size = FALSE; break;
2982 case DT_RELA: name = ".rela.dyn"; size = FALSE; break;
2983 case DT_RELASZ: name = ".rela.dyn"; size = TRUE; break;
2984 default: name = NULL; size = FALSE; break;
2991 s = bfd_get_section_by_name (output_bfd, name);
2997 dyn.d_un.d_ptr = s->vma;
2999 dyn.d_un.d_val = s->size;
3001 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
3005 /* Clear the first entry in the procedure linkage table,
3006 and put a nop in the last four bytes. */
3009 memset (splt->contents, 0, PLT_ENTRY_SIZE);
3010 bfd_put_32 (output_bfd, (bfd_vma) 0x80000000 /* nop. */,
3011 splt->contents + splt->size - 4);
3014 elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
3017 /* Set the first entry in the global offset table to the address of
3018 the dynamic section. */
3019 sgot = bfd_get_linker_section (dynobj, ".got.plt");
3020 if (sgot && sgot->size > 0)
3023 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
3025 bfd_put_32 (output_bfd,
3026 sdyn->output_section->vma + sdyn->output_offset,
3028 elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
3031 if (htab->sgot && htab->sgot->size > 0)
3032 elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 4;
3037 /* Hook called by the linker routine which adds symbols from an object
3038 file. We use it to put .comm items in .sbss, and not .bss. */
3041 microblaze_elf_add_symbol_hook (bfd *abfd,
3042 struct bfd_link_info *info,
3043 Elf_Internal_Sym *sym,
3044 const char **namep ATTRIBUTE_UNUSED,
3045 flagword *flagsp ATTRIBUTE_UNUSED,
3049 if (sym->st_shndx == SHN_COMMON
3050 && !info->relocatable
3051 && sym->st_size <= elf_gp_size (abfd))
3053 /* Common symbols less than or equal to -G nn bytes are automatically
3055 *secp = bfd_make_section_old_way (abfd, ".sbss");
3057 || ! bfd_set_section_flags (abfd, *secp, SEC_IS_COMMON))
3060 *valp = sym->st_size;
3066 #define TARGET_LITTLE_SYM bfd_elf32_microblazeel_vec
3067 #define TARGET_LITTLE_NAME "elf32-microblazeel"
3069 #define TARGET_BIG_SYM bfd_elf32_microblaze_vec
3070 #define TARGET_BIG_NAME "elf32-microblaze"
3072 #define ELF_ARCH bfd_arch_microblaze
3073 #define ELF_TARGET_ID MICROBLAZE_ELF_DATA
3074 #define ELF_MACHINE_CODE EM_MICROBLAZE
3075 #define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
3076 #define ELF_MAXPAGESIZE 0x4 /* 4k, if we ever have 'em. */
3077 #define elf_info_to_howto microblaze_elf_info_to_howto
3078 #define elf_info_to_howto_rel NULL
3080 #define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
3081 #define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name
3082 #define elf_backend_relocate_section microblaze_elf_relocate_section
3083 #define bfd_elf32_bfd_relax_section microblaze_elf_relax_section
3084 #define bfd_elf32_bfd_merge_private_bfd_data microblaze_elf_merge_private_bfd_data
3085 #define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
3087 #define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
3088 #define elf_backend_gc_sweep_hook microblaze_elf_gc_sweep_hook
3089 #define elf_backend_check_relocs microblaze_elf_check_relocs
3090 #define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
3091 #define bfd_elf32_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
3092 #define elf_backend_can_gc_sections 1
3093 #define elf_backend_can_refcount 1
3094 #define elf_backend_want_got_plt 1
3095 #define elf_backend_plt_readonly 1
3096 #define elf_backend_got_header_size 12
3097 #define elf_backend_rela_normal 1
3099 #define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
3100 #define elf_backend_create_dynamic_sections microblaze_elf_create_dynamic_sections
3101 #define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
3102 #define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
3103 #define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
3104 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
3106 #include "elf32-target.h"