Touches most files in bfd/, so likely will be blamed for everything..
[binutils.git] / bfd / elf32-openrisc.c
blob20358e09e38423e7eb380523b99747ec2796b212
1 /* OpenRISC-specific support for 32-bit ELF.
2 Copyright 2001 Free Software Foundation, Inc.
3 Contributed by Johan Rydberg, jrydberg@opencores.org
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 2 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 Free Software
19 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 #include "bfd.h"
22 #include "sysdep.h"
23 #include "libbfd.h"
24 #include "elf-bfd.h"
25 #include "elf/openrisc.h"
26 #include "libiberty.h"
28 /* Forward declarations. */
30 static reloc_howto_type *openrisc_reloc_type_lookup
31 PARAMS ((bfd * , bfd_reloc_code_real_type));
32 static void openrisc_info_to_howto_rela
33 PARAMS ((bfd *, arelent *, Elf32_Internal_Rela *));
34 static boolean openrisc_elf_relocate_section
35 PARAMS ((bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
36 Elf_Internal_Rela *, Elf_Internal_Sym *, asection **));
37 static bfd_reloc_status_type openrisc_final_link_relocate
38 PARAMS ((reloc_howto_type *, bfd *, asection *, bfd_byte *,
39 Elf_Internal_Rela *, bfd_vma));
40 static boolean openrisc_elf_gc_sweep_hook
41 PARAMS ((bfd *, struct bfd_link_info *, asection *,
42 const Elf_Internal_Rela *));
43 static asection * openrisc_elf_gc_mark_hook
44 PARAMS ((bfd *, struct bfd_link_info *, Elf_Internal_Rela *,
45 struct elf_link_hash_entry *, Elf_Internal_Sym *));
46 static boolean openrisc_elf_check_relocs
47 PARAMS ((bfd *, struct bfd_link_info *, asection *,
48 const Elf_Internal_Rela *));
49 static boolean openrisc_elf_object_p
50 PARAMS ((bfd *));
51 static void openrisc_elf_final_write_processing
52 PARAMS ((bfd *, boolean));
55 static reloc_howto_type openrisc_elf_howto_table[] =
57 /* This reloc does nothing. */
58 HOWTO (R_OPENRISC_NONE, /* type */
59 0, /* rightshift */
60 2, /* size (0 = byte, 1 = short, 2 = long) */
61 32, /* bitsize */
62 false, /* pc_relative */
63 0, /* bitpos */
64 complain_overflow_bitfield, /* complain_on_overflow */
65 bfd_elf_generic_reloc, /* special_function */
66 "R_OPENRISC_NONE", /* name */
67 false, /* partial_inplace */
68 0, /* src_mask */
69 0, /* dst_mask */
70 false), /* pcrel_offset */
72 /* A PC relative 26 bit relocation, right shifted by 2. */
73 HOWTO (R_OPENRISC_INSN_REL_26, /* type */
74 2, /* rightshift */
75 2, /* size (0 = byte, 1 = short, 2 = long) */
76 26, /* bitsize */
77 true, /* pc_relative */
78 0, /* bitpos */
79 complain_overflow_signed, /* complain_on_overflow */
80 bfd_elf_generic_reloc, /* special_function */
81 "R_OPENRISC_INSN_REL_26", /* name */
82 false, /* partial_inplace */
83 0x00000000, /* src_mask */
84 0x03ffffff, /* dst_mask */
85 false), /* pcrel_offset */
87 /* A absolute 26 bit relocation, right shifted by 2. */
88 HOWTO (R_OPENRISC_INSN_ABS_26, /* type */
89 2, /* rightshift */
90 2, /* size (0 = byte, 1 = short, 2 = long) */
91 26, /* bitsize */
92 false, /* pc_relative */
93 0, /* bitpos */
94 complain_overflow_signed, /* complain_on_overflow */
95 bfd_elf_generic_reloc, /* special_function */
96 "R_OPENRISC_INSN_ABS_26", /* name */
97 false, /* partial_inplace */
98 0x00000000, /* src_mask */
99 0x03ffffff, /* dst_mask */
100 false), /* pcrel_offset */
102 HOWTO (R_OPENRISC_LO_16_IN_INSN, /* type */
103 0, /* rightshift */
104 1, /* size (0 = byte, 1 = short, 2 = long) */
105 16, /* bitsize */
106 false, /* pc_relative */
107 0, /* bitpos */
108 complain_overflow_dont, /* complain_on_overflow */
109 bfd_elf_generic_reloc, /* special_function */
110 "R_OPENRISC_LO_16_IN_INSN", /* name */
111 false, /* partial_inplace */
112 0, /* src_mask */
113 0x0000ffff, /* dst_mask */
114 false), /* pcrel_offset */
116 HOWTO (R_OPENRISC_HI_16_IN_INSN, /* type */
117 16, /* rightshift */
118 1, /* size (0 = byte, 1 = short, 2 = long) */
119 16, /* bitsize */
120 false, /* pc_relative */
121 0, /* bitpos */
122 complain_overflow_dont, /* complain_on_overflow */
123 bfd_elf_generic_reloc, /* special_function */
124 "R_OPENRISC_HI_16_IN_INSN", /* name */
125 false, /* partial_inplace */
126 0, /* src_mask */
127 0x0000ffff, /* dst_mask */
128 false), /* pcrel_offset */
130 /* An 8 bit absolute relocation. */
131 HOWTO (R_OPENRISC_8, /* type */
132 0, /* rightshift */
133 0, /* size (0 = byte, 1 = short, 2 = long) */
134 8, /* bitsize */
135 false, /* pc_relative */
136 0, /* bitpos */
137 complain_overflow_bitfield, /* complain_on_overflow */
138 bfd_elf_generic_reloc, /* special_function */
139 "R_OPENRISC_8", /* name */
140 true, /* partial_inplace */
141 0x0000, /* src_mask */
142 0x00ff, /* dst_mask */
143 false), /* pcrel_offset */
145 /* A 16 bit absolute relocation. */
146 HOWTO (R_OPENRISC_16, /* type */
147 0, /* rightshift */
148 1, /* size (0 = byte, 1 = short, 2 = long) */
149 16, /* bitsize */
150 false, /* pc_relative */
151 0, /* bitpos */
152 complain_overflow_bitfield, /* complain_on_overflow */
153 bfd_elf_generic_reloc, /* special_function */
154 "R_OPENRISC_16", /* name */
155 true, /* partial_inplace */
156 0x00000000, /* src_mask */
157 0x0000ffff, /* dst_mask */
158 false), /* pcrel_offset */
160 /* A 32 bit absolute relocation. */
161 HOWTO (R_OPENRISC_32, /* type */
162 0, /* rightshift */
163 2, /* size (0 = byte, 1 = short, 2 = long) */
164 32, /* bitsize */
165 false, /* pc_relative */
166 0, /* bitpos */
167 complain_overflow_bitfield, /* complain_on_overflow */
168 bfd_elf_generic_reloc, /* special_function */
169 "R_OPENRISC_32", /* name */
170 true, /* partial_inplace */
171 0x00000000, /* src_mask */
172 0xffffffff, /* dst_mask */
173 false), /* pcrel_offset */
175 /* GNU extension to record C++ vtable hierarchy */
176 HOWTO (R_OPENRISC_GNU_VTINHERIT, /* type */
177 0, /* rightshift */
178 2, /* size (0 = byte, 1 = short, 2 = long) */
179 0, /* bitsize */
180 false, /* pc_relative */
181 0, /* bitpos */
182 complain_overflow_dont, /* complain_on_overflow */
183 NULL, /* special_function */
184 "R_OPENRISC_GNU_VTINHERIT", /* name */
185 false, /* partial_inplace */
186 0, /* src_mask */
187 0, /* dst_mask */
188 false), /* pcrel_offset */
190 /* GNU extension to record C++ vtable member usage */
191 HOWTO (R_OPENRISC_GNU_VTENTRY, /* type */
192 0, /* rightshift */
193 2, /* size (0 = byte, 1 = short, 2 = long) */
194 0, /* bitsize */
195 false, /* pc_relative */
196 0, /* bitpos */
197 complain_overflow_dont, /* complain_on_overflow */
198 _bfd_elf_rel_vtable_reloc_fn, /* special_function */
199 "R_OPENRISC_GNU_VTENTRY", /* name */
200 false, /* partial_inplace */
201 0, /* src_mask */
202 0, /* dst_mask */
203 false), /* pcrel_offset */
206 /* Map BFD reloc types to OpenRISC ELF reloc types. */
208 struct openrisc_reloc_map
210 bfd_reloc_code_real_type bfd_reloc_val;
211 unsigned int openrisc_reloc_val;
214 static const struct openrisc_reloc_map openrisc_reloc_map[] =
216 { BFD_RELOC_NONE, R_OPENRISC_NONE },
217 { BFD_RELOC_32, R_OPENRISC_32 },
218 { BFD_RELOC_16, R_OPENRISC_16 },
219 { BFD_RELOC_8, R_OPENRISC_8 },
220 { BFD_RELOC_OPENRISC_REL_26,R_OPENRISC_INSN_REL_26 },
221 { BFD_RELOC_OPENRISC_ABS_26,R_OPENRISC_INSN_ABS_26 },
222 { BFD_RELOC_HI16, R_OPENRISC_HI_16_IN_INSN },
223 { BFD_RELOC_LO16, R_OPENRISC_LO_16_IN_INSN },
224 { BFD_RELOC_VTABLE_INHERIT, R_OPENRISC_GNU_VTINHERIT },
225 { BFD_RELOC_VTABLE_ENTRY, R_OPENRISC_GNU_VTENTRY }
228 static reloc_howto_type *
229 openrisc_reloc_type_lookup (abfd, code)
230 bfd * abfd ATTRIBUTE_UNUSED;
231 bfd_reloc_code_real_type code;
233 unsigned int i;
235 for (i = ARRAY_SIZE (openrisc_reloc_map); --i;)
236 if (openrisc_reloc_map[i].bfd_reloc_val == code)
237 return & openrisc_elf_howto_table[openrisc_reloc_map[i].
238 openrisc_reloc_val];
240 return NULL;
243 /* Set the howto pointer for an OpenRISC ELF reloc. */
245 static void
246 openrisc_info_to_howto_rela (abfd, cache_ptr, dst)
247 bfd * abfd ATTRIBUTE_UNUSED;
248 arelent * cache_ptr;
249 Elf32_Internal_Rela * dst;
251 unsigned int r_type;
253 r_type = ELF32_R_TYPE (dst->r_info);
254 BFD_ASSERT (r_type < (unsigned int) R_OPENRISC_max);
255 cache_ptr->howto = & openrisc_elf_howto_table[r_type];
258 /* Perform a single relocation. By default we use the standard BFD
259 routines, but a few relocs, we have to do them ourselves. */
261 static bfd_reloc_status_type
262 openrisc_final_link_relocate (howto, input_bfd, input_section, contents, rel,
263 relocation)
264 reloc_howto_type *howto;
265 bfd *input_bfd;
266 asection *input_section;
267 bfd_byte *contents;
268 Elf_Internal_Rela *rel;
269 bfd_vma relocation;
271 bfd_reloc_status_type r = bfd_reloc_ok;
273 switch (howto->type)
275 case R_OPENRISC_LO_16_IN_INSN:
276 relocation &= 0xffff;
277 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
278 contents, rel->r_offset,
279 relocation, rel->r_addend);
280 break;
282 default:
283 r = _bfd_final_link_relocate (howto, input_bfd, input_section,
284 contents, rel->r_offset,
285 relocation, rel->r_addend);
288 return r;
291 /* Relocate an OpenRISC ELF section.
292 There is some attempt to make this function usable for many architectures,
293 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
294 if only to serve as a learning tool.
296 The RELOCATE_SECTION function is called by the new ELF backend linker
297 to handle the relocations for a section.
299 The relocs are always passed as Rela structures; if the section
300 actually uses Rel structures, the r_addend field will always be
301 zero.
303 This function is responsible for adjusting the section contents as
304 necessary, and (if using Rela relocs and generating a relocateable
305 output file) adjusting the reloc addend as necessary.
307 This function does not have to worry about setting the reloc
308 address or the reloc symbol index.
310 LOCAL_SYMS is a pointer to the swapped in local symbols.
312 LOCAL_SECTIONS is an array giving the section in the input file
313 corresponding to the st_shndx field of each local symbol.
315 The global hash table entry for the global symbols can be found
316 via elf_sym_hashes (input_bfd).
318 When generating relocateable output, this function must handle
319 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
320 going to be the section symbol corresponding to the output
321 section, which means that the addend must be adjusted
322 accordingly. */
324 static boolean
325 openrisc_elf_relocate_section (output_bfd, info, input_bfd, input_section,
326 contents, relocs, local_syms, local_sections)
327 bfd *output_bfd ATTRIBUTE_UNUSED;
328 struct bfd_link_info *info;
329 bfd *input_bfd;
330 asection *input_section;
331 bfd_byte *contents;
332 Elf_Internal_Rela *relocs;
333 Elf_Internal_Sym *local_syms;
334 asection **local_sections;
336 Elf_Internal_Shdr *symtab_hdr;
337 struct elf_link_hash_entry **sym_hashes;
338 Elf_Internal_Rela *rel;
339 Elf_Internal_Rela *relend;
341 symtab_hdr = &elf_tdata (input_bfd)->symtab_hdr;
342 sym_hashes = elf_sym_hashes (input_bfd);
343 relend = relocs + input_section->reloc_count;
345 for (rel = relocs; rel < relend; rel++)
347 reloc_howto_type *howto;
348 unsigned long r_symndx;
349 Elf_Internal_Sym *sym;
350 asection *sec;
351 struct elf_link_hash_entry *h;
352 bfd_vma relocation;
353 bfd_reloc_status_type r;
354 const char *name = NULL;
355 int r_type;
357 r_type = ELF32_R_TYPE (rel->r_info);
358 r_symndx = ELF32_R_SYM (rel->r_info);
360 if (r_type == R_OPENRISC_GNU_VTINHERIT
361 || r_type == R_OPENRISC_GNU_VTENTRY)
362 continue;
364 if (info->relocateable)
366 /* This is a relocateable link. We don't have to change
367 anything, unless the reloc is against a section symbol,
368 in which case we have to adjust according to where the
369 section symbol winds up in the output section. */
370 if (r_symndx < symtab_hdr->sh_info)
372 sym = local_syms + r_symndx;
374 if (ELF_ST_TYPE (sym->st_info) == STT_SECTION)
376 sec = local_sections[r_symndx];
377 rel->r_addend += sec->output_offset + sym->st_value;
380 continue;
383 if ((unsigned int) r_type >
384 (sizeof openrisc_elf_howto_table / sizeof (reloc_howto_type)))
385 abort ();
387 /* This is a final link. */
388 howto = openrisc_elf_howto_table + ELF32_R_TYPE (rel->r_info);
389 h = NULL;
390 sym = NULL;
391 sec = NULL;
393 if (r_symndx < symtab_hdr->sh_info)
395 sym = local_syms + r_symndx;
396 sec = local_sections[r_symndx];
397 relocation = (sec->output_section->vma
398 + sec->output_offset + sym->st_value);
400 name = bfd_elf_string_from_elf_section
401 (input_bfd, symtab_hdr->sh_link, sym->st_name);
402 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
404 else
406 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
408 while (h->root.type == bfd_link_hash_indirect
409 || h->root.type == bfd_link_hash_warning)
410 h = (struct elf_link_hash_entry *) h->root.u.i.link;
412 name = h->root.root.string;
414 if (h->root.type == bfd_link_hash_defined
415 || h->root.type == bfd_link_hash_defweak)
417 sec = h->root.u.def.section;
418 relocation = (h->root.u.def.value
419 + sec->output_section->vma + sec->output_offset);
421 else if (h->root.type == bfd_link_hash_undefweak)
423 relocation = 0;
425 else
427 if (!((*info->callbacks->undefined_symbol)
428 (info, h->root.root.string, input_bfd,
429 input_section, rel->r_offset, true)))
430 return false;
431 relocation = 0;
435 r = openrisc_final_link_relocate (howto, input_bfd, input_section,
436 contents, rel, relocation);
438 if (r != bfd_reloc_ok)
440 const char *msg = (const char *) NULL;
442 switch (r)
444 case bfd_reloc_overflow:
445 r = info->callbacks->reloc_overflow
446 (info, name, howto->name, (bfd_vma) 0,
447 input_bfd, input_section, rel->r_offset);
448 break;
450 case bfd_reloc_undefined:
451 r = info->callbacks->undefined_symbol
452 (info, name, input_bfd, input_section, rel->r_offset, true);
453 break;
455 case bfd_reloc_outofrange:
456 msg = _("internal error: out of range error");
457 break;
459 case bfd_reloc_notsupported:
460 msg = _("internal error: unsupported relocation error");
461 break;
463 case bfd_reloc_dangerous:
464 msg = _("internal error: dangerous relocation");
465 break;
467 default:
468 msg = _("internal error: unknown error");
469 break;
472 if (msg)
473 r = info->callbacks->warning
474 (info, msg, name, input_bfd, input_section, rel->r_offset);
476 if (!r)
477 return false;
481 return true;
484 /* Return the section that should be marked against GC for a given
485 relocation. */
487 static asection *
488 openrisc_elf_gc_mark_hook (abfd, info, rel, h, sym)
489 bfd *abfd ATTRIBUTE_UNUSED;
490 struct bfd_link_info *info ATTRIBUTE_UNUSED;
491 Elf_Internal_Rela *rel ATTRIBUTE_UNUSED;
492 struct elf_link_hash_entry *h ATTRIBUTE_UNUSED;
493 Elf_Internal_Sym *sym ATTRIBUTE_UNUSED;
495 if (h != NULL)
497 switch (ELF32_R_TYPE (rel->r_info))
499 case R_OPENRISC_GNU_VTINHERIT:
500 case R_OPENRISC_GNU_VTENTRY:
501 break;
503 default:
504 switch (h->root.type)
506 case bfd_link_hash_defined:
507 case bfd_link_hash_defweak:
508 return h->root.u.def.section;
510 case bfd_link_hash_common:
511 return h->root.u.c.p->section;
513 default:
514 break;
518 else
520 if (!(elf_bad_symtab (abfd)
521 && ELF_ST_BIND (sym->st_info) != STB_LOCAL)
522 && !((sym->st_shndx <= 0 || sym->st_shndx >= SHN_LORESERVE)
523 && sym->st_shndx != SHN_COMMON))
525 return bfd_section_from_elf_index (abfd, sym->st_shndx);
529 return NULL;
532 /* Update the got entry reference counts for the section being removed. */
534 static boolean
535 openrisc_elf_gc_sweep_hook (abfd, info, sec, relocs)
536 bfd *abfd ATTRIBUTE_UNUSED;
537 struct bfd_link_info *info ATTRIBUTE_UNUSED;
538 asection *sec ATTRIBUTE_UNUSED;
539 const Elf_Internal_Rela *relocs ATTRIBUTE_UNUSED;
541 return true;
544 /* Look through the relocs for a section during the first phase.
545 Since we don't do .gots or .plts, we just need to consider the
546 virtual table relocs for gc. */
548 static boolean
549 openrisc_elf_check_relocs (abfd, info, sec, relocs)
550 bfd *abfd;
551 struct bfd_link_info *info;
552 asection *sec;
553 const Elf_Internal_Rela *relocs;
555 Elf_Internal_Shdr *symtab_hdr;
556 struct elf_link_hash_entry **sym_hashes, **sym_hashes_end;
557 const Elf_Internal_Rela *rel;
558 const Elf_Internal_Rela *rel_end;
560 if (info->relocateable)
561 return true;
563 symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
564 sym_hashes = elf_sym_hashes (abfd);
565 sym_hashes_end =
566 sym_hashes + symtab_hdr->sh_size / sizeof (Elf32_External_Sym);
567 if (!elf_bad_symtab (abfd))
568 sym_hashes_end -= symtab_hdr->sh_info;
570 rel_end = relocs + sec->reloc_count;
571 for (rel = relocs; rel < rel_end; rel++)
573 struct elf_link_hash_entry *h;
574 unsigned long r_symndx;
576 r_symndx = ELF32_R_SYM (rel->r_info);
577 if (r_symndx < symtab_hdr->sh_info)
578 h = NULL;
579 else
580 h = sym_hashes[r_symndx - symtab_hdr->sh_info];
582 switch (ELF32_R_TYPE (rel->r_info))
584 /* This relocation describes the C++ object vtable hierarchy.
585 Reconstruct it for later use during GC. */
586 case R_OPENRISC_GNU_VTINHERIT:
587 if (!_bfd_elf32_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
588 return false;
589 break;
591 /* This relocation describes which C++ vtable entries are actually
592 used. Record for later use during GC. */
593 case R_OPENRISC_GNU_VTENTRY:
594 if (!_bfd_elf32_gc_record_vtentry (abfd, sec, h, rel->r_addend))
595 return false;
596 break;
600 return true;
603 /* Set the right machine number. */
605 static boolean
606 openrisc_elf_object_p (abfd)
607 bfd *abfd;
609 switch (elf_elfheader (abfd)->e_flags & 0xf)
611 default:
612 (void) bfd_default_set_arch_mach (abfd, bfd_arch_openrisc, 0);
613 break;
615 return true;
618 /* Store the machine number in the flags field. */
620 static void
621 openrisc_elf_final_write_processing (abfd, linker)
622 bfd *abfd;
623 boolean linker ATTRIBUTE_UNUSED;
625 unsigned long val;
627 switch (bfd_get_mach (abfd))
629 default:
630 val = 0;
631 break;
634 elf_elfheader (abfd)->e_flags &= ~0xf;
635 elf_elfheader (abfd)->e_flags |= val;
639 #define ELF_ARCH bfd_arch_openrisc
640 #define ELF_MACHINE_CODE EM_OPENRISC
641 #define ELF_MACHINE_ALT1 EM_OPENRISC_OLD
642 #define ELF_MAXPAGESIZE 0x1000
644 #define TARGET_BIG_SYM bfd_elf32_openrisc_vec
645 #define TARGET_BIG_NAME "elf32-openrisc"
647 #define elf_info_to_howto_rel NULL
648 #define elf_info_to_howto openrisc_info_to_howto_rela
649 #define elf_backend_relocate_section openrisc_elf_relocate_section
650 #define elf_backend_gc_mark_hook openrisc_elf_gc_mark_hook
651 #define elf_backend_gc_sweep_hook openrisc_elf_gc_sweep_hook
652 #define elf_backend_check_relocs openrisc_elf_check_relocs
654 #define elf_backend_can_gc_sections 1
656 #define bfd_elf32_bfd_reloc_type_lookup openrisc_reloc_type_lookup
658 #define elf_backend_object_p openrisc_elf_object_p
659 #define elf_backend_final_write_processing openrisc_elf_final_write_processing
661 #include "elf32-target.h"