1 /* Xilinx MicroBlaze-specific support for 32-bit ELF
3 Copyright 2009, 2010 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 /* Assume success. */
706 bfd_boolean ret = TRUE;
708 bfd_vma *local_got_offsets;
710 if (!microblaze_elf_howto_table[R_MICROBLAZE_max-1])
711 microblaze_elf_howto_init ();
713 htab = elf32_mb_hash_table (info);
717 local_got_offsets = elf_local_got_offsets (input_bfd);
719 sreloc = elf_section_data (input_section)->sreloc;
722 relend = relocs + input_section->reloc_count;
723 for (; rel < relend; rel++)
726 reloc_howto_type *howto;
727 unsigned long r_symndx;
728 bfd_vma addend = rel->r_addend;
729 bfd_vma offset = rel->r_offset;
730 struct elf_link_hash_entry *h;
731 Elf_Internal_Sym *sym;
733 const char *sym_name;
734 bfd_reloc_status_type r = bfd_reloc_ok;
735 const char *errmsg = NULL;
736 bfd_boolean unresolved_reloc = FALSE;
739 r_type = ELF32_R_TYPE (rel->r_info);
740 if (r_type < 0 || r_type >= (int) R_MICROBLAZE_max)
742 (*_bfd_error_handler) (_("%s: unknown relocation type %d"),
743 bfd_get_filename (input_bfd), (int) r_type);
744 bfd_set_error (bfd_error_bad_value);
749 howto = microblaze_elf_howto_table[r_type];
750 r_symndx = ELF32_R_SYM (rel->r_info);
752 if (info->relocatable)
754 /* This is a relocatable link. We don't have to change
755 anything, unless the reloc is against a section symbol,
756 in which case we have to adjust according to where the
757 section symbol winds up in the output section. */
759 if (r_symndx >= symtab_hdr->sh_info)
760 /* External symbol. */
764 sym = local_syms + r_symndx;
765 sym_name = "<local symbol>";
766 /* STT_SECTION: symbol is associated with a section. */
767 if (ELF_ST_TYPE (sym->st_info) != STT_SECTION)
768 /* Symbol isn't associated with a section. Nothing to do. */
771 sec = local_sections[r_symndx];
772 addend += sec->output_offset + sym->st_value;
774 /* This can't be done for USE_REL because it doesn't mean anything
775 and elf_link_input_bfd asserts this stays zero. */
776 /* rel->r_addend = addend; */
780 /* Addends are stored with relocs. We're done. */
783 /* If partial_inplace, we need to store any additional addend
784 back in the section. */
785 if (!howto->partial_inplace)
787 /* ??? Here is a nice place to call a special_function like handler. */
788 r = _bfd_relocate_contents (howto, input_bfd, addend,
796 /* This is a final link. */
799 unresolved_reloc = FALSE;
801 if (r_symndx < symtab_hdr->sh_info)
804 sym = local_syms + r_symndx;
805 sec = local_sections[r_symndx];
808 sym_name = "<local symbol>";
809 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
810 /* r_addend may have changed if the reference section was
812 addend = rel->r_addend;
816 /* External symbol. */
817 bfd_boolean warned ATTRIBUTE_UNUSED;
819 RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
820 r_symndx, symtab_hdr, sym_hashes,
822 unresolved_reloc, warned);
823 sym_name = h->root.root.string;
826 /* Sanity check the address. */
827 if (offset > bfd_get_section_limit (output_bfd, input_section))
829 r = bfd_reloc_outofrange;
833 switch ((int) r_type)
835 case (int) R_MICROBLAZE_SRO32 :
839 /* Only relocate if the symbol is defined. */
842 name = bfd_get_section_name (abfd, sec);
844 if (strcmp (name, ".sdata2") == 0
845 || strcmp (name, ".sbss2") == 0)
847 if (ro_small_data_pointer == 0)
848 microblaze_elf_final_sdp (info);
849 if (ro_small_data_pointer == 0)
852 r = bfd_reloc_undefined;
856 /* At this point `relocation' contains the object's
858 relocation -= ro_small_data_pointer;
859 /* Now it contains the offset from _SDA2_BASE_. */
860 r = _bfd_final_link_relocate (howto, input_bfd,
867 (*_bfd_error_handler) (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"),
868 bfd_get_filename (input_bfd),
870 microblaze_elf_howto_table[(int) r_type]->name,
871 bfd_get_section_name (abfd, sec));
872 /*bfd_set_error (bfd_error_bad_value); ??? why? */
880 case (int) R_MICROBLAZE_SRW32 :
884 /* Only relocate if the symbol is defined. */
887 name = bfd_get_section_name (abfd, sec);
889 if (strcmp (name, ".sdata") == 0
890 || strcmp (name, ".sbss") == 0)
892 if (rw_small_data_pointer == 0)
893 microblaze_elf_final_sdp (info);
894 if (rw_small_data_pointer == 0)
897 r = bfd_reloc_undefined;
901 /* At this point `relocation' contains the object's
903 relocation -= rw_small_data_pointer;
904 /* Now it contains the offset from _SDA_BASE_. */
905 r = _bfd_final_link_relocate (howto, input_bfd,
912 (*_bfd_error_handler) (_("%s: The target (%s) of an %s relocation is in the wrong section (%s)"),
913 bfd_get_filename (input_bfd),
915 microblaze_elf_howto_table[(int) r_type]->name,
916 bfd_get_section_name (abfd, sec));
917 /*bfd_set_error (bfd_error_bad_value); ??? why? */
925 case (int) R_MICROBLAZE_32_SYM_OP_SYM:
926 break; /* Do nothing. */
928 case (int) R_MICROBLAZE_GOTPC_64:
929 relocation = htab->sgotplt->output_section->vma
930 + htab->sgotplt->output_offset;
931 relocation -= (input_section->output_section->vma
932 + input_section->output_offset
933 + offset + INST_WORD_SIZE);
934 relocation += addend;
935 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
936 contents + offset + 2);
937 bfd_put_16 (input_bfd, relocation & 0xffff,
938 contents + offset + 2 + INST_WORD_SIZE);
941 case (int) R_MICROBLAZE_PLT_64:
944 if (htab->splt != NULL && h != NULL
945 && h->plt.offset != (bfd_vma) -1)
947 relocation = (htab->splt->output_section->vma
948 + htab->splt->output_offset
950 unresolved_reloc = FALSE;
951 immediate = relocation - (input_section->output_section->vma
952 + input_section->output_offset
953 + offset + INST_WORD_SIZE);
954 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
955 contents + offset + 2);
956 bfd_put_16 (input_bfd, immediate & 0xffff,
957 contents + offset + 2 + INST_WORD_SIZE);
961 relocation -= (input_section->output_section->vma
962 + input_section->output_offset
963 + offset + INST_WORD_SIZE);
964 immediate = relocation;
965 bfd_put_16 (input_bfd, (immediate >> 16) & 0xffff,
966 contents + offset + 2);
967 bfd_put_16 (input_bfd, immediate & 0xffff,
968 contents + offset + 2 + INST_WORD_SIZE);
973 case (int) R_MICROBLAZE_GOT_64:
975 if (htab->sgot == NULL)
980 if (local_got_offsets == NULL)
982 off = local_got_offsets[r_symndx];
983 /* The LSB indicates whether we've already
984 created relocation. */
989 bfd_put_32 (output_bfd, relocation + addend,
990 htab->sgot->contents + off);
994 Elf_Internal_Rela outrel;
996 if (htab->srelgot == NULL)
998 outrel.r_offset = (htab->sgot->output_section->vma
999 + htab->sgot->output_offset
1001 outrel.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL);
1002 outrel.r_addend = relocation + addend;
1003 loc = htab->srelgot->contents;
1004 loc += htab->srelgot->reloc_count++
1005 * sizeof (Elf32_External_Rela);
1006 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1008 local_got_offsets[r_symndx] |= 1;
1010 relocation = htab->sgot->output_section->vma
1011 + htab->sgot->output_offset + off
1012 - htab->sgotplt->output_section->vma
1013 - htab->sgotplt->output_offset;
1014 unresolved_reloc = FALSE;
1018 if (htab->sgotplt != NULL && h != NULL
1019 && h->got.offset != (bfd_vma) -1)
1021 bfd_put_32 (output_bfd, relocation + addend,
1022 htab->sgot->contents + h->got.offset);
1023 relocation = htab->sgot->output_section->vma
1024 + htab->sgot->output_offset
1026 - htab->sgotplt->output_section->vma
1027 - htab->sgotplt->output_offset;
1028 unresolved_reloc = FALSE;
1033 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1034 contents + offset + 2);
1035 bfd_put_16 (input_bfd, relocation & 0xffff,
1036 contents + offset + 2 + INST_WORD_SIZE);
1040 case (int) R_MICROBLAZE_GOTOFF_64:
1043 unsigned short lo, high;
1044 relocation += addend;
1045 relocation -= htab->sgotplt->output_section->vma
1046 + htab->sgotplt->output_offset;
1047 /* Write this value into correct location. */
1048 immediate = relocation;
1049 lo = immediate & 0x0000ffff;
1050 high = (immediate >> 16) & 0x0000ffff;
1051 bfd_put_16 (input_bfd, high, contents + offset + 2);
1052 bfd_put_16 (input_bfd, lo, contents + offset + INST_WORD_SIZE + 2);
1056 case (int) R_MICROBLAZE_GOTOFF_32:
1058 relocation += addend;
1059 relocation -= htab->sgotplt->output_section->vma
1060 + htab->sgotplt->output_offset;
1061 /* Write this value into correct location. */
1062 bfd_put_32 (input_bfd, relocation, contents + offset);
1066 case (int) R_MICROBLAZE_64_PCREL :
1067 case (int) R_MICROBLAZE_64:
1068 case (int) R_MICROBLAZE_32:
1070 /* r_symndx will be zero only for relocs against symbols
1071 from removed linkonce sections, or sections discarded by
1073 if (r_symndx == 0 || (input_section->flags & SEC_ALLOC) == 0)
1075 relocation += addend;
1076 if (r_type == R_MICROBLAZE_32)
1077 bfd_put_32 (input_bfd, relocation, contents + offset);
1080 if (r_type == R_MICROBLAZE_64_PCREL)
1081 relocation -= (input_section->output_section->vma
1082 + input_section->output_offset
1083 + offset + INST_WORD_SIZE);
1084 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1085 contents + offset + 2);
1086 bfd_put_16 (input_bfd, relocation & 0xffff,
1087 contents + offset + 2 + INST_WORD_SIZE);
1094 || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
1095 || h->root.type != bfd_link_hash_undefweak)
1096 && (!howto->pc_relative
1100 || !h->def_regular))))
1107 || h->root.type == bfd_link_hash_undefweak
1108 || h->root.type == bfd_link_hash_undefined)))
1110 Elf_Internal_Rela outrel;
1112 bfd_boolean skip, relocate = FALSE;
1114 /* When generating a shared object, these relocations
1115 are copied into the output file to be resolved at run
1118 BFD_ASSERT (sreloc != NULL);
1123 _bfd_elf_section_offset (output_bfd, info, input_section,
1125 if (outrel.r_offset == (bfd_vma) -1)
1127 else if (outrel.r_offset == (bfd_vma) -2)
1128 skip = TRUE, relocate = TRUE;
1129 outrel.r_offset += (input_section->output_section->vma
1130 + input_section->output_offset);
1133 memset (&outrel, 0, sizeof outrel);
1134 /* h->dynindx may be -1 if the symbol was marked to
1137 && ((! info->symbolic && h->dynindx != -1)
1138 || !h->def_regular))
1140 BFD_ASSERT (h->dynindx != -1);
1141 outrel.r_info = ELF32_R_INFO (h->dynindx, r_type);
1142 outrel.r_addend = addend;
1146 if (r_type == R_MICROBLAZE_32)
1148 outrel.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL);
1149 outrel.r_addend = relocation + addend;
1154 (*_bfd_error_handler)
1155 (_("%B: probably compiled without -fPIC?"),
1157 bfd_set_error (bfd_error_bad_value);
1162 loc = sreloc->contents;
1163 loc += sreloc->reloc_count++ * sizeof (Elf32_External_Rela);
1164 bfd_elf32_swap_reloca_out (output_bfd, &outrel, loc);
1169 relocation += addend;
1170 if (r_type == R_MICROBLAZE_32)
1171 bfd_put_32 (input_bfd, relocation, contents + offset);
1174 if (r_type == R_MICROBLAZE_64_PCREL)
1175 relocation -= (input_section->output_section->vma
1176 + input_section->output_offset
1177 + offset + INST_WORD_SIZE);
1178 bfd_put_16 (input_bfd, (relocation >> 16) & 0xffff,
1179 contents + offset + 2);
1180 bfd_put_16 (input_bfd, relocation & 0xffff,
1181 contents + offset + 2 + INST_WORD_SIZE);
1188 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
1190 relocation, addend);
1197 if (r != bfd_reloc_ok)
1199 /* FIXME: This should be generic enough to go in a utility. */
1203 name = h->root.root.string;
1206 name = (bfd_elf_string_from_elf_section
1207 (input_bfd, symtab_hdr->sh_link, sym->st_name));
1208 if (name == NULL || *name == '\0')
1209 name = bfd_section_name (input_bfd, sec);
1217 case bfd_reloc_overflow:
1218 if (!((*info->callbacks->reloc_overflow)
1219 (info, (h ? &h->root : NULL), name, howto->name,
1220 (bfd_vma) 0, input_bfd, input_section, offset)))
1224 case bfd_reloc_undefined:
1225 if (!((*info->callbacks->undefined_symbol)
1226 (info, name, input_bfd, input_section, offset, TRUE)))
1230 case bfd_reloc_outofrange:
1231 errmsg = _("internal error: out of range error");
1234 case bfd_reloc_notsupported:
1235 errmsg = _("internal error: unsupported relocation error");
1238 case bfd_reloc_dangerous:
1239 errmsg = _("internal error: dangerous error");
1243 errmsg = _("internal error: unknown error");
1246 if (!((*info->callbacks->warning)
1247 (info, errmsg, name, input_bfd, input_section, offset)))
1257 /* Calculate fixup value for reference. */
1260 calc_fixup (bfd_vma addr, asection *sec)
1264 if (sec == NULL || sec->relax == NULL)
1267 /* Look for addr in relax table, total fixup value. */
1268 for (i = 0; i < sec->relax_count; i++)
1270 if (addr <= sec->relax[i].addr)
1272 fixup += sec->relax[i].size;
1279 microblaze_elf_relax_section (bfd *abfd,
1281 struct bfd_link_info *link_info,
1284 Elf_Internal_Shdr *symtab_hdr;
1285 Elf_Internal_Rela *internal_relocs;
1286 Elf_Internal_Rela *free_relocs = NULL;
1287 Elf_Internal_Rela *irel, *irelend;
1288 bfd_byte *contents = NULL;
1289 bfd_byte *free_contents = NULL;
1294 struct elf_link_hash_entry *sym_hash;
1295 Elf_Internal_Sym *isymbuf, *isymend;
1296 Elf_Internal_Sym *isym;
1301 /* We only do this once per section. We may be able to delete some code
1302 by running multiple passes, but it is not worth it. */
1305 /* Only do this for a text section. */
1306 if (link_info->relocatable
1307 || (sec->flags & SEC_RELOC) == 0
1308 || (sec->reloc_count == 0))
1311 BFD_ASSERT ((sec->size > 0) || (sec->rawsize > 0));
1313 /* If this is the first time we have been called for this section,
1314 initialize the cooked size. */
1316 sec->size = sec->rawsize;
1318 /* Get symbols for this section. */
1319 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
1320 isymbuf = (Elf_Internal_Sym *) symtab_hdr->contents;
1321 symcount = symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
1322 if (isymbuf == NULL)
1323 isymbuf = bfd_elf_get_elf_syms (abfd, symtab_hdr, symcount,
1324 0, NULL, NULL, NULL);
1325 BFD_ASSERT (isymbuf != NULL);
1327 internal_relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL, link_info->keep_memory);
1328 if (internal_relocs == NULL)
1330 if (! link_info->keep_memory)
1331 free_relocs = internal_relocs;
1333 sec->relax = (struct relax_table *) bfd_malloc ((sec->reloc_count + 1)
1334 * sizeof (struct relax_table));
1335 if (sec->relax == NULL)
1337 sec->relax_count = 0;
1339 irelend = internal_relocs + sec->reloc_count;
1341 for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1344 if ((ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64_PCREL)
1345 && (ELF32_R_TYPE (irel->r_info) != (int) R_MICROBLAZE_64 ))
1346 continue; /* Can't delete this reloc. */
1348 /* Get the section contents. */
1349 if (contents == NULL)
1351 if (elf_section_data (sec)->this_hdr.contents != NULL)
1352 contents = elf_section_data (sec)->this_hdr.contents;
1355 contents = (bfd_byte *) bfd_malloc (sec->size);
1356 if (contents == NULL)
1358 free_contents = contents;
1360 if (!bfd_get_section_contents (abfd, sec, contents,
1361 (file_ptr) 0, sec->size))
1363 elf_section_data (sec)->this_hdr.contents = contents;
1367 /* Get the value of the symbol referred to by the reloc. */
1368 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1370 /* A local symbol. */
1373 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1374 if (isym->st_shndx == SHN_UNDEF)
1375 sym_sec = bfd_und_section_ptr;
1376 else if (isym->st_shndx == SHN_ABS)
1377 sym_sec = bfd_abs_section_ptr;
1378 else if (isym->st_shndx == SHN_COMMON)
1379 sym_sec = bfd_com_section_ptr;
1381 sym_sec = bfd_section_from_elf_index (abfd, isym->st_shndx);
1383 symval = _bfd_elf_rela_local_sym (abfd, isym, &sym_sec, irel);
1388 struct elf_link_hash_entry *h;
1390 indx = ELF32_R_SYM (irel->r_info) - symtab_hdr->sh_info;
1391 h = elf_sym_hashes (abfd)[indx];
1392 BFD_ASSERT (h != NULL);
1394 if (h->root.type != bfd_link_hash_defined
1395 && h->root.type != bfd_link_hash_defweak)
1396 /* This appears to be a reference to an undefined
1397 symbol. Just ignore it--it will be caught by the
1398 regular reloc processing. */
1401 symval = (h->root.u.def.value
1402 + h->root.u.def.section->output_section->vma
1403 + h->root.u.def.section->output_offset);
1406 /* If this is a PC-relative reloc, subtract the instr offset from
1407 the symbol value. */
1408 if (ELF32_R_TYPE (irel->r_info) == (int) R_MICROBLAZE_64_PCREL)
1410 symval = symval + irel->r_addend
1412 + sec->output_section->vma
1413 + sec->output_offset);
1416 symval += irel->r_addend;
1418 if ((symval & 0xffff8000) == 0
1419 || (symval & 0xffff8000) == 0xffff8000)
1421 /* We can delete this instruction. */
1422 sec->relax[sec->relax_count].addr = irel->r_offset;
1423 sec->relax[sec->relax_count].size = INST_WORD_SIZE;
1426 /* Rewrite relocation type. */
1427 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1429 case R_MICROBLAZE_64_PCREL:
1430 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1431 (int) R_MICROBLAZE_32_PCREL_LO);
1433 case R_MICROBLAZE_64:
1434 irel->r_info = ELF32_R_INFO (ELF32_R_SYM (irel->r_info),
1435 (int) R_MICROBLAZE_32_LO);
1438 /* Cannot happen. */
1442 } /* Loop through all relocations. */
1444 /* Loop through the relocs again, and see if anything needs to change. */
1445 if (sec->relax_count > 0)
1447 shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
1449 sec->relax[sec->relax_count].addr = sec->size;
1451 for (irel = internal_relocs; irel < irelend; irel++, rel_count++)
1455 /* Get the new reloc address. */
1456 nraddr = irel->r_offset - calc_fixup (irel->r_offset, sec);
1457 switch ((enum elf_microblaze_reloc_type) ELF32_R_TYPE (irel->r_info))
1461 case R_MICROBLAZE_64_PCREL:
1463 case R_MICROBLAZE_64:
1464 case R_MICROBLAZE_32_LO:
1465 /* If this reloc is against a symbol defined in this
1466 section, we must check the addend to see it will put the value in
1467 range to be adjusted, and hence must be changed. */
1468 if (ELF32_R_SYM (irel->r_info) < symtab_hdr->sh_info)
1470 isym = isymbuf + ELF32_R_SYM (irel->r_info);
1471 /* Only handle relocs against .text. */
1472 if (isym->st_shndx == shndx
1473 && ELF32_ST_TYPE (isym->st_info) == STT_SECTION)
1474 irel->r_addend -= calc_fixup (irel->r_addend, sec);
1477 case R_MICROBLAZE_NONE:
1479 /* This was a PC-relative instruction that was
1480 completely resolved. */
1482 bfd_vma target_address;
1483 target_address = irel->r_addend + irel->r_offset;
1484 sfix = calc_fixup (irel->r_offset, sec);
1485 efix = calc_fixup (target_address, sec);
1486 irel->r_addend -= (efix - sfix);
1487 /* Should use HOWTO. */
1488 bfd_put_16 (abfd, irel->r_addend, contents + irel->r_offset + 2);
1491 case R_MICROBLAZE_64_NONE:
1493 /* This was a PC-relative 64-bit instruction that was
1494 completely resolved. */
1496 bfd_vma target_address;
1497 target_address = irel->r_addend + irel->r_offset + INST_WORD_SIZE;
1498 sfix = calc_fixup (irel->r_offset + INST_WORD_SIZE, sec);
1499 efix = calc_fixup (target_address, sec);
1500 irel->r_addend -= (efix - sfix);
1501 bfd_put_16 (abfd, irel->r_addend, contents + irel->r_offset
1502 + INST_WORD_SIZE + 2);
1506 irel->r_offset = nraddr;
1507 } /* Change all relocs in this section. */
1509 /* Look through all other sections. */
1510 for (o = abfd->sections; o != NULL; o = o->next)
1512 Elf_Internal_Rela *irelocs;
1513 Elf_Internal_Rela *irelscan, *irelscanend;
1514 bfd_byte *ocontents;
1517 || (o->flags & SEC_RELOC) == 0
1518 || o->reloc_count == 0)
1521 /* We always cache the relocs. Perhaps, if info->keep_memory is
1522 FALSE, we should free them, if we are permitted to. */
1524 irelocs = _bfd_elf_link_read_relocs (abfd, o, NULL, NULL, TRUE);
1525 if (irelocs == NULL)
1529 irelscanend = irelocs + o->reloc_count;
1530 for (irelscan = irelocs; irelscan < irelscanend; irelscan++)
1532 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32)
1534 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1536 /* Look at the reloc only if the value has been resolved. */
1537 if (isym->st_shndx == shndx
1538 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
1540 if (ocontents == NULL)
1542 if (elf_section_data (o)->this_hdr.contents != NULL)
1543 ocontents = elf_section_data (o)->this_hdr.contents;
1546 /* We always cache the section contents.
1547 Perhaps, if info->keep_memory is FALSE, we
1548 should free them, if we are permitted to. */
1549 if (o->rawsize == 0)
1550 o->rawsize = o->size;
1551 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
1552 if (ocontents == NULL)
1554 if (!bfd_get_section_contents (abfd, o, ocontents,
1558 elf_section_data (o)->this_hdr.contents = ocontents;
1562 irelscan->r_addend -= calc_fixup (irelscan->r_addend, sec);
1564 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_SYM_OP_SYM)
1566 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1568 /* Look at the reloc only if the value has been resolved. */
1569 if (ocontents == NULL)
1571 if (elf_section_data (o)->this_hdr.contents != NULL)
1572 ocontents = elf_section_data (o)->this_hdr.contents;
1575 /* We always cache the section contents.
1576 Perhaps, if info->keep_memory is FALSE, we
1577 should free them, if we are permitted to. */
1579 if (o->rawsize == 0)
1580 o->rawsize = o->size;
1581 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
1582 if (ocontents == NULL)
1584 if (!bfd_get_section_contents (abfd, o, ocontents,
1588 elf_section_data (o)->this_hdr.contents = ocontents;
1591 irelscan->r_addend -= calc_fixup (irel->r_addend
1596 else if ((ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_PCREL_LO)
1597 || (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_32_LO))
1599 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1601 /* Look at the reloc only if the value has been resolved. */
1602 if (isym->st_shndx == shndx
1603 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
1606 bfd_vma target_address;
1608 if (ocontents == NULL)
1610 if (elf_section_data (o)->this_hdr.contents != NULL)
1611 ocontents = elf_section_data (o)->this_hdr.contents;
1614 /* We always cache the section contents.
1615 Perhaps, if info->keep_memory is FALSE, we
1616 should free them, if we are permitted to. */
1617 if (o->rawsize == 0)
1618 o->rawsize = o->size;
1619 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
1620 if (ocontents == NULL)
1622 if (!bfd_get_section_contents (abfd, o, ocontents,
1626 elf_section_data (o)->this_hdr.contents = ocontents;
1630 immediate = (unsigned short) bfd_get_16 (abfd, ocontents +
1631 irelscan->r_offset + 2);
1632 target_address = immediate;
1633 offset = calc_fixup (target_address, sec);
1634 immediate -= offset;
1635 irelscan->r_addend -= offset;
1636 bfd_put_16 (abfd, immediate, ocontents + irelscan->r_offset + 2);
1640 if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64)
1642 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1644 /* Look at the reloc only if the value has been resolved. */
1645 if (isym->st_shndx == shndx
1646 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
1650 if (ocontents == NULL)
1652 if (elf_section_data (o)->this_hdr.contents != NULL)
1653 ocontents = elf_section_data (o)->this_hdr.contents;
1656 /* We always cache the section contents.
1657 Perhaps, if info->keep_memory is FALSE, we
1658 should free them, if we are permitted to. */
1660 if (o->rawsize == 0)
1661 o->rawsize = o->size;
1662 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
1663 if (ocontents == NULL)
1665 if (!bfd_get_section_contents (abfd, o, ocontents,
1669 elf_section_data (o)->this_hdr.contents = ocontents;
1672 immediate = (unsigned short) (bfd_get_16 (abfd, ocontents
1673 + irelscan->r_offset
1676 immediate += (unsigned short) (bfd_get_16 (abfd, ocontents
1677 + irelscan->r_offset
1678 + INST_WORD_SIZE + 2))
1681 offset = calc_fixup (irelscan->r_addend, sec);
1682 immediate -= offset;
1683 irelscan->r_addend -= offset;
1686 else if (ELF32_R_TYPE (irelscan->r_info) == (int) R_MICROBLAZE_64_PCREL)
1688 isym = isymbuf + ELF32_R_SYM (irelscan->r_info);
1690 /* Look at the reloc only if the value has been resolved. */
1691 if (isym->st_shndx == shndx
1692 && (ELF32_ST_TYPE (isym->st_info) == STT_SECTION))
1695 bfd_vma target_address;
1697 if (ocontents == NULL)
1699 if (elf_section_data (o)->this_hdr.contents != NULL)
1700 ocontents = elf_section_data (o)->this_hdr.contents;
1703 /* We always cache the section contents.
1704 Perhaps, if info->keep_memory is FALSE, we
1705 should free them, if we are permitted to. */
1706 if (o->rawsize == 0)
1707 o->rawsize = o->size;
1708 ocontents = (bfd_byte *) bfd_malloc (o->rawsize);
1709 if (ocontents == NULL)
1711 if (!bfd_get_section_contents (abfd, o, ocontents,
1715 elf_section_data (o)->this_hdr.contents = ocontents;
1719 immediate = (unsigned short)
1720 (bfd_get_16 (abfd, ocontents + irelscan->r_offset + 2) << 16)
1722 immediate += (unsigned short)
1723 (bfd_get_16 (abfd, ocontents + irelscan->r_offset
1724 + INST_WORD_SIZE + 2))
1726 target_address = immediate;
1727 offset = calc_fixup (target_address, sec);
1728 immediate -= offset;
1729 irelscan->r_addend -= offset;
1730 bfd_put_16 (abfd, ((immediate >> 16) & 0x0000ffff),
1731 ocontents + irelscan->r_offset + 2);
1732 bfd_put_16 (abfd, (immediate & 0x0000ffff),
1733 ocontents + irelscan->r_offset + INST_WORD_SIZE + 2);
1739 /* Adjust the local symbols defined in this section. */
1740 isymend = isymbuf + symtab_hdr->sh_info;
1741 for (isym = isymbuf; isym < isymend; isym++)
1743 if (isym->st_shndx == shndx)
1744 isym->st_value =- calc_fixup (isym->st_value, sec);
1747 /* Now adjust the global symbols defined in this section. */
1748 isym = isymbuf + symtab_hdr->sh_info;
1749 isymend = isymbuf + (symtab_hdr->sh_size / sizeof (Elf32_External_Sym));
1750 for (sym_index = 0; isym < isymend; isym++, sym_index++)
1752 sym_hash = elf_sym_hashes (abfd)[sym_index];
1753 if (isym->st_shndx == shndx
1754 && (sym_hash->root.type == bfd_link_hash_defined
1755 || sym_hash->root.type == bfd_link_hash_defweak)
1756 && sym_hash->root.u.def.section == sec)
1758 sym_hash->root.u.def.value -= calc_fixup (sym_hash->root.u.def.value,
1763 /* Physically move the code and change the cooked size. */
1764 dest = sec->relax[0].addr;
1765 for (i = 0; i < sec->relax_count; i++)
1768 src = sec->relax[i].addr + sec->relax[i].size;
1769 len = sec->relax[i+1].addr - sec->relax[i].addr - sec->relax[i].size;
1771 memmove (contents + dest, contents + src, len);
1772 sec->size -= sec->relax[i].size;
1776 elf_section_data (sec)->relocs = internal_relocs;
1779 elf_section_data (sec)->this_hdr.contents = contents;
1780 free_contents = NULL;
1782 symtab_hdr->contents = (bfd_byte *) isymbuf;
1785 if (free_relocs != NULL)
1791 if (free_contents != NULL)
1793 if (!link_info->keep_memory)
1794 free (free_contents);
1796 /* Cache the section contents for elf_link_input_bfd. */
1797 elf_section_data (sec)->this_hdr.contents = contents;
1798 free_contents = NULL;
1801 if (sec->relax_count == 0)
1809 if (free_relocs != NULL)
1811 if (free_contents != NULL)
1812 free (free_contents);
1813 if (sec->relax != NULL)
1817 sec->relax_count = 0;
1822 /* Return the section that should be marked against GC for a given
1826 microblaze_elf_gc_mark_hook (asection *sec,
1827 struct bfd_link_info * info,
1828 Elf_Internal_Rela * rel,
1829 struct elf_link_hash_entry * h,
1830 Elf_Internal_Sym * sym)
1833 switch (ELF32_R_TYPE (rel->r_info))
1835 case R_MICROBLAZE_GNU_VTINHERIT:
1836 case R_MICROBLAZE_GNU_VTENTRY:
1840 return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
1843 /* Update the got entry reference counts for the section being removed. */
1846 microblaze_elf_gc_sweep_hook (bfd * abfd ATTRIBUTE_UNUSED,
1847 struct bfd_link_info * info ATTRIBUTE_UNUSED,
1848 asection * sec ATTRIBUTE_UNUSED,
1849 const Elf_Internal_Rela * relocs ATTRIBUTE_UNUSED)
1856 #define PLT_ENTRY_SIZE 16
1858 #define PLT_ENTRY_WORD_0 0xb0000000 /* "imm 0". */
1859 #define PLT_ENTRY_WORD_1 0xe9940000 /* "lwi r12,r20,0" - relocated to lwi r12,r20,func@GOT. */
1860 #define PLT_ENTRY_WORD_1_NOPIC 0xe9800000 /* "lwi r12,r0,0" - non-PIC object. */
1861 #define PLT_ENTRY_WORD_2 0x98186000 /* "brad r12". */
1862 #define PLT_ENTRY_WORD_3 0x80000000 /* "nop". */
1864 /* Create .got, .gotplt, and .rela.got sections in DYNOBJ, and set up
1865 shortcuts to them in our hash table. */
1868 create_got_section (bfd *dynobj, struct bfd_link_info *info)
1870 struct elf32_mb_link_hash_table *htab;
1872 if (! _bfd_elf_create_got_section (dynobj, info))
1874 htab = elf32_mb_hash_table (info);
1878 htab->sgot = bfd_get_section_by_name (dynobj, ".got");
1879 htab->sgotplt = bfd_get_section_by_name (dynobj, ".got.plt");
1880 if (!htab->sgot || !htab->sgotplt)
1883 htab->srelgot = bfd_make_section (dynobj, ".rela.got");
1884 if (htab->srelgot == NULL
1885 || ! bfd_set_section_flags (dynobj, htab->srelgot, SEC_ALLOC
1889 | SEC_LINKER_CREATED
1891 || ! bfd_set_section_alignment (dynobj, htab->srelgot, 2))
1896 /* Look through the relocs for a section during the first phase. */
1899 microblaze_elf_check_relocs (bfd * abfd,
1900 struct bfd_link_info * info,
1902 const Elf_Internal_Rela * relocs)
1904 Elf_Internal_Shdr * symtab_hdr;
1905 struct elf_link_hash_entry ** sym_hashes;
1906 struct elf_link_hash_entry ** sym_hashes_end;
1907 const Elf_Internal_Rela * rel;
1908 const Elf_Internal_Rela * rel_end;
1909 struct elf32_mb_link_hash_table *htab;
1910 bfd_vma *local_got_offsets;
1911 asection *sreloc = NULL;
1913 if (info->relocatable)
1916 htab = elf32_mb_hash_table (info);
1920 local_got_offsets = elf_local_got_offsets (abfd);
1921 symtab_hdr = & elf_tdata (abfd)->symtab_hdr;
1922 sym_hashes = elf_sym_hashes (abfd);
1923 sym_hashes_end = sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
1924 if (!elf_bad_symtab (abfd))
1925 sym_hashes_end -= symtab_hdr->sh_info;
1927 rel_end = relocs + sec->reloc_count;
1929 for (rel = relocs; rel < rel_end; rel++)
1931 unsigned int r_type;
1932 struct elf_link_hash_entry * h;
1933 unsigned long r_symndx;
1935 r_symndx = ELF32_R_SYM (rel->r_info);
1936 r_type = ELF32_R_TYPE (rel->r_info);
1938 if (r_symndx < symtab_hdr->sh_info)
1941 h = sym_hashes [r_symndx - symtab_hdr->sh_info];
1945 /* This relocation describes the C++ object vtable hierarchy.
1946 Reconstruct it for later use during GC. */
1947 case R_MICROBLAZE_GNU_VTINHERIT:
1948 if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
1952 /* This relocation describes which C++ vtable entries are actually
1953 used. Record for later use during GC. */
1954 case R_MICROBLAZE_GNU_VTENTRY:
1955 if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
1959 /* This relocation requires .plt entry. */
1960 case R_MICROBLAZE_PLT_64:
1964 h->plt.refcount += 1;
1968 /* This relocation requires .got entry. */
1969 case R_MICROBLAZE_GOT_64:
1970 if (htab->sgot == NULL)
1972 if (htab->elf.dynobj == NULL)
1973 htab->elf.dynobj = abfd;
1974 if (!create_got_section (htab->elf.dynobj, info))
1979 h->got.refcount += 1;
1983 bfd_signed_vma *local_got_refcounts;
1985 /* This is a global offset table entry for a local symbol. */
1986 local_got_refcounts = elf_local_got_refcounts (abfd);
1987 if (local_got_refcounts == NULL)
1991 size = symtab_hdr->sh_info;
1992 size *= sizeof (bfd_signed_vma);
1993 local_got_refcounts = bfd_zalloc (abfd, size);
1994 if (local_got_refcounts == NULL)
1996 elf_local_got_refcounts (abfd) = local_got_refcounts;
1998 local_got_refcounts[r_symndx] += 1;
2002 case R_MICROBLAZE_64:
2003 case R_MICROBLAZE_64_PCREL:
2004 case R_MICROBLAZE_32:
2006 if (h != NULL && !info->shared)
2008 /* we may need a copy reloc. */
2011 /* we may also need a .plt entry. */
2012 h->plt.refcount += 1;
2013 if (ELF32_R_TYPE (rel->r_info) != R_MICROBLAZE_64_PCREL)
2014 h->pointer_equality_needed = 1;
2018 /* If we are creating a shared library, and this is a reloc
2019 against a global symbol, or a non PC relative reloc
2020 against a local symbol, then we need to copy the reloc
2021 into the shared library. However, if we are linking with
2022 -Bsymbolic, we do not need to copy a reloc against a
2023 global symbol which is defined in an object we are
2024 including in the link (i.e., DEF_REGULAR is set). At
2025 this point we have not seen all the input files, so it is
2026 possible that DEF_REGULAR is not set now but will be set
2027 later (it is never cleared). In case of a weak definition,
2028 DEF_REGULAR may be cleared later by a strong definition in
2029 a shared library. We account for that possibility below by
2030 storing information in the relocs_copied field of the hash
2031 table entry. A similar situation occurs when creating
2032 shared libraries and symbol visibility changes render the
2035 If on the other hand, we are creating an executable, we
2036 may need to keep relocations for symbols satisfied by a
2037 dynamic library if we manage to avoid copy relocs for the
2041 && (sec->flags & SEC_ALLOC) != 0
2042 && (r_type != R_MICROBLAZE_64_PCREL
2044 && (! info->symbolic
2045 || h->root.type == bfd_link_hash_defweak
2046 || !h->def_regular))))
2048 && (sec->flags & SEC_ALLOC) != 0
2050 && (h->root.type == bfd_link_hash_defweak
2051 || !h->def_regular)))
2053 struct elf32_mb_dyn_relocs *p;
2054 struct elf32_mb_dyn_relocs **head;
2056 /* When creating a shared object, we must copy these
2057 relocs into the output file. We create a reloc
2058 section in dynobj and make room for the reloc. */
2064 unsigned int strndx = elf_elfheader (abfd)->e_shstrndx;
2065 unsigned int shnam = elf_section_data (sec)->rel_hdr.sh_name;
2067 name = bfd_elf_string_from_elf_section (abfd, strndx, shnam);
2071 if (strncmp (name, ".rela", 5) != 0
2072 || strcmp (bfd_get_section_name (abfd, sec),
2075 (*_bfd_error_handler)
2076 (_("%B: bad relocation section name `%s\'"),
2080 if (htab->elf.dynobj == NULL)
2081 htab->elf.dynobj = abfd;
2082 dynobj = htab->elf.dynobj;
2084 sreloc = bfd_get_section_by_name (dynobj, name);
2089 sreloc = bfd_make_section (dynobj, name);
2090 flags = (SEC_HAS_CONTENTS | SEC_READONLY
2091 | SEC_IN_MEMORY | SEC_LINKER_CREATED);
2092 if ((sec->flags & SEC_ALLOC) != 0)
2093 flags |= SEC_ALLOC | SEC_LOAD;
2095 || ! bfd_set_section_flags (dynobj, sreloc, flags)
2096 || ! bfd_set_section_alignment (dynobj, sreloc, 2))
2099 elf_section_data (sec)->sreloc = sreloc;
2102 /* If this is a global symbol, we count the number of
2103 relocations we need for this symbol. */
2105 head = &((struct elf32_mb_link_hash_entry *) h)->dyn_relocs;
2108 /* Track dynamic relocs needed for local syms too.
2109 We really need local syms available to do this
2113 Elf_Internal_Sym *isym;
2116 isym = bfd_sym_from_r_symndx (&htab->sym_sec,
2121 s = bfd_section_from_elf_index (abfd, isym->st_shndx);
2125 vpp = &elf_section_data (s)->local_dynrel;
2126 head = (struct elf32_mb_dyn_relocs **) vpp;
2130 if (p == NULL || p->sec != sec)
2132 bfd_size_type amt = sizeof *p;
2133 p = ((struct elf32_mb_dyn_relocs *)
2134 bfd_alloc (htab->elf.dynobj, amt));
2145 if (r_type == R_MICROBLAZE_64_PCREL)
2157 microblaze_elf_create_dynamic_sections (bfd *dynobj, struct bfd_link_info *info)
2159 struct elf32_mb_link_hash_table *htab;
2161 htab = elf32_mb_hash_table (info);
2165 if (!htab->sgot && !create_got_section (dynobj, info))
2168 if (!_bfd_elf_create_dynamic_sections (dynobj, info))
2171 htab->splt = bfd_get_section_by_name (dynobj, ".plt");
2172 htab->srelplt = bfd_get_section_by_name (dynobj, ".rela.plt");
2173 htab->sdynbss = bfd_get_section_by_name (dynobj, ".dynbss");
2175 htab->srelbss = bfd_get_section_by_name (dynobj, ".rela.bss");
2177 if (!htab->splt || !htab->srelplt || !htab->sdynbss
2178 || (!info->shared && !htab->srelbss))
2184 /* Copy the extra info we tack onto an elf_link_hash_entry. */
2187 microblaze_elf_copy_indirect_symbol (struct bfd_link_info *info,
2188 struct elf_link_hash_entry *dir,
2189 struct elf_link_hash_entry *ind)
2191 struct elf32_mb_link_hash_entry *edir, *eind;
2193 edir = (struct elf32_mb_link_hash_entry *) dir;
2194 eind = (struct elf32_mb_link_hash_entry *) ind;
2196 if (eind->dyn_relocs != NULL)
2198 if (edir->dyn_relocs != NULL)
2200 struct elf32_mb_dyn_relocs **pp;
2201 struct elf32_mb_dyn_relocs *p;
2203 if (ind->root.type == bfd_link_hash_indirect)
2206 /* Add reloc counts against the weak sym to the strong sym
2207 list. Merge any entries against the same section. */
2208 for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
2210 struct elf32_mb_dyn_relocs *q;
2212 for (q = edir->dyn_relocs; q != NULL; q = q->next)
2213 if (q->sec == p->sec)
2215 q->pc_count += p->pc_count;
2216 q->count += p->count;
2223 *pp = edir->dyn_relocs;
2226 edir->dyn_relocs = eind->dyn_relocs;
2227 eind->dyn_relocs = NULL;
2230 _bfd_elf_link_hash_copy_indirect (info, dir, ind);
2234 microblaze_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
2235 struct elf_link_hash_entry *h)
2237 struct elf32_mb_link_hash_table *htab;
2238 struct elf32_mb_link_hash_entry * eh;
2239 struct elf32_mb_dyn_relocs *p;
2240 asection *sdynbss, *s;
2241 unsigned int power_of_two;
2244 htab = elf32_mb_hash_table (info);
2248 /* If this is a function, put it in the procedure linkage table. We
2249 will fill in the contents of the procedure linkage table later,
2250 when we know the address of the .got section. */
2251 if (h->type == STT_FUNC
2254 if (h->plt.refcount <= 0
2255 || SYMBOL_CALLS_LOCAL (info, h)
2256 || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
2257 && h->root.type == bfd_link_hash_undefweak))
2259 /* This case can occur if we saw a PLT reloc in an input
2260 file, but the symbol was never referred to by a dynamic
2261 object, or if all references were garbage collected. In
2262 such a case, we don't actually need to build a procedure
2263 linkage table, and we can just do a PC32 reloc instead. */
2264 h->plt.offset = (bfd_vma) -1;
2271 /* It's possible that we incorrectly decided a .plt reloc was
2272 needed for an R_MICROBLAZE_64_PCREL reloc to a non-function sym in
2273 check_relocs. We can't decide accurately between function and
2274 non-function syms in check-relocs; Objects loaded later in
2275 the link may change h->type. So fix it now. */
2276 h->plt.offset = (bfd_vma) -1;
2278 /* If this is a weak symbol, and there is a real definition, the
2279 processor independent code will have arranged for us to see the
2280 real definition first, and we can just use the same value. */
2281 if (h->u.weakdef != NULL)
2283 BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
2284 || h->u.weakdef->root.type == bfd_link_hash_defweak);
2285 h->root.u.def.section = h->u.weakdef->root.u.def.section;
2286 h->root.u.def.value = h->u.weakdef->root.u.def.value;
2290 /* This is a reference to a symbol defined by a dynamic object which
2291 is not a function. */
2293 /* If we are creating a shared library, we must presume that the
2294 only references to the symbol are via the global offset table.
2295 For such cases we need not do anything here; the relocations will
2296 be handled correctly by relocate_section. */
2300 /* If there are no references to this symbol that do not use the
2301 GOT, we don't need to generate a copy reloc. */
2302 if (!h->non_got_ref)
2305 /* If -z nocopyreloc was given, we won't generate them either. */
2306 if (info->nocopyreloc)
2312 eh = (struct elf32_mb_link_hash_entry *) h;
2313 for (p = eh->dyn_relocs; p != NULL; p = p->next)
2315 s = p->sec->output_section;
2316 if (s != NULL && (s->flags & SEC_READONLY) != 0)
2320 /* If we didn't find any dynamic relocs in read-only sections, then
2321 we'll be keeping the dynamic relocs and avoiding the copy reloc. */
2328 /* We must allocate the symbol in our .dynbss section, which will
2329 become part of the .bss section of the executable. There will be
2330 an entry for this symbol in the .dynsym section. The dynamic
2331 object will contain position independent code, so all references
2332 from the dynamic object to this symbol will go through the global
2333 offset table. The dynamic linker will use the .dynsym entry to
2334 determine the address it must put in the global offset table, so
2335 both the dynamic object and the regular object will refer to the
2336 same memory location for the variable. */
2338 /* We must generate a R_MICROBLAZE_COPY reloc to tell the dynamic linker
2339 to copy the initial value out of the dynamic object and into the
2340 runtime process image. */
2341 dynobj = elf_hash_table (info)->dynobj;
2342 BFD_ASSERT (dynobj != NULL);
2343 if ((h->root.u.def.section->flags & SEC_ALLOC) != 0)
2345 htab->srelbss->size += sizeof (Elf32_External_Rela);
2349 /* We need to figure out the alignment required for this symbol. I
2350 have no idea how ELF linkers handle this. */
2351 power_of_two = bfd_log2 (h->size);
2352 if (power_of_two > 3)
2355 sdynbss = htab->sdynbss;
2356 /* Apply the required alignment. */
2357 sdynbss->size = BFD_ALIGN (sdynbss->size, (bfd_size_type) (1 << power_of_two));
2358 if (power_of_two > bfd_get_section_alignment (dynobj, sdynbss))
2360 if (! bfd_set_section_alignment (dynobj, sdynbss, power_of_two))
2364 /* Define the symbol as being at this point in the section. */
2365 h->root.u.def.section = sdynbss;
2366 h->root.u.def.value = sdynbss->size;
2368 /* Increment the section size to make room for the symbol. */
2369 sdynbss->size += h->size;
2373 /* Allocate space in .plt, .got and associated reloc sections for
2377 allocate_dynrelocs (struct elf_link_hash_entry *h, void * dat)
2379 struct bfd_link_info *info;
2380 struct elf32_mb_link_hash_table *htab;
2381 struct elf32_mb_link_hash_entry *eh;
2382 struct elf32_mb_dyn_relocs *p;
2384 if (h->root.type == bfd_link_hash_indirect)
2387 if (h->root.type == bfd_link_hash_warning)
2388 /* When warning symbols are created, they **replace** the "real"
2389 entry in the hash table, thus we never get to see the real
2390 symbol in a hash traversal. So look at it now. */
2391 h = (struct elf_link_hash_entry *) h->root.u.i.link;
2393 info = (struct bfd_link_info *) dat;
2394 htab = elf32_mb_hash_table (info);
2398 if (htab->elf.dynamic_sections_created
2399 && h->plt.refcount > 0)
2401 /* Make sure this symbol is output as a dynamic symbol.
2402 Undefined weak syms won't yet be marked as dynamic. */
2403 if (h->dynindx == -1
2404 && !h->forced_local)
2406 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2410 if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
2412 asection *s = htab->splt;
2414 /* The first entry in .plt is reserved. */
2416 s->size = PLT_ENTRY_SIZE;
2418 h->plt.offset = s->size;
2420 /* If this symbol is not defined in a regular file, and we are
2421 not generating a shared library, then set the symbol to this
2422 location in the .plt. This is required to make function
2423 pointers compare as equal between the normal executable and
2424 the shared library. */
2428 h->root.u.def.section = s;
2429 h->root.u.def.value = h->plt.offset;
2432 /* Make room for this entry. */
2433 s->size += PLT_ENTRY_SIZE;
2435 /* We also need to make an entry in the .got.plt section, which
2436 will be placed in the .got section by the linker script. */
2437 htab->sgotplt->size += 4;
2439 /* We also need to make an entry in the .rel.plt section. */
2440 htab->srelplt->size += sizeof (Elf32_External_Rela);
2444 h->plt.offset = (bfd_vma) -1;
2450 h->plt.offset = (bfd_vma) -1;
2454 if (h->got.refcount > 0)
2458 /* Make sure this symbol is output as a dynamic symbol.
2459 Undefined weak syms won't yet be marked as dynamic. */
2460 if (h->dynindx == -1
2461 && !h->forced_local)
2463 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2468 h->got.offset = s->size;
2470 htab->srelgot->size += sizeof (Elf32_External_Rela);
2473 h->got.offset = (bfd_vma) -1;
2475 eh = (struct elf32_mb_link_hash_entry *) h;
2476 if (eh->dyn_relocs == NULL)
2479 /* In the shared -Bsymbolic case, discard space allocated for
2480 dynamic pc-relative relocs against symbols which turn out to be
2481 defined in regular objects. For the normal shared case, discard
2482 space for pc-relative relocs that have become local due to symbol
2483 visibility changes. */
2491 struct elf32_mb_dyn_relocs **pp;
2493 for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
2495 p->count -= p->pc_count;
2506 /* For the non-shared case, discard space for relocs against
2507 symbols which turn out to need copy relocs or are not
2513 || (htab->elf.dynamic_sections_created
2514 && (h->root.type == bfd_link_hash_undefweak
2515 || h->root.type == bfd_link_hash_undefined))))
2517 /* Make sure this symbol is output as a dynamic symbol.
2518 Undefined weak syms won't yet be marked as dynamic. */
2519 if (h->dynindx == -1
2520 && !h->forced_local)
2522 if (! bfd_elf_link_record_dynamic_symbol (info, h))
2526 /* If that succeeded, we know we'll be keeping all the
2528 if (h->dynindx != -1)
2532 eh->dyn_relocs = NULL;
2537 /* Finally, allocate space. */
2538 for (p = eh->dyn_relocs; p != NULL; p = p->next)
2540 asection *sreloc = elf_section_data (p->sec)->sreloc;
2541 sreloc->size += p->count * sizeof (Elf32_External_Rela);
2547 /* Set the sizes of the dynamic sections. */
2550 microblaze_elf_size_dynamic_sections (bfd *output_bfd ATTRIBUTE_UNUSED,
2551 struct bfd_link_info *info)
2553 struct elf32_mb_link_hash_table *htab;
2558 htab = elf32_mb_hash_table (info);
2562 dynobj = htab->elf.dynobj;
2563 BFD_ASSERT (dynobj != NULL);
2565 /* Set up .got offsets for local syms, and space for local dynamic
2567 for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link_next)
2569 bfd_signed_vma *local_got;
2570 bfd_signed_vma *end_local_got;
2571 bfd_size_type locsymcount;
2572 Elf_Internal_Shdr *symtab_hdr;
2575 if (bfd_get_flavour (ibfd) != bfd_target_elf_flavour)
2578 for (s = ibfd->sections; s != NULL; s = s->next)
2580 struct elf32_mb_dyn_relocs *p;
2582 for (p = ((struct elf32_mb_dyn_relocs *)
2583 elf_section_data (s)->local_dynrel);
2587 if (!bfd_is_abs_section (p->sec)
2588 && bfd_is_abs_section (p->sec->output_section))
2590 /* Input section has been discarded, either because
2591 it is a copy of a linkonce section or due to
2592 linker script /DISCARD/, so we'll be discarding
2595 else if (p->count != 0)
2597 srel = elf_section_data (p->sec)->sreloc;
2598 srel->size += p->count * sizeof (Elf32_External_Rela);
2599 if ((p->sec->output_section->flags & SEC_READONLY) != 0)
2600 info->flags |= DF_TEXTREL;
2605 local_got = elf_local_got_refcounts (ibfd);
2609 symtab_hdr = &elf_tdata (ibfd)->symtab_hdr;
2610 locsymcount = symtab_hdr->sh_info;
2611 end_local_got = local_got + locsymcount;
2613 srel = htab->srelgot;
2615 for (; local_got < end_local_got; ++local_got)
2619 *local_got = s->size;
2622 srel->size += sizeof (Elf32_External_Rela);
2625 *local_got = (bfd_vma) -1;
2629 /* Allocate global sym .plt and .got entries, and space for global
2630 sym dynamic relocs. */
2631 elf_link_hash_traverse (elf_hash_table (info), allocate_dynrelocs, info);
2633 if (elf_hash_table (info)->dynamic_sections_created)
2635 /* Make space for the trailing nop in .plt. */
2636 if (htab->splt->size > 0)
2637 htab->splt->size += 4;
2640 /* The check_relocs and adjust_dynamic_symbol entry points have
2641 determined the sizes of the various dynamic sections. Allocate
2643 for (s = dynobj->sections; s != NULL; s = s->next)
2646 bfd_boolean strip = FALSE;
2648 if ((s->flags & SEC_LINKER_CREATED) == 0)
2651 /* It's OK to base decisions on the section name, because none
2652 of the dynobj section names depend upon the input files. */
2653 name = bfd_get_section_name (dynobj, s);
2655 if (strncmp (name, ".rela", 5) == 0)
2659 /* If we don't need this section, strip it from the
2660 output file. This is to handle .rela.bss and
2661 .rela.plt. We must create it in
2662 create_dynamic_sections, because it must be created
2663 before the linker maps input sections to output
2664 sections. The linker does that before
2665 adjust_dynamic_symbol is called, and it is that
2666 function which decides whether anything needs to go
2667 into these sections. */
2672 /* We use the reloc_count field as a counter if we need
2673 to copy relocs into the output file. */
2677 else if (s != htab->splt && s != htab->sgot && s != htab->sgotplt)
2679 /* It's not one of our sections, so don't allocate space. */
2685 s->flags |= SEC_EXCLUDE;
2689 /* Allocate memory for the section contents. */
2690 /* FIXME: This should be a call to bfd_alloc not bfd_zalloc.
2691 Unused entries should be reclaimed before the section's contents
2692 are written out, but at the moment this does not happen. Thus in
2693 order to prevent writing out garbage, we initialise the section's
2694 contents to zero. */
2695 s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
2696 if (s->contents == NULL && s->size != 0)
2700 if (elf_hash_table (info)->dynamic_sections_created)
2702 /* Add some entries to the .dynamic section. We fill in the
2703 values later, in microblaze_elf_finish_dynamic_sections, but we
2704 must add the entries now so that we get the correct size for
2705 the .dynamic section. The DT_DEBUG entry is filled in by the
2706 dynamic linker and used by the debugger. */
2707 #define add_dynamic_entry(TAG, VAL) \
2708 _bfd_elf_add_dynamic_entry (info, TAG, VAL)
2710 if (info->executable)
2712 if (!add_dynamic_entry (DT_DEBUG, 0))
2716 if (!add_dynamic_entry (DT_RELA, 0)
2717 || !add_dynamic_entry (DT_RELASZ, 0)
2718 || !add_dynamic_entry (DT_RELAENT, sizeof (Elf32_External_Rela)))
2721 if (htab->splt->size != 0)
2723 if (!add_dynamic_entry (DT_PLTGOT, 0)
2724 || !add_dynamic_entry (DT_PLTRELSZ, 0)
2725 || !add_dynamic_entry (DT_PLTREL, DT_RELA)
2726 || !add_dynamic_entry (DT_JMPREL, 0)
2727 || !add_dynamic_entry (DT_BIND_NOW, 1))
2731 if (info->flags & DF_TEXTREL)
2733 if (!add_dynamic_entry (DT_TEXTREL, 0))
2737 #undef add_dynamic_entry
2741 /* Finish up dynamic symbol handling. We set the contents of various
2742 dynamic sections here. */
2745 microblaze_elf_finish_dynamic_symbol (bfd *output_bfd,
2746 struct bfd_link_info *info,
2747 struct elf_link_hash_entry *h,
2748 Elf_Internal_Sym *sym)
2751 struct elf32_mb_link_hash_table *htab;
2753 htab = elf32_mb_hash_table (info);
2757 dynobj = htab->elf.dynobj;
2759 if (h->plt.offset != (bfd_vma) -1)
2764 Elf_Internal_Rela rela;
2770 /* This symbol has an entry in the procedure linkage table. Set
2772 BFD_ASSERT (h->dynindx != -1);
2775 srela = htab->srelplt;
2776 sgotplt = htab->sgotplt;
2777 BFD_ASSERT (splt != NULL && srela != NULL && sgotplt != NULL);
2779 plt_index = h->plt.offset / PLT_ENTRY_SIZE - 1; /* first entry reserved. */
2780 got_offset = (plt_index + 3) * 4; /* 3 reserved ??? */
2781 got_addr = got_offset;
2783 /* For non-PIC objects we need absolute address of the GOT entry. */
2785 got_addr += htab->sgotplt->output_section->vma + sgotplt->output_offset;
2787 /* Fill in the entry in the procedure linkage table. */
2788 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_0 + ((got_addr >> 16) & 0xffff),
2789 splt->contents + h->plt.offset);
2791 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1 + (got_addr & 0xffff),
2792 splt->contents + h->plt.offset + 4);
2794 bfd_put_32 (output_bfd, PLT_ENTRY_WORD_1_NOPIC + (got_addr & 0xffff),
2795 splt->contents + h->plt.offset + 4);
2796 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_2,
2797 splt->contents + h->plt.offset + 8);
2798 bfd_put_32 (output_bfd, (bfd_vma) PLT_ENTRY_WORD_3,
2799 splt->contents + h->plt.offset + 12);
2801 /* Any additions to the .got section??? */
2802 /* bfd_put_32 (output_bfd,
2803 splt->output_section->vma + splt->output_offset + h->plt.offset + 4,
2804 sgotplt->contents + got_offset); */
2806 /* Fill in the entry in the .rela.plt section. */
2807 rela.r_offset = (sgotplt->output_section->vma
2808 + sgotplt->output_offset
2810 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_JUMP_SLOT);
2812 loc = srela->contents;
2813 loc += plt_index * sizeof (Elf32_External_Rela);
2814 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
2816 if (!h->def_regular)
2818 /* Mark the symbol as undefined, rather than as defined in
2819 the .plt section. Zero the value. */
2820 sym->st_shndx = SHN_UNDEF;
2825 if (h->got.offset != (bfd_vma) -1)
2829 Elf_Internal_Rela rela;
2832 /* This symbol has an entry in the global offset table. Set it
2836 srela = htab->srelgot;
2837 BFD_ASSERT (sgot != NULL && srela != NULL);
2839 rela.r_offset = (sgot->output_section->vma
2840 + sgot->output_offset
2841 + (h->got.offset &~ (bfd_vma) 1));
2843 /* If this is a -Bsymbolic link, and the symbol is defined
2844 locally, we just want to emit a RELATIVE reloc. Likewise if
2845 the symbol was forced to be local because of a version file.
2846 The entry in the global offset table will already have been
2847 initialized in the relocate_section function. */
2849 && (info->symbolic || h->dynindx == -1)
2852 asection *sec = h->root.u.def.section;
2853 rela.r_info = ELF32_R_INFO (0, R_MICROBLAZE_REL);
2854 rela.r_addend = (h->root.u.def.value
2855 + sec->output_section->vma
2856 + sec->output_offset);
2860 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_GLOB_DAT);
2864 bfd_put_32 (output_bfd, (bfd_vma) 0,
2865 sgot->contents + (h->got.offset &~ (bfd_vma) 1));
2866 loc = srela->contents;
2867 loc += srela->reloc_count++ * sizeof (Elf32_External_Rela);
2868 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
2874 Elf_Internal_Rela rela;
2877 /* This symbols needs a copy reloc. Set it up. */
2879 BFD_ASSERT (h->dynindx != -1);
2881 s = bfd_get_section_by_name (h->root.u.def.section->owner,
2883 BFD_ASSERT (s != NULL);
2885 rela.r_offset = (h->root.u.def.value
2886 + h->root.u.def.section->output_section->vma
2887 + h->root.u.def.section->output_offset);
2888 rela.r_info = ELF32_R_INFO (h->dynindx, R_MICROBLAZE_COPY);
2890 loc = s->contents + s->reloc_count++ * sizeof (Elf32_External_Rela);
2891 bfd_elf32_swap_reloca_out (output_bfd, &rela, loc);
2894 /* Mark some specially defined symbols as absolute. */
2895 if (strcmp (h->root.root.string, "_DYNAMIC") == 0
2896 || strcmp (h->root.root.string, "_GLOBAL_OFFSET_TABLE_") == 0
2897 || strcmp (h->root.root.string, "_PROCEDURE_LINKAGE_TABLE_") == 0)
2898 sym->st_shndx = SHN_ABS;
2904 /* Finish up the dynamic sections. */
2907 microblaze_elf_finish_dynamic_sections (bfd *output_bfd,
2908 struct bfd_link_info *info)
2911 asection *sdyn, *sgot;
2912 struct elf32_mb_link_hash_table *htab;
2914 htab = elf32_mb_hash_table (info);
2918 dynobj = htab->elf.dynobj;
2920 sdyn = bfd_get_section_by_name (dynobj, ".dynamic");
2922 if (htab->elf.dynamic_sections_created)
2925 Elf32_External_Dyn *dyncon, *dynconend;
2927 splt = bfd_get_section_by_name (dynobj, ".plt");
2928 BFD_ASSERT (splt != NULL && sdyn != NULL);
2930 dyncon = (Elf32_External_Dyn *) sdyn->contents;
2931 dynconend = (Elf32_External_Dyn *) (sdyn->contents + sdyn->size);
2932 for (; dyncon < dynconend; dyncon++)
2934 Elf_Internal_Dyn dyn;
2938 bfd_elf32_swap_dyn_in (dynobj, dyncon, &dyn);
2942 case DT_PLTGOT: name = ".got.plt"; size = FALSE; break;
2943 case DT_PLTRELSZ: name = ".rela.plt"; size = TRUE; break;
2944 case DT_JMPREL: name = ".rela.plt"; size = FALSE; break;
2945 case DT_RELA: name = ".rela.dyn"; size = FALSE; break;
2946 case DT_RELASZ: name = ".rela.dyn"; size = TRUE; break;
2947 default: name = NULL; size = FALSE; break;
2954 s = bfd_get_section_by_name (output_bfd, name);
2960 dyn.d_un.d_ptr = s->vma;
2962 dyn.d_un.d_val = s->size;
2964 bfd_elf32_swap_dyn_out (output_bfd, &dyn, dyncon);
2968 /* Clear the first entry in the procedure linkage table,
2969 and put a nop in the last four bytes. */
2972 memset (splt->contents, 0, PLT_ENTRY_SIZE);
2973 bfd_put_32 (output_bfd, (bfd_vma) 0x80000000 /* nop. */,
2974 splt->contents + splt->size - 4);
2977 elf_section_data (splt->output_section)->this_hdr.sh_entsize = 4;
2980 /* Set the first entry in the global offset table to the address of
2981 the dynamic section. */
2982 sgot = bfd_get_section_by_name (dynobj, ".got.plt");
2983 if (sgot && sgot->size > 0)
2986 bfd_put_32 (output_bfd, (bfd_vma) 0, sgot->contents);
2988 bfd_put_32 (output_bfd,
2989 sdyn->output_section->vma + sdyn->output_offset,
2991 elf_section_data (sgot->output_section)->this_hdr.sh_entsize = 4;
2994 if (htab->sgot && htab->sgot->size > 0)
2995 elf_section_data (htab->sgot->output_section)->this_hdr.sh_entsize = 4;
3000 /* Hook called by the linker routine which adds symbols from an object
3001 file. We use it to put .comm items in .sbss, and not .bss. */
3004 microblaze_elf_add_symbol_hook (bfd *abfd,
3005 struct bfd_link_info *info,
3006 Elf_Internal_Sym *sym,
3007 const char **namep ATTRIBUTE_UNUSED,
3008 flagword *flagsp ATTRIBUTE_UNUSED,
3012 if (sym->st_shndx == SHN_COMMON
3013 && !info->relocatable
3014 && sym->st_size <= elf_gp_size (abfd))
3016 /* Common symbols less than or equal to -G nn bytes are automatically
3018 *secp = bfd_make_section_anyway (abfd, ".sbss");
3020 || ! bfd_set_section_flags (abfd, *secp, SEC_IS_COMMON))
3023 *valp = sym->st_size;
3030 #define TARGET_BIG_SYM bfd_elf32_microblaze_vec
3031 #define TARGET_BIG_NAME "elf32-microblaze"
3033 #define ELF_ARCH bfd_arch_microblaze
3034 #define ELF_MACHINE_CODE EM_MICROBLAZE
3035 #define ELF_MACHINE_ALT1 EM_MICROBLAZE_OLD
3036 #define ELF_MAXPAGESIZE 0x4 /* 4k, if we ever have 'em. */
3037 #define elf_info_to_howto microblaze_elf_info_to_howto
3038 #define elf_info_to_howto_rel NULL
3040 #define bfd_elf32_bfd_reloc_type_lookup microblaze_elf_reloc_type_lookup
3041 #define bfd_elf32_bfd_is_local_label_name microblaze_elf_is_local_label_name
3042 #define elf_backend_relocate_section microblaze_elf_relocate_section
3043 #define bfd_elf32_bfd_relax_section microblaze_elf_relax_section
3044 #define bfd_elf32_bfd_reloc_name_lookup microblaze_elf_reloc_name_lookup
3046 #define elf_backend_gc_mark_hook microblaze_elf_gc_mark_hook
3047 #define elf_backend_gc_sweep_hook microblaze_elf_gc_sweep_hook
3048 #define elf_backend_check_relocs microblaze_elf_check_relocs
3049 #define elf_backend_copy_indirect_symbol microblaze_elf_copy_indirect_symbol
3050 #define bfd_elf32_bfd_link_hash_table_create microblaze_elf_link_hash_table_create
3051 #define elf_backend_can_gc_sections 1
3052 #define elf_backend_can_refcount 1
3053 #define elf_backend_want_got_plt 1
3054 #define elf_backend_plt_readonly 1
3055 #define elf_backend_got_header_size 12
3056 #define elf_backend_rela_normal 1
3058 #define elf_backend_adjust_dynamic_symbol microblaze_elf_adjust_dynamic_symbol
3059 #define elf_backend_create_dynamic_sections microblaze_elf_create_dynamic_sections
3060 #define elf_backend_finish_dynamic_sections microblaze_elf_finish_dynamic_sections
3061 #define elf_backend_finish_dynamic_symbol microblaze_elf_finish_dynamic_symbol
3062 #define elf_backend_size_dynamic_sections microblaze_elf_size_dynamic_sections
3063 #define elf_backend_add_symbol_hook microblaze_elf_add_symbol_hook
3065 #include "elf32-target.h"