1 /* MeP-specific support for 32-bit ELF.
2 Copyright (C) 2001-2019 Free Software Foundation, Inc.
4 This file is part of BFD, the Binary File Descriptor library.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
19 MA 02110-1301, USA. */
26 #include "libiberty.h"
28 /* Forward declarations. */
30 /* Private relocation functions. */
32 #define MEPREL(type, size, bits, right, left, pcrel, overflow, mask) \
33 HOWTO (type, right, size, bits, pcrel, left, overflow, bfd_elf_generic_reloc, #type, FALSE, 0, mask, 0)
35 #define N complain_overflow_dont
36 #define S complain_overflow_signed
37 #define U complain_overflow_unsigned
39 static reloc_howto_type mep_elf_howto_table [] =
41 /* type, size, bits, leftshift, rightshift, pcrel, OD/OS/OU, mask. */
42 MEPREL (R_MEP_NONE, 3, 0, 0, 0, 0, N, 0),
43 MEPREL (R_RELC, 0, 0, 0, 0, 0, N, 0),
45 /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h. */
46 MEPREL (R_MEP_8, 0, 8, 0, 0, 0, U, 0xff),
47 MEPREL (R_MEP_16, 1, 16, 0, 0, 0, U, 0xffff),
48 MEPREL (R_MEP_32, 2, 32, 0, 0, 0, U, 0xffffffff),
49 MEPREL (R_MEP_PCREL8A2, 1, 8, 1, 1, 1, S, 0x00fe),
50 MEPREL (R_MEP_PCREL12A2,1, 12, 1, 1, 1, S, 0x0ffe),
51 MEPREL (R_MEP_PCREL17A2,2, 17, 0, 1, 1, S, 0x0000ffff),
52 MEPREL (R_MEP_PCREL24A2,2, 24, 0, 1, 1, S, 0x07f0ffff),
53 MEPREL (R_MEP_PCABS24A2,2, 24, 0, 1, 0, U, 0x07f0ffff),
54 MEPREL (R_MEP_LOW16, 2, 16, 0, 0, 0, N, 0x0000ffff),
55 MEPREL (R_MEP_HI16U, 2, 32, 0,16, 0, N, 0x0000ffff),
56 MEPREL (R_MEP_HI16S, 2, 32, 0,16, 0, N, 0x0000ffff),
57 MEPREL (R_MEP_GPREL, 2, 16, 0, 0, 0, S, 0x0000ffff),
58 MEPREL (R_MEP_TPREL, 2, 16, 0, 0, 0, S, 0x0000ffff),
59 MEPREL (R_MEP_TPREL7, 1, 7, 0, 0, 0, U, 0x007f),
60 MEPREL (R_MEP_TPREL7A2, 1, 7, 1, 1, 0, U, 0x007e),
61 MEPREL (R_MEP_TPREL7A4, 1, 7, 2, 2, 0, U, 0x007c),
62 MEPREL (R_MEP_UIMM24, 2, 24, 0, 0, 0, U, 0x00ffffff),
63 MEPREL (R_MEP_ADDR24A4, 2, 24, 0, 2, 0, U, 0x00fcffff),
64 MEPREL (R_MEP_GNU_VTINHERIT,1, 0,16,32, 0, N, 0x0000),
65 MEPREL (R_MEP_GNU_VTENTRY,1, 0,16,32, 0, N, 0x0000),
69 #define VALID_MEP_RELOC(N) ((N) >= 0 \
70 && (N) < ARRAY_SIZE (mep_elf_howto_table)
77 #define BFD_RELOC_MEP_NONE BFD_RELOC_NONE
78 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
79 #define MAP(n) case BFD_RELOC_MEP_##n: type = R_MEP_##n; break
81 #define MAP(n) case BFD_RELOC_MEP_/**/n: type = R_MEP_/**/n; break
84 static reloc_howto_type *
86 (bfd * abfd ATTRIBUTE_UNUSED,
87 bfd_reloc_code_real_type code)
89 unsigned int type = 0;
103 case BFD_RELOC_VTABLE_ENTRY:
104 type = R_MEP_GNU_VTENTRY;
106 case BFD_RELOC_VTABLE_INHERIT:
107 type = R_MEP_GNU_VTINHERIT;
114 /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h. */
138 /* Pacify gcc -Wall. */
139 _bfd_error_handler (_("mep: no reloc for code %d"), code);
143 if (mep_elf_howto_table[type].type != type)
145 /* xgettext:c-format */
146 _bfd_error_handler (_("MeP: howto %d has type %d"),
147 type, mep_elf_howto_table[type].type);
151 return mep_elf_howto_table + type;
156 static reloc_howto_type *
157 mep_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
162 i < sizeof (mep_elf_howto_table) / sizeof (mep_elf_howto_table[0]);
164 if (mep_elf_howto_table[i].name != NULL
165 && strcasecmp (mep_elf_howto_table[i].name, r_name) == 0)
166 return &mep_elf_howto_table[i];
171 /* Perform a single relocation. */
173 static struct bfd_link_info *mep_info;
174 static int warn_tp = 0, warn_sda = 0;
183 struct bfd_link_hash_entry *h;
188 h = bfd_link_hash_lookup (mep_info->hash, name, FALSE, FALSE, TRUE);
189 if (h == 0 || h->type != bfd_link_hash_defined)
194 *cache = (h->u.def.value
195 + h->u.def.section->output_section->vma
196 + h->u.def.section->output_offset);
201 mep_tpoff_base (bfd_vma ofs)
203 static bfd_vma cache = 0;
204 return mep_lookup_global ("__tpbase", ofs, &cache, &warn_tp);
208 mep_sdaoff_base (bfd_vma ofs)
210 static bfd_vma cache = 0;
211 return mep_lookup_global ("__sdabase", ofs, &cache, &warn_sda);
214 static bfd_reloc_status_type
215 mep_final_link_relocate
216 (reloc_howto_type * howto,
218 asection * input_section,
220 Elf_Internal_Rela * rel,
227 bfd_reloc_status_type r = bfd_reloc_ok;
230 if (bfd_big_endian (input_bfd))
241 pc = (input_section->output_section->vma
242 + input_section->output_offset
245 s = relocation + rel->r_addend;
247 byte = (unsigned char *)contents + rel->r_offset;
249 if (howto->type == R_MEP_PCREL24A2
253 /* This is an unreachable branch to an undefined weak function.
254 Silently ignore it, since the opcode can't do that but should
255 never be executed anyway. */
259 if (howto->pc_relative)
262 u = (unsigned long) s;
267 /* This section generated from bfd/mep-relocs.pl from include/elf/mep.h. */
268 case R_MEP_8: /* 76543210 */
269 if (u > 255) r = bfd_reloc_overflow;
270 byte[0] = (u & 0xff);
272 case R_MEP_16: /* fedcba9876543210 */
273 if (u > 65535) r = bfd_reloc_overflow;
274 byte[0^e2] = ((u >> 8) & 0xff);
275 byte[1^e2] = (u & 0xff);
277 case R_MEP_32: /* vutsrqponmlkjihgfedcba9876543210 */
278 byte[0^e4] = ((u >> 24) & 0xff);
279 byte[1^e4] = ((u >> 16) & 0xff);
280 byte[2^e4] = ((u >> 8) & 0xff);
281 byte[3^e4] = (u & 0xff);
283 case R_MEP_PCREL8A2: /* --------7654321- */
284 if (-128 > s || s > 127) r = bfd_reloc_overflow;
285 byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe);
287 case R_MEP_PCREL12A2: /* ----ba987654321- */
288 if (-2048 > s || s > 2047) r = bfd_reloc_overflow;
289 byte[0^e2] = (byte[0^e2] & 0xf0) | ((s >> 8) & 0x0f);
290 byte[1^e2] = (byte[1^e2] & 0x01) | (s & 0xfe);
292 case R_MEP_PCREL17A2: /* ----------------gfedcba987654321 */
293 if (-65536 > s || s > 65535) r = bfd_reloc_overflow;
294 byte[2^e2] = ((s >> 9) & 0xff);
295 byte[3^e2] = ((s >> 1) & 0xff);
297 case R_MEP_PCREL24A2: /* -----7654321----nmlkjihgfedcba98 */
298 if (-8388608 > s || s > 8388607) r = bfd_reloc_overflow;
299 byte[0^e2] = (byte[0^e2] & 0xf8) | ((s >> 5) & 0x07);
300 byte[1^e2] = (byte[1^e2] & 0x0f) | ((s << 3) & 0xf0);
301 byte[2^e2] = ((s >> 16) & 0xff);
302 byte[3^e2] = ((s >> 8) & 0xff);
304 case R_MEP_PCABS24A2: /* -----7654321----nmlkjihgfedcba98 */
305 if (u > 16777215) r = bfd_reloc_overflow;
306 byte[0^e2] = (byte[0^e2] & 0xf8) | ((u >> 5) & 0x07);
307 byte[1^e2] = (byte[1^e2] & 0x0f) | ((u << 3) & 0xf0);
308 byte[2^e2] = ((u >> 16) & 0xff);
309 byte[3^e2] = ((u >> 8) & 0xff);
311 case R_MEP_LOW16: /* ----------------fedcba9876543210 */
312 byte[2^e2] = ((u >> 8) & 0xff);
313 byte[3^e2] = (u & 0xff);
315 case R_MEP_HI16U: /* ----------------vutsrqponmlkjihg */
316 byte[2^e2] = ((u >> 24) & 0xff);
317 byte[3^e2] = ((u >> 16) & 0xff);
319 case R_MEP_HI16S: /* ----------------vutsrqponmlkjihg */
322 byte[2^e2] = ((s >> 24) & 0xff);
323 byte[3^e2] = ((s >> 16) & 0xff);
325 case R_MEP_GPREL: /* ----------------fedcba9876543210 */
326 s -= mep_sdaoff_base(rel->r_offset);
327 if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
328 byte[2^e2] = ((s >> 8) & 0xff);
329 byte[3^e2] = (s & 0xff);
331 case R_MEP_TPREL: /* ----------------fedcba9876543210 */
332 s -= mep_tpoff_base(rel->r_offset);
333 if (-32768 > s || s > 32767) r = bfd_reloc_overflow;
334 byte[2^e2] = ((s >> 8) & 0xff);
335 byte[3^e2] = (s & 0xff);
337 case R_MEP_TPREL7: /* ---------6543210 */
338 u -= mep_tpoff_base(rel->r_offset);
339 if (u > 127) r = bfd_reloc_overflow;
340 byte[1^e2] = (byte[1^e2] & 0x80) | (u & 0x7f);
342 case R_MEP_TPREL7A2: /* ---------654321- */
343 u -= mep_tpoff_base(rel->r_offset);
344 if (u > 127) r = bfd_reloc_overflow;
345 byte[1^e2] = (byte[1^e2] & 0x81) | (u & 0x7e);
347 case R_MEP_TPREL7A4: /* ---------65432-- */
348 u -= mep_tpoff_base(rel->r_offset);
349 if (u > 127) r = bfd_reloc_overflow;
350 byte[1^e2] = (byte[1^e2] & 0x83) | (u & 0x7c);
352 case R_MEP_UIMM24: /* --------76543210nmlkjihgfedcba98 */
353 if (u > 16777215) r = bfd_reloc_overflow;
354 byte[1^e2] = (u & 0xff);
355 byte[2^e2] = ((u >> 16) & 0xff);
356 byte[3^e2] = ((u >> 8) & 0xff);
358 case R_MEP_ADDR24A4: /* --------765432--nmlkjihgfedcba98 */
359 if (u > 16777215) r = bfd_reloc_overflow;
360 byte[1^e2] = (byte[1^e2] & 0x03) | (u & 0xfc);
361 byte[2^e2] = ((u >> 16) & 0xff);
362 byte[3^e2] = ((u >> 8) & 0xff);
364 case R_MEP_GNU_VTINHERIT: /* ---------------- */
366 case R_MEP_GNU_VTENTRY: /* ---------------- */
376 /* Set the howto pointer for a MEP ELF reloc. */
379 mep_info_to_howto_rela (bfd * abfd,
381 Elf_Internal_Rela * dst)
385 r_type = ELF32_R_TYPE (dst->r_info);
386 if (r_type >= R_MEP_max)
388 /* xgettext:c-format */
389 _bfd_error_handler (_("%pB: unsupported relocation type %#x"),
391 bfd_set_error (bfd_error_bad_value);
394 cache_ptr->howto = & mep_elf_howto_table [r_type];
398 /* Relocate a MEP ELF section.
399 There is some attempt to make this function usable for many architectures,
400 both USE_REL and USE_RELA ['twould be nice if such a critter existed],
401 if only to serve as a learning tool.
403 The RELOCATE_SECTION function is called by the new ELF backend linker
404 to handle the relocations for a section.
406 The relocs are always passed as Rela structures; if the section
407 actually uses Rel structures, the r_addend field will always be
410 This function is responsible for adjusting the section contents as
411 necessary, and (if using Rela relocs and generating a relocatable
412 output file) adjusting the reloc addend as necessary.
414 This function does not have to worry about setting the reloc
415 address or the reloc symbol index.
417 LOCAL_SYMS is a pointer to the swapped in local symbols.
419 LOCAL_SECTIONS is an array giving the section in the input file
420 corresponding to the st_shndx field of each local symbol.
422 The global hash table entry for the global symbols can be found
423 via elf_sym_hashes (input_bfd).
425 When generating relocatable output, this function must handle
426 STB_LOCAL/STT_SECTION symbols specially. The output symbol is
427 going to be the section symbol corresponding to the output
428 section, which means that the addend must be adjusted
432 mep_elf_relocate_section
433 (bfd * output_bfd ATTRIBUTE_UNUSED,
434 struct bfd_link_info * info,
436 asection * input_section,
438 Elf_Internal_Rela * relocs,
439 Elf_Internal_Sym * local_syms,
440 asection ** local_sections)
442 Elf_Internal_Shdr * symtab_hdr;
443 struct elf_link_hash_entry ** sym_hashes;
444 Elf_Internal_Rela * rel;
445 Elf_Internal_Rela * relend;
447 symtab_hdr = & elf_tdata (input_bfd)->symtab_hdr;
448 sym_hashes = elf_sym_hashes (input_bfd);
449 relend = relocs + input_section->reloc_count;
453 for (rel = relocs; rel < relend; rel ++)
455 reloc_howto_type * howto;
456 unsigned long r_symndx;
457 Elf_Internal_Sym * sym;
459 struct elf_link_hash_entry * h;
461 bfd_reloc_status_type r;
462 const char * name = NULL;
465 r_type = ELF32_R_TYPE (rel->r_info);
466 r_symndx = ELF32_R_SYM (rel->r_info);
467 howto = mep_elf_howto_table + ELF32_R_TYPE (rel->r_info);
472 if (r_symndx < symtab_hdr->sh_info)
474 sym = local_syms + r_symndx;
475 sec = local_sections [r_symndx];
476 relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
478 name = bfd_elf_string_from_elf_section
479 (input_bfd, symtab_hdr->sh_link, sym->st_name);
480 name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
484 bfd_boolean warned, unresolved_reloc, ignored;
486 RELOC_FOR_GLOBAL_SYMBOL(info, input_bfd, input_section, rel,
487 r_symndx, symtab_hdr, sym_hashes,
489 unresolved_reloc, warned, ignored);
491 name = h->root.root.string;
494 if (sec != NULL && discarded_section (sec))
495 RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
496 rel, 1, relend, howto, 0, contents);
498 if (bfd_link_relocatable (info))
501 if (r_type == R_RELC)
502 r = bfd_elf_perform_complex_relocation (input_bfd, input_section,
503 contents, rel, relocation);
505 r = mep_final_link_relocate (howto, input_bfd, input_section,
506 contents, rel, relocation);
508 if (r != bfd_reloc_ok)
510 const char * msg = (const char *) NULL;
514 case bfd_reloc_overflow:
515 (*info->callbacks->reloc_overflow)
516 (info, (h ? &h->root : NULL), name, howto->name, (bfd_vma) 0,
517 input_bfd, input_section, rel->r_offset);
520 case bfd_reloc_undefined:
521 (*info->callbacks->undefined_symbol)
522 (info, name, input_bfd, input_section, rel->r_offset, TRUE);
525 case bfd_reloc_outofrange:
526 msg = _("internal error: out of range error");
529 case bfd_reloc_notsupported:
530 msg = _("internal error: unsupported relocation error");
533 case bfd_reloc_dangerous:
534 msg = _("internal error: dangerous relocation");
538 msg = _("internal error: unknown error");
543 (*info->callbacks->warning) (info, msg, name, input_bfd,
544 input_section, rel->r_offset);
549 info->callbacks->undefined_symbol
550 (info, "__tpbase", input_bfd, input_section, warn_tp-1, TRUE);
552 info->callbacks->undefined_symbol
553 (info, "__sdabase", input_bfd, input_section, warn_sda-1, TRUE);
554 if (warn_sda || warn_tp)
560 /* Function to set the ELF flag bits. */
563 mep_elf_set_private_flags (bfd * abfd,
566 elf_elfheader (abfd)->e_flags = flags;
567 elf_flags_init (abfd) = TRUE;
571 /* Merge backend specific data from an object file to the output
572 object file when linking. */
575 mep_elf_merge_private_bfd_data (bfd *ibfd, struct bfd_link_info *info)
577 bfd *obfd = info->output_bfd;
578 static bfd *last_ibfd = 0;
579 flagword old_flags, new_flags;
580 flagword old_partial, new_partial;
582 /* Check if we have the same endianness. */
583 if (!_bfd_generic_verify_endian_match (ibfd, info))
586 new_flags = elf_elfheader (ibfd)->e_flags;
587 old_flags = elf_elfheader (obfd)->e_flags;
590 _bfd_error_handler ("%pB: old_flags = 0x%.8x, new_flags = 0x%.8x, init = %s",
591 ibfd, old_flags, new_flags, elf_flags_init (obfd) ? "yes" : "no");
594 /* First call, no flags set. */
595 if (!elf_flags_init (obfd))
597 elf_flags_init (obfd) = TRUE;
598 old_flags = new_flags;
600 else if ((new_flags | old_flags) & EF_MEP_LIBRARY)
602 /* Non-library flags trump library flags. The choice doesn't really
603 matter if both OLD_FLAGS and NEW_FLAGS have EF_MEP_LIBRARY set. */
604 if (old_flags & EF_MEP_LIBRARY)
605 old_flags = new_flags;
609 /* Make sure they're for the same mach. Allow upgrade from the "mep"
611 new_partial = (new_flags & EF_MEP_CPU_MASK);
612 old_partial = (old_flags & EF_MEP_CPU_MASK);
613 if (new_partial == old_partial)
615 else if (new_partial == EF_MEP_CPU_MEP)
617 else if (old_partial == EF_MEP_CPU_MEP)
618 old_flags = (old_flags & ~EF_MEP_CPU_MASK) | new_partial;
621 /* xgettext:c-format */
622 _bfd_error_handler (_("%pB and %pB are for different cores"),
624 bfd_set_error (bfd_error_invalid_target);
628 /* Make sure they're for the same me_module. Allow basic config to
629 mix with any other. */
630 new_partial = (new_flags & EF_MEP_INDEX_MASK);
631 old_partial = (old_flags & EF_MEP_INDEX_MASK);
632 if (new_partial == old_partial)
634 else if (new_partial == 0)
636 else if (old_partial == 0)
637 old_flags = (old_flags & ~EF_MEP_INDEX_MASK) | new_partial;
640 /* xgettext:c-format */
641 _bfd_error_handler (_("%pB and %pB are for different configurations"),
643 bfd_set_error (bfd_error_invalid_target);
648 elf_elfheader (obfd)->e_flags = old_flags;
653 /* This will be edited by the MeP configration tool. */
654 static const char * config_names[] =
657 /* start-mepcfgtool */
662 static const char * core_names[] =
664 "MeP", "MeP-c2", "MeP-c3", "MeP-h1"
668 mep_elf_print_private_bfd_data (bfd * abfd, void * ptr)
670 FILE * file = (FILE *) ptr;
671 flagword flags, partial_flags;
673 BFD_ASSERT (abfd != NULL && ptr != NULL);
675 /* Print normal ELF private data. */
676 _bfd_elf_print_private_bfd_data (abfd, ptr);
678 flags = elf_elfheader (abfd)->e_flags;
679 fprintf (file, _("private flags = 0x%lx"), (unsigned long) flags);
681 partial_flags = (flags & EF_MEP_CPU_MASK) >> 24;
682 if (partial_flags < ARRAY_SIZE (core_names))
683 fprintf (file, " core: %s", core_names[(long)partial_flags]);
685 partial_flags = flags & EF_MEP_INDEX_MASK;
686 if (partial_flags < ARRAY_SIZE (config_names))
687 fprintf (file, " me_module: %s", config_names[(long)partial_flags]);
694 /* Return the machine subcode from the ELF e_flags header. */
697 elf32_mep_machine (bfd * abfd)
699 switch (elf_elfheader (abfd)->e_flags & EF_MEP_CPU_MASK)
702 case EF_MEP_CPU_C2: return bfd_mach_mep;
703 case EF_MEP_CPU_C3: return bfd_mach_mep;
704 case EF_MEP_CPU_C4: return bfd_mach_mep;
705 case EF_MEP_CPU_C5: return bfd_mach_mep_c5;
706 case EF_MEP_CPU_H1: return bfd_mach_mep_h1;
713 mep_elf_object_p (bfd * abfd)
715 bfd_default_set_arch_mach (abfd, bfd_arch_mep, elf32_mep_machine (abfd));
720 mep_elf_section_flags (flagword * flags, const Elf_Internal_Shdr * hdr)
722 if (hdr->sh_flags & SHF_MEP_VLIW)
723 * flags |= SEC_MEP_VLIW;
728 mep_elf_fake_sections (bfd * abfd ATTRIBUTE_UNUSED,
729 Elf_Internal_Shdr * hdr,
732 if (sec->flags & SEC_MEP_VLIW)
733 hdr->sh_flags |= SHF_MEP_VLIW;
738 #define ELF_ARCH bfd_arch_mep
739 #define ELF_MACHINE_CODE EM_CYGNUS_MEP
740 #define ELF_MAXPAGESIZE 0x1000
742 #define TARGET_BIG_SYM mep_elf32_vec
743 #define TARGET_BIG_NAME "elf32-mep"
745 #define TARGET_LITTLE_SYM mep_elf32_le_vec
746 #define TARGET_LITTLE_NAME "elf32-mep-little"
748 #define elf_info_to_howto_rel NULL
749 #define elf_info_to_howto mep_info_to_howto_rela
750 #define elf_backend_relocate_section mep_elf_relocate_section
751 #define elf_backend_object_p mep_elf_object_p
752 #define elf_backend_section_flags mep_elf_section_flags
753 #define elf_backend_fake_sections mep_elf_fake_sections
755 #define bfd_elf32_bfd_reloc_type_lookup mep_reloc_type_lookup
756 #define bfd_elf32_bfd_reloc_name_lookup mep_reloc_name_lookup
757 #define bfd_elf32_bfd_set_private_flags mep_elf_set_private_flags
758 #define bfd_elf32_bfd_merge_private_bfd_data mep_elf_merge_private_bfd_data
759 #define bfd_elf32_bfd_print_private_bfd_data mep_elf_print_private_bfd_data
761 #define elf_backend_rela_normal 1
763 #include "elf32-target.h"