This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Commit: RL78: Add support for G13 and G14 flags in ELF header
- From: Nick Clifton <nickc at redhat dot com>
- To: binutils at sourceware dot org
- Date: Thu, 19 Mar 2015 15:37:14 +0000
- Subject: Commit: RL78: Add support for G13 and G14 flags in ELF header
- Authentication-results: sourceware.org; auth=none
Hi Guys,
I am checking in the patch below to add support for encoding the G13
and G14 core types for the RL78 into the ELF header. The patch adds
a couple of new options to GAS for the RL78 (-mg13 and -mg14) which
can be used to set the flags. It also updates readelf and objdump to
display the flags and the linker to issue error messages if the user
attempts to link together objects built for different cores.
Cheers
Nick
include/elf/ChangeLog
2015-03-19 Nick Clifton <nickc@redhat.com>
* 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.
gas/ChangeLog
2015-03-19 Nick Clifton <nickc@redhat.com>
* 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/ChangeLog
2015-03-19 Nick Clifton <nickc@redhat.com>
* 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.
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
diff --git a/binutils/readelf.c b/binutils/readelf.c
index 20cfc47..adf2a91 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -3256,8 +3256,13 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
break;
case EM_RL78:
- if (e_flags & E_FLAG_RL78_G10)
- strcat (buf, ", G10");
+ switch (e_flags & E_FLAG_RL78_CPU_MASK)
+ {
+ case E_FLAG_RL78_ANY_CPU: break;
+ case E_FLAG_RL78_G10: strcat (buf, ", G10"); break;
+ case E_FLAG_RL78_G13: strcat (buf, ", G13"); break;
+ case E_FLAG_RL78_G14: strcat (buf, ", G14"); break;
+ }
if (e_flags & E_FLAG_RL78_64BIT_DOUBLES)
strcat (buf, ", 64-bit doubles");
break;
diff --git a/gas/config/tc-rl78.c b/gas/config/tc-rl78.c
index abc05a0..337b819 100644
--- a/gas/config/tc-rl78.c
+++ b/gas/config/tc-rl78.c
@@ -281,6 +281,8 @@ enum options
{
OPTION_RELAX = OPTION_MD_BASE,
OPTION_G10,
+ OPTION_G13,
+ OPTION_G14,
OPTION_32BIT_DOUBLES,
OPTION_64BIT_DOUBLES,
};
@@ -293,6 +295,9 @@ struct option md_longopts[] =
{
{"relax", no_argument, NULL, OPTION_RELAX},
{"mg10", no_argument, NULL, OPTION_G10},
+ {"mg13", no_argument, NULL, OPTION_G13},
+ {"mg14", no_argument, NULL, OPTION_G14},
+ {"mrl78", no_argument, NULL, OPTION_G14},
{"m32bit-doubles", no_argument, NULL, OPTION_32BIT_DOUBLES},
{"m64bit-doubles", no_argument, NULL, OPTION_64BIT_DOUBLES},
{NULL, no_argument, NULL, 0}
@@ -309,9 +314,20 @@ md_parse_option (int c, char * arg ATTRIBUTE_UNUSED)
return 1;
case OPTION_G10:
+ elf_flags &= ~ E_FLAG_RL78_CPU_MASK;
elf_flags |= E_FLAG_RL78_G10;
return 1;
+ case OPTION_G13:
+ elf_flags &= ~ E_FLAG_RL78_CPU_MASK;
+ elf_flags |= E_FLAG_RL78_G13;
+ return 1;
+
+ case OPTION_G14:
+ elf_flags &= ~ E_FLAG_RL78_CPU_MASK;
+ elf_flags |= E_FLAG_RL78_G14;
+ return 1;
+
case OPTION_32BIT_DOUBLES:
elf_flags &= ~ E_FLAG_RL78_64BIT_DOUBLES;
return 1;
@@ -328,6 +344,9 @@ md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
{
fprintf (stream, _(" RL78 specific command line options:\n"));
fprintf (stream, _(" --mg10 Enable support for G10 variant\n"));
+ fprintf (stream, _(" --mg13 Selects the G13 core.\n"));
+ fprintf (stream, _(" --mg14 Selects the G14 core [default]\n"));
+ fprintf (stream, _(" --mrl78 Alias for --mg14\n"));
fprintf (stream, _(" --m32bit-doubles [default]\n"));
fprintf (stream, _(" --m64bit-doubles\n"));
}
diff --git a/gas/doc/c-rl78.texi b/gas/doc/c-rl78.texi
index fee16f1..5cb568f 100644
--- a/gas/doc/c-rl78.texi
+++ b/gas/doc/c-rl78.texi
@@ -32,6 +32,15 @@ Enable support for link-time relaxation.
Mark the generated binary as targeting the G10 variant of the RL78
architecture.
+@item mg13
+Mark the generated binary as targeting the G13 variant of the RL78
+architecture.
+
+@item mg14
+@itemx mrl78
+Mark the generated binary as targeting the G14 variant of the RL78
+architecture. This is the default.
+
@item m32bit-doubles
Mark the generated binary as one that uses 32-bits to hold the
@code{double} floating point type. This is the default.
diff --git a/include/elf/rl78.h b/include/elf/rl78.h
index e7df0d7..b5236d9 100644
--- a/include/elf/rl78.h
+++ b/include/elf/rl78.h
@@ -106,7 +106,11 @@ END_RELOC_NUMBERS (R_RL78_max)
/* Values for the e_flags field in the ELF header. */
#define E_FLAG_RL78_64BIT_DOUBLES (1 << 0)
#define E_FLAG_RL78_DSP (1 << 1) /* Defined in the RL78 CPU Object file specification, but not explained. */
-#define E_FLAG_RL78_G10 (1 << 2) /* CPU is missing register banks 1-3, so uses different ABI. */
+#define E_FLAG_RL78_CPU_MASK 0x0c
+#define E_FLAG_RL78_ANY_CPU 0x00 /* CPU not specified. Assume no CPU specific code usage. */
+#define E_FLAG_RL78_G10 0x04 /* CPU is missing register banks 1-3, so uses different ABI. */
+#define E_FLAG_RL78_G13 0x08 /* CPU uses a peripheral for multiply/divide. */
+#define E_FLAG_RL78_G14 0x0c /* CPU has multiply/divide instructions. */
/* These define the addend field of R_RL78_RH_RELAX relocations. */
#define RL78_RELAXA_MASK 0x000000f0 /* Mask for relax types */