This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

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;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]