This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
Commit: RX: Add support for alternate ABI
- From: Nick Clifton <nickc at redhat dot com>
- To: binutils at sourceware dot org
- Date: Fri, 09 Nov 2012 16:50:41 +0000
- Subject: Commit: RX: Add support for alternate ABI
Hi Guys,
I am checking in the patch below to fix a couple of problems with the
RX target and to add support for a GCC patch which corrects the
implementation of the ABI. The bugs fixed are:
* The EF_RX_CPU_RX flag conflicts with the E_FLAG_RX_... flags.
This needs to be sorted out (by Renesas choosing which values they
want to use), but in the meantime the patch means that RX binaries
from other compilers will still be recognised.
* The .init_array, .fini_array and .preinit_array sections need to
be marked as containing code so that their contents will not be
byte swapped when the linker is generating big-endian data code.
The GCC patch is to fix an ABI implementation bug. Since this means
producing binaries with a changed/fixed ABI, it is helpful to be able
to determine which ABI implementation a particular binary is using.
This patch adds that support to the assembler and linker.
Tested with no regressions on an rx-elf target.
Cheers
Nick
bfd/ChangeLog
2012-11-09 Nick Clifton <nickc@redhat.com>
* elf32-rx.c (describe_flags): New function. Returns a buffer
containing a description of the E_FLAG_RX_... values set.
(rx_elf_merge_private_bfd_data): Use it.
(rx_elf_print_private_bfd_data): Likewise.
(elf32_rx_machine): Skip EF_RX_CPU_RX check.
(elf32_rx_special_sections): Define.
(elf_backend_special_sections): Define.
binutils/ChangeLog
2012-11-09 Nick Clifton <nickc@redhat.com>
* readelf.c (get_machine_flags): Add support for E_FLAG_RX_ABI.
gas/ChangeLog
2012-11-09 Nick Clifton <nickc@redhat.com>
* config/obj-elf.c (obj_elf_change_section): Allow init array
sections to have the SHF_EXECINSTR attribute for the RX target.
* config/tc-rx.c (elf_flags): Initialise with E_FLAG_RX_ABI.
(enum options): Add OPTION_USES_GCC_ABI and OPTION_USES_RX_ABI.
(md_longopts): Add -mgcc-abi and -mrx-abi.
(md_parse_option): Add support for OPTION_USES_GCC_ABI and
OPTION_USES_RX_ABI.
* doc/as.texinfo (RX Options): Add mention of remaining RX
options.
* doc/c-rx.texi: Document -mgcc-abi and -mrx-abi.
include/elf/ChangeLog
2012-11-09 Nick Clifton <nickc@redhat.com>
* rx.h (EF_RX_CPU_RX): Add comment.
(E_FLAG_RX_ABI): Define.
ld/ChangeLog
2012-11-09 Nick Clifton <nickc@redhat.com>
* emultempl/rxelf.em (no_flag_mismatch_warnings): Initialise to
true.
(PARSE_AND_LIST_LONGOPTS): Add flag-mismatch-warnings.
(PARSE_AND_LIST_ARG_CASES): Add support for
--flag-mismatch-warnings.
Index: bfd/elf32-rx.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-rx.c,v
retrieving revision 1.20
diff -u -3 -p -r1.20 elf32-rx.c
--- bfd/elf32-rx.c 13 Jul 2012 14:22:47 -0000 1.20
+++ bfd/elf32-rx.c 9 Nov 2012 08:31:18 -0000
@@ -2937,6 +2937,39 @@ bfd_elf32_rx_set_target_flags (bfd_boole
ignore_lma = user_ignore_lma;
}
+/* Converts FLAGS into a descriptive string.
+ Returns a static pointer. */
+
+static const char *
+describe_flags (flagword flags)
+{
+ static char buf [128];
+
+ buf[0] = 0;
+
+ if (flags & E_FLAG_RX_64BIT_DOUBLES)
+ strcat (buf, "64-bit doubles");
+ else
+ strcat (buf, "32-bit doubles");
+
+ if (flags & E_FLAG_RX_DSP)
+ strcat (buf, ", dsp");
+ else
+ strcat (buf, ", no dsp");
+
+ if (flags & E_FLAG_RX_PID)
+ strcat (buf, ", pid");
+ else
+ strcat (buf, ", no pid");
+
+ if (flags & E_FLAG_RX_ABI)
+ strcat (buf, ", RX ABI");
+ else
+ strcat (buf, ", GCC ABI");
+
+ return buf;
+}
+
/* Merge backend specific data from an object file to the output
object file when linking. */
@@ -2958,7 +2991,10 @@ rx_elf_merge_private_bfd_data (bfd * ibf
}
else if (old_flags != new_flags)
{
- flagword known_flags = E_FLAG_RX_64BIT_DOUBLES | E_FLAG_RX_DSP | E_FLAG_RX_PID;
+ flagword known_flags;
+
+ known_flags = E_FLAG_RX_ABI | E_FLAG_RX_64BIT_DOUBLES
+ | E_FLAG_RX_DSP | E_FLAG_RX_PID;
if ((old_flags ^ new_flags) & known_flags)
{
@@ -2971,9 +3007,12 @@ rx_elf_merge_private_bfd_data (bfd * ibf
}
else
{
- (*_bfd_error_handler)
- ("ELF header flags mismatch: old_flags = 0x%.8lx, new_flags = 0x%.8lx, filename = %s",
- old_flags, new_flags, bfd_get_filename (ibfd));
+ _bfd_error_handler ("There is a conflict merging the ELF header flags from %s",
+ bfd_get_filename (ibfd));
+ _bfd_error_handler (" the input file's flags: %s",
+ describe_flags (new_flags));
+ _bfd_error_handler (" the output file's flags: %s",
+ describe_flags (old_flags));
error = TRUE;
}
}
@@ -3001,21 +3040,20 @@ rx_elf_print_private_bfd_data (bfd * abf
flags = elf_elfheader (abfd)->e_flags;
fprintf (file, _("private flags = 0x%lx:"), (long) flags);
- if (flags & E_FLAG_RX_64BIT_DOUBLES)
- fprintf (file, _(" [64-bit doubles]"));
- if (flags & E_FLAG_RX_DSP)
- fprintf (file, _(" [dsp]"));
-
- fputc ('\n', file);
+ fprintf (file, describe_flags (flags));
return TRUE;
}
/* Return the MACH for an e_flags value. */
static int
-elf32_rx_machine (bfd * abfd)
+elf32_rx_machine (bfd * abfd ATTRIBUTE_UNUSED)
{
+#if 0 /* FIXME: EF_RX_CPU_MASK collides with E_FLAG_RX_...
+ Need to sort out how these flag bits are used.
+ For now we assume that the flags are OK. */
if ((elf_elfheader (abfd)->e_flags & EF_RX_CPU_MASK) == EF_RX_CPU_RX)
+#endif
return bfd_mach_rx;
return 0;
@@ -3495,6 +3533,17 @@ elf32_rx_modify_program_headers (bfd * a
return TRUE;
}
+
+/* The default literal sections should always be marked as "code" (i.e.,
+ SHF_EXECINSTR). This is particularly important for big-endian mode
+ when we do not want their contents byte reversed. */
+static const struct bfd_elf_special_section elf32_rx_special_sections[] =
+{
+ { STRING_COMMA_LEN (".init_array"), 0, SHT_INIT_ARRAY, SHF_ALLOC + SHF_EXECINSTR },
+ { STRING_COMMA_LEN (".fini_array"), 0, SHT_FINI_ARRAY, SHF_ALLOC + SHF_EXECINSTR },
+ { STRING_COMMA_LEN (".preinit_array"), 0, SHT_PREINIT_ARRAY, SHF_ALLOC + SHF_EXECINSTR },
+ { NULL, 0, 0, 0, 0 }
+};
#define ELF_ARCH bfd_arch_rx
#define ELF_MACHINE_CODE EM_RX
@@ -3523,6 +3572,7 @@ elf32_rx_modify_program_headers (bfd * a
#define bfd_elf32_set_section_contents rx_set_section_contents
#define bfd_elf32_bfd_final_link rx_final_link
#define bfd_elf32_bfd_relax_section elf32_rx_relax_section_wrapper
+#define elf_backend_special_sections elf32_rx_special_sections
#include "elf32-target.h"
Index: binutils/readelf.c
===================================================================
RCS file: /cvs/src/src/binutils/readelf.c,v
retrieving revision 1.585
diff -u -3 -p -r1.585 readelf.c
--- binutils/readelf.c 1 Nov 2012 14:57:22 -0000 1.585
+++ binutils/readelf.c 9 Nov 2012 08:31:19 -0000
@@ -2682,6 +2736,8 @@ get_machine_flags (unsigned e_flags, uns
strcat (buf, ", dsp");
if (e_flags & E_FLAG_RX_PID)
strcat (buf, ", pid");
+ if (e_flags & E_FLAG_RX_ABI)
+ strcat (buf, ", RX ABI");
break;
case EM_S390:
Index: gas/config/obj-elf.c
===================================================================
RCS file: /cvs/src/src/gas/config/obj-elf.c,v
retrieving revision 1.147
diff -u -3 -p -r1.147 obj-elf.c
--- gas/config/obj-elf.c 30 Jun 2012 06:32:29 -0000 1.147
+++ gas/config/obj-elf.c 9 Nov 2012 08:31:20 -0000
@@ -658,6 +658,14 @@ obj_elf_change_section (const char *name
else if ((attr & ~ssect->attr) == SHF_ALPHA_GPREL)
override = TRUE;
#endif
+#ifdef TC_RX
+ else if (attr == (SHF_EXECINSTR | SHF_WRITE | SHF_ALLOC)
+ && (ssect->type == SHT_INIT_ARRAY
+ || ssect->type == SHT_FINI_ARRAY
+ || ssect->type == SHT_PREINIT_ARRAY))
+ /* RX init/fini arrays can and should have the "awx" attributes set. */
+ ;
+#endif
else
{
if (group_name == NULL)
Index: gas/config/tc-rx.c
===================================================================
RCS file: /cvs/src/src/gas/config/tc-rx.c,v
retrieving revision 1.12
diff -u -3 -p -r1.12 tc-rx.c
--- gas/config/tc-rx.c 15 May 2012 03:04:47 -0000 1.12
+++ gas/config/tc-rx.c 9 Nov 2012 08:31:20 -0000
@@ -46,7 +46,7 @@ const char EXP_CHARS[] = "eE"
const char FLT_CHARS[] = "dD";
/* ELF flags to set in the output file header. */
-static int elf_flags = 0;
+static int elf_flags = E_FLAG_RX_ABI;
bfd_boolean rx_use_conventional_section_names = FALSE;
static bfd_boolean rx_use_small_data_limit = FALSE;
@@ -70,6 +70,8 @@ enum options
OPTION_RELAX,
OPTION_PID,
OPTION_INT_REGS,
+ OPTION_USES_GCC_ABI,
+ OPTION_USES_RX_ABI,
};
#define RX_SHORTOPTS ""
@@ -94,6 +96,8 @@ struct option md_longopts[] =
{"relax", no_argument, NULL, OPTION_RELAX},
{"mpid", no_argument, NULL, OPTION_PID},
{"mint-register", required_argument, NULL, OPTION_INT_REGS},
+ {"mgcc-abi", no_argument, NULL, OPTION_USES_GCC_ABI},
+ {"mrx-abi", no_argument, NULL, OPTION_USES_RX_ABI},
{NULL, no_argument, NULL, 0}
};
size_t md_longopts_size = sizeof (md_longopts);
@@ -143,6 +147,14 @@ md_parse_option (int c ATTRIBUTE_UNUSED,
case OPTION_INT_REGS:
rx_num_int_regs = atoi (optarg);
return 1;
+
+ case OPTION_USES_GCC_ABI:
+ elf_flags &= ~ E_FLAG_RX_ABI;
+ return 1;
+
+ case OPTION_USES_RX_ABI:
+ elf_flags |= E_FLAG_RX_ABI;
+ return 1;
}
return 0;
}
Index: gas/doc/as.texinfo
===================================================================
RCS file: /cvs/src/src/gas/doc/as.texinfo,v
retrieving revision 1.260
diff -u -3 -p -r1.260 as.texinfo
--- gas/doc/as.texinfo 30 Oct 2012 12:44:54 -0000 1.260
+++ gas/doc/as.texinfo 9 Nov 2012 08:31:21 -0000
@@ -459,6 +459,12 @@ gcc(1), ld(1), and the Info entries for
@emph{Target RX options:}
[@b{-mlittle-endian}|@b{-mbig-endian}]
[@b{-m32bit-doubles}|@b{-m64bit-doubles}]
+ [@b{-muse-conventional-section-names}]
+ [@b{-msmall-data-limit}]
+ [@b{-mpid}]
+ [@b{-mrelax}]
+ [@b{-mint-register=@var{number}}]
+ [@b{-mgcc-abi}|@b{-mrx-abi}]
@end ifset
@ifset S390
Index: gas/doc/c-rx.texi
===================================================================
RCS file: /cvs/src/src/gas/doc/c-rx.texi,v
retrieving revision 1.4
diff -u -3 -p -r1.4 c-rx.texi
--- gas/doc/c-rx.texi 15 May 2012 03:04:47 -0000 1.4
+++ gas/doc/c-rx.texi 9 Nov 2012 08:31:21 -0000
@@ -93,6 +93,19 @@ This option tells the assembler how many
for use by interrupt handlers. This is needed in order to compute the
correct values for the @code{%gpreg} and @code{%pidreg} meta registers.
+@cindex @samp{-mgcc-abi}
+@item -mgcc-abi
+This option tells the assembler that the old GCC ABI is being used by
+the assembled code. With this version of the ABI function arguments
+that are passed on the stack are aligned to a 32-bit boundary.
+
+@cindex @samp{-mrx-abi}
+@item -mrx-abi
+This option tells the assembler that the official RX ABI is being used
+by the assembled code. With this version of the ABI function
+arguments that are passed on the stack are aligned to their natural
+alignments. This option is the default.
+
@end table
@node RX-Modifiers
Index: include/elf/rx.h
===================================================================
RCS file: /cvs/src/src/include/elf/rx.h,v
retrieving revision 1.3
diff -u -3 -p -r1.3 rx.h
--- include/elf/rx.h 5 Oct 2011 14:13:29 -0000 1.3
+++ include/elf/rx.h 9 Nov 2012 08:31:22 -0000
@@ -110,7 +110,7 @@ START_RELOC_NUMBERS (elf_rx_reloc_type)
END_RELOC_NUMBERS (R_RX_max)
-#define EF_RX_CPU_RX 0x00000079 /* FIXME: correct value? */
+#define EF_RX_CPU_RX 0x00000079 /* FIXME: this collides with the E_FLAG_RX_... values below. */
#define EF_RX_CPU_MASK 0x0000007F /* specific cpu bits. */
#define EF_RX_ALL_FLAGS (EF_RX_CPU_MASK)
@@ -118,6 +118,7 @@ END_RELOC_NUMBERS (R_RX_max)
#define E_FLAG_RX_64BIT_DOUBLES (1 << 0)
#define E_FLAG_RX_DSP (1 << 1) /* Defined in the RX CPU Object file specification, but not explained. */
#define E_FLAG_RX_PID (1 << 2) /* Unofficial - DJ */
+#define E_FLAG_RX_ABI (1 << 3) /* Binary passes stacked arguments using natural alignment. Unofficial - NC. */
/* These define the addend field of R_RX_RH_RELAX relocations. */
#define RX_RELAXA_IMM6 0x00000010 /* Imm8/16/24/32 at bit offset 6. */
Index: ld/emultempl/rxelf.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/rxelf.em,v
retrieving revision 1.2
diff -u -3 -p -r1.2 rxelf.em
--- ld/emultempl/rxelf.em 17 May 2011 16:02:29 -0000 1.2
+++ ld/emultempl/rxelf.em 9 Nov 2012 08:31:22 -0000
@@ -25,7 +25,7 @@
test -z "$TARGET2_TYPE" && TARGET2_TYPE="rel"
fragment <<EOF
-static bfd_boolean no_flag_mismatch_warnings = FALSE;
+static bfd_boolean no_flag_mismatch_warnings = TRUE;
static bfd_boolean ignore_lma = TRUE;
/* This is a convenient point to tell BFD about target specific flags.
@@ -47,10 +47,12 @@ PARSE_AND_LIST_PROLOGUE='
#define OPTION_NO_FLAG_MISMATCH_WARNINGS 301
#define OPTION_IGNORE_LMA 302
#define OPTION_NO_IGNORE_LMA 303
+#define OPTION_FLAG_MISMATCH_WARNINGS 304
'
PARSE_AND_LIST_LONGOPTS='
{ "no-flag-mismatch-warnings", no_argument, NULL, OPTION_NO_FLAG_MISMATCH_WARNINGS},
+ { "flag-mismatch-warnings", no_argument, NULL, OPTION_FLAG_MISMATCH_WARNINGS},
{ "ignore-lma", no_argument, NULL, OPTION_IGNORE_LMA},
{ "no-ignore-lma", no_argument, NULL, OPTION_NO_IGNORE_LMA},
'
@@ -58,6 +60,8 @@ PARSE_AND_LIST_LONGOPTS='
PARSE_AND_LIST_OPTIONS='
fprintf (file, _(" --no-flag-mismatch-warnings Don'\''t warn about objects with incompatible\n"
" endian or dsp settings\n"));
+ fprintf (file, _(" --flag-mismatch-warnings Warn about objects with incompatible\n"
+ " endian, dsp or ABI settings\n"));
fprintf (file, _(" --ignore-lma Ignore segment LMAs [default]\n"
" (for Renesas Tools compatibility)\n"));
fprintf (file, _(" --no-ignore-lma Don'\''t ignore segment LMAs\n"));
@@ -68,6 +72,10 @@ PARSE_AND_LIST_ARGS_CASES='
no_flag_mismatch_warnings = TRUE;
break;
+ case OPTION_FLAG_MISMATCH_WARNINGS:
+ no_flag_mismatch_warnings = FALSE;
+ break;
+
case OPTION_IGNORE_LMA:
ignore_lma = TRUE;
break;