From 1740ba0cec44bdfe9cba586892a5953a4c602228 Mon Sep 17 00:00:00 2001 From: Nick Clifton Date: Thu, 19 Mar 2015 15:37:43 +0000 Subject: Add support for G13 and G14 flag bits in RL78 ELF binaries. inc * rl78.h (E_FLAG_RL78_G10): Redefine. (E_FLAG_RL78_CPU_MASK, E_FLAG_RL78_ANY_CPU, E_FLAG_RL78_G13 E_FLAG_RL78_G14): New flags. bin * readelf.c (get_machine_flags): Decode RL78's G13 and G14 flags. gas * config/tc-rl78.c (enum options): Add G13 and G14. (md_longopts): Add -mg13 and -mg14. (md_parse_option): Handle -mg13 and -mg14. (md_show_usage): List -mg13 and -mg14. * doc/c-rl78.texi: Add description of -mg13 and -mg14 options. bfd * elf32-rl78.c (rl78_cpu_name): New function. Prints the name of the RL78 core based upon the flags. (rl78_elf_merge_private_bfd_data): Handle merging of G13 and G14 flags. (rl78_elf_print_private_bfd_data): Use rl78_cpu_name. (elf32_rl78_machine): Always return bfd_mach_rl78. --- bfd/ChangeLog | 9 ++++++ bfd/elf32-rl78.c | 92 ++++++++++++++++++++++++++++++++++++++------------------ 2 files changed, 72 insertions(+), 29 deletions(-) (limited to 'bfd') diff --git a/bfd/ChangeLog b/bfd/ChangeLog index e158591..f901f5a 100644 --- a/bfd/ChangeLog +++ b/bfd/ChangeLog @@ -1,5 +1,14 @@ 2015-03-19 Nick Clifton + * elf32-rl78.c (rl78_cpu_name): New function. Prints the name of + the RL78 core based upon the flags. + (rl78_elf_merge_private_bfd_data): Handle merging of G13 and G14 + flags. + (rl78_elf_print_private_bfd_data): Use rl78_cpu_name. + (elf32_rl78_machine): Always return bfd_mach_rl78. + +2015-03-19 Nick Clifton + PR 18078 * compress.c (bfd_compress_section_contents): Do not define this function if it is not used. diff --git a/bfd/elf32-rl78.c b/bfd/elf32-rl78.c index acd82b9..70b49aa 100644 --- a/bfd/elf32-rl78.c +++ b/bfd/elf32-rl78.c @@ -1018,6 +1018,18 @@ bfd_elf32_rl78_set_target_flags (bfd_boolean user_no_warn_mismatch) no_warn_mismatch = user_no_warn_mismatch; } +static const char * +rl78_cpu_name (flagword flags) +{ + switch (flags & E_FLAG_RL78_CPU_MASK) + { + default: return ""; + case E_FLAG_RL78_G10: return "G10"; + case E_FLAG_RL78_G13: return "G13"; + case E_FLAG_RL78_G14: return "G14"; + } +} + /* Merge backend specific data from an object file to the output object file when linking. */ @@ -1041,17 +1053,44 @@ rl78_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd) { flagword changed_flags = old_flags ^ new_flags; - if (changed_flags & E_FLAG_RL78_G10) + if (changed_flags & E_FLAG_RL78_CPU_MASK) { - (*_bfd_error_handler) - (_("RL78/G10 ABI conflict: cannot link G10 and non-G10 objects together")); + flagword out_cpu = old_flags & E_FLAG_RL78_CPU_MASK; + flagword in_cpu = new_flags & E_FLAG_RL78_CPU_MASK; - if (old_flags & E_FLAG_RL78_G10) - (*_bfd_error_handler) (_("- %s is G10, %s is not"), - bfd_get_filename (obfd), bfd_get_filename (ibfd)); + if (in_cpu == E_FLAG_RL78_ANY_CPU || in_cpu == out_cpu) + /* It does not matter what new_cpu may have. */; + else if (out_cpu == E_FLAG_RL78_ANY_CPU) + { + if (in_cpu == E_FLAG_RL78_G10) + { + /* G10 files can only be linked with other G10 files. + If the output is set to "any" this means that it is + a G14 file that does not use hardware multiply/divide, + but that is still incompatible with the G10 ABI. */ + error = TRUE; + + (*_bfd_error_handler) + (_("RL78 ABI conflict: G10 file %s cannot be linked with %s file %s"), + bfd_get_filename (ibfd), + rl78_cpu_name (out_cpu), bfd_get_filename (obfd)); + } + else + { + old_flags &= ~ E_FLAG_RL78_CPU_MASK; + old_flags |= in_cpu; + elf_elfheader (obfd)->e_flags = old_flags; + } + } else - (*_bfd_error_handler) (_("- %s is G10, %s is not"), - bfd_get_filename (ibfd), bfd_get_filename (obfd)); + { + error = TRUE; + + (*_bfd_error_handler) + (_("RL78 ABI conflict: cannot link %s file %s with %s file %s"), + rl78_cpu_name (in_cpu), bfd_get_filename (ibfd), + rl78_cpu_name (out_cpu), bfd_get_filename (obfd)); + } } if (changed_flags & E_FLAG_RL78_64BIT_DOUBLES) @@ -1065,6 +1104,7 @@ rl78_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd) else (*_bfd_error_handler) (_("- %s is 64-bit, %s is not"), bfd_get_filename (ibfd), bfd_get_filename (obfd)); + error = TRUE; } } @@ -1085,8 +1125,8 @@ rl78_elf_print_private_bfd_data (bfd * abfd, void * ptr) flags = elf_elfheader (abfd)->e_flags; fprintf (file, _("private flags = 0x%lx:"), (long) flags); - if (flags & E_FLAG_RL78_G10) - fprintf (file, _(" [G10]")); + if (flags & E_FLAG_RL78_CPU_MASK) + fprintf (file, " [%s]", rl78_cpu_name (flags)); if (flags & E_FLAG_RL78_64BIT_DOUBLES) fprintf (file, _(" [64-bit doubles]")); @@ -1098,12 +1138,9 @@ rl78_elf_print_private_bfd_data (bfd * abfd, void * ptr) /* Return the MACH for an e_flags value. */ static int -elf32_rl78_machine (bfd * abfd) +elf32_rl78_machine (bfd * abfd ATTRIBUTE_UNUSED) { - if ((elf_elfheader (abfd)->e_flags & EF_RL78_CPU_MASK) == EF_RL78_CPU_RL78) - return bfd_mach_rl78; - - return 0; + return bfd_mach_rl78; } static bfd_boolean @@ -1240,7 +1277,7 @@ rl78_elf_finish_dynamic_sections (bfd *abfd ATTRIBUTE_UNUSED, this check if we're relaxing. Unfortunately, check_relocs is called before relaxation. */ - if (info->relax_trip > 0) + if (info->relax_trip > 0) return TRUE; if ((dynobj = elf_hash_table (info)->dynobj) != NULL @@ -1473,7 +1510,7 @@ rl78_elf_relax_plt_section (bfd *dynobj, static bfd_boolean elf32_rl78_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, int count, - Elf_Internal_Rela *alignment_rel, int force_snip) + Elf_Internal_Rela *alignment_rel, int force_snip) { Elf_Internal_Shdr * symtab_hdr; unsigned int sec_shndx; @@ -2129,8 +2166,8 @@ rl78_elf_relax_section nbytes /= alignment; nbytes *= alignment; - elf32_rl78_relax_delete_bytes (abfd, sec, erel->r_offset-nbytes, nbytes, next_alignment, - erel->r_offset == sec->size); + elf32_rl78_relax_delete_bytes (abfd, sec, erel->r_offset - nbytes, nbytes, + next_alignment, erel->r_offset == sec->size); *again = TRUE; continue; @@ -2163,16 +2200,17 @@ rl78_elf_relax_section pc = sec->output_section->vma + sec->output_offset + srel->r_offset; -#define GET_RELOC \ - BFD_ASSERT (nrelocs > 0); \ - symval = OFFSET_FOR_RELOC (srel, &srel, &scale); \ - pcrel = symval - pc + srel->r_addend; \ +#define GET_RELOC \ + BFD_ASSERT (nrelocs > 0); \ + symval = OFFSET_FOR_RELOC (srel, &srel, &scale); \ + pcrel = symval - pc + srel->r_addend; \ nrelocs --; #define SNIPNR(offset, nbytes) \ elf32_rl78_relax_delete_bytes (abfd, sec, (insn - contents) + offset, nbytes, next_alignment, 0); -#define SNIP(offset, nbytes, newtype) \ - SNIPNR (offset, nbytes); \ + +#define SNIP(offset, nbytes, newtype) \ + SNIPNR (offset, nbytes); \ srel->r_info = ELF32_R_INFO (ELF32_R_SYM (srel->r_info), newtype) /* The order of these bit tests must match the order that the @@ -2335,7 +2373,6 @@ rl78_elf_relax_section } break; } - } if ((irel->r_addend & RL78_RELAXA_MASK) == RL78_RELAXA_ADDR16 @@ -2402,13 +2439,10 @@ rl78_elf_relax_section insn[poff] = relax_addr16[idx].insn_for_saddr; SNIP (poff+2, 1, R_RL78_RH_SADDR); } - } } } - /*----------------------------------------------------------------------*/ - } return TRUE; -- cgit v1.1