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 detecting string insn use


Hi Guys,

  I am applying the attached patch to add support for a couple of new
  bits in the ELF header of RX binaries.  These bits indicate whether
  the binary uses string insns (SMOVF, SUNTIL, etc), and if it is
  allowed to be linked to binaries which use string insns.  (The problem
  with the RX string insns is that they are not safe to use on the I/O
  portion of the address space, so if a binary will or might access that
  space, then the strings insns must not be used).

  A follow up patch to GCC (once the sources are unfrozen) will add
  support for a non-string-insn using RX multilib.

Cheers
  Nick

bfd/ChangeLog
2015-04-09  Nick Clifton  <nickc@redhat.com>

	* elf32-rx.c (describe_flags): Report the settings of the string
	insn using bits.
	(rx_elf_merge_private_bfd_data): Handle merging of the string insn
	using bits.

binutils/ChangeLog
2015-04-09  Nick Clifton  <nickc@redhat.com>

	* readelf.c (get_machine_flags): Report the setting of the string
	insn using bits.

gas/ChangeLog
2015-04-09  Nick Clifton  <nickc@redhat.com>

	* config/tc-rx.c (enum options): Add OPTION_DISALLOW_STRING_INSNS.
	(md_longopts): Add -mno-allow-string-insns.
	(md_parse_option): Handle -mno-allow-string-insns.
	(md_show_usage): Mention -mno-allow-string-insns.
	(rx_note_string_insn_use): New function.  Produces an error
	message if a string insn is used when it is not allowed.
	* config/rx-parse.y (SCMPU): Call rx_note_string_insn_use.
	(SMOVU, SMOVB, SMOVF, SUNTIL, SWHILE, RMPA): Likewise.
	* config/rx-defs.h (rx_note_string_insn_use): Prototype.
	* doc/c-rx.texi: Document -mno-allow-string-insns.

include/elf/ChangeLog
2015-04-09  Nick Clifton  <nickc@redhat.com>

	* rx.h (E_FLAG_RX_SINSNS_SET): New bit in e_flags field.
	(E_FLAG_RX_SINSNS_YES): Likewise.
	(E_FLAG_RX_SINSNS_MASK): New define.

diff --git a/bfd/elf32-rx.c b/bfd/elf32-rx.c
index b8c632e..8d71628 100644
--- a/bfd/elf32-rx.c
+++ b/bfd/elf32-rx.c
@@ -3086,6 +3086,9 @@ describe_flags (flagword flags)
   else
     strcat (buf, ", GCC ABI");
 
+  if (flags & E_FLAG_RX_SINSNS_SET)
+    strcat (buf, flags & E_FLAG_RX_SINSNS_YES ? ", uses String instructions" : ", bans String instructions");
+
   return buf;
 }
 
@@ -3112,8 +3115,22 @@ rx_elf_merge_private_bfd_data (bfd * ibfd, bfd * obfd)
     {
       flagword known_flags;
 
+      if (old_flags & E_FLAG_RX_SINSNS_SET)
+	{
+	  if ((new_flags & E_FLAG_RX_SINSNS_SET) == 0)
+	    {
+	      new_flags &= ~ E_FLAG_RX_SINSNS_MASK;
+	      new_flags |= (old_flags & E_FLAG_RX_SINSNS_MASK);
+	    }
+	}
+      else if (new_flags & E_FLAG_RX_SINSNS_SET)
+	{
+	  old_flags &= ~ E_FLAG_RX_SINSNS_MASK;
+	  old_flags |= (new_flags & E_FLAG_RX_SINSNS_MASK);
+	}
+
       known_flags = E_FLAG_RX_ABI | E_FLAG_RX_64BIT_DOUBLES
-	| E_FLAG_RX_DSP | E_FLAG_RX_PID;
+	| E_FLAG_RX_DSP | E_FLAG_RX_PID | E_FLAG_RX_SINSNS_MASK;
 
       if ((old_flags ^ new_flags) & known_flags)
 	{
diff --git a/binutils/readelf.c b/binutils/readelf.c
index fea372f..db69b5d 100644
--- a/binutils/readelf.c
+++ b/binutils/readelf.c
@@ -3274,6 +3274,9 @@ get_machine_flags (unsigned e_flags, unsigned e_machine)
 	    strcat (buf, ", pid");
 	  if (e_flags & E_FLAG_RX_ABI)
 	    strcat (buf, ", RX ABI");
+	  if (e_flags & E_FLAG_RX_SINSNS_SET)
+	    strcat (buf, e_flags & E_FLAG_RX_SINSNS_YES
+		    ? ", uses String instructions" : ", bans String instructions");
 	  break;
 
 	case EM_S390:
diff --git a/gas/config/rx-defs.h b/gas/config/rx-defs.h
index 2a15b6c..15c447d 100644
--- a/gas/config/rx-defs.h
+++ b/gas/config/rx-defs.h
@@ -62,6 +62,7 @@ extern void   rx_linkrelax_imm (int);
 extern void   rx_linkrelax_branch (void);
 extern int    rx_parse (void);
 extern int    rx_wrap (void);
+extern void   rx_note_string_insn_use (void);
 
 extern char * rx_lex_start;
 extern char * rx_lex_end;
diff --git a/gas/config/rx-parse.y b/gas/config/rx-parse.y
index 645ec99..5269d66 100644
--- a/gas/config/rx-parse.y
+++ b/gas/config/rx-parse.y
@@ -500,27 +500,27 @@ statement :
 /* ---------------------------------------------------------------------- */
 
 	| SCMPU
-	  { B2 (0x7f, 0x83); }
+	  { B2 (0x7f, 0x83); rx_note_string_insn_use (); }
 	| SMOVU
-	  { B2 (0x7f, 0x87); }
+	  { B2 (0x7f, 0x87); rx_note_string_insn_use (); }
 	| SMOVB
-	  { B2 (0x7f, 0x8b); }
+	  { B2 (0x7f, 0x8b); rx_note_string_insn_use (); }
 	| SMOVF
-	  { B2 (0x7f, 0x8f); }
+	  { B2 (0x7f, 0x8f); rx_note_string_insn_use (); }
 
 /* ---------------------------------------------------------------------- */
 
 	| SUNTIL bwl
-	  { B2 (0x7f, 0x80); F ($2, 14, 2); }
+	  { B2 (0x7f, 0x80); F ($2, 14, 2); rx_note_string_insn_use (); }
 	| SWHILE bwl
-	  { B2 (0x7f, 0x84); F ($2, 14, 2); }
+	  { B2 (0x7f, 0x84); F ($2, 14, 2); rx_note_string_insn_use (); }
 	| SSTR bwl
 	  { B2 (0x7f, 0x88); F ($2, 14, 2); }
 
 /* ---------------------------------------------------------------------- */
 
 	| RMPA bwl
-	  { B2 (0x7f, 0x8c); F ($2, 14, 2); }
+	  { B2 (0x7f, 0x8c); F ($2, 14, 2); rx_note_string_insn_use (); }
 
 /* ---------------------------------------------------------------------- */
 
diff --git a/gas/config/tc-rx.c b/gas/config/tc-rx.c
index 2dec69f..4e58f88 100644
--- a/gas/config/tc-rx.c
+++ b/gas/config/tc-rx.c
@@ -73,6 +73,7 @@ enum options
   OPTION_USES_GCC_ABI,
   OPTION_USES_RX_ABI,
   OPTION_CPU,
+  OPTION_DISALLOW_STRING_INSNS,
 };
 
 #define RX_SHORTOPTS ""
@@ -99,7 +100,8 @@ struct option md_longopts[] =
   {"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},
-  {"mcpu",required_argument,NULL,OPTION_CPU},
+  {"mcpu", required_argument, NULL, OPTION_CPU},
+  {"mno-allow-string-insns", no_argument, NULL, OPTION_DISALLOW_STRING_INSNS},
   {NULL, no_argument, NULL, 0}
 };
 size_t md_longopts_size = sizeof (md_longopts);
@@ -173,6 +175,10 @@ md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED)
 	  break;
 	}
       return 1;
+
+    case OPTION_DISALLOW_STRING_INSNS:
+      elf_flags |= E_FLAG_RX_SINSNS_SET | E_FLAG_RX_SINSNS_NO;
+      return 1;
     }
   return 0;
 }
@@ -192,6 +198,7 @@ md_show_usage (FILE * stream)
   fprintf (stream, _("  --mpid\n"));
   fprintf (stream, _("  --mint-register=<value>\n"));
   fprintf (stream, _("  --mcpu=<rx100|rx200|rx600|rx610>\n"));
+  fprintf (stream, _("  --mno-allow-string-insns"));
 }
 
 static void
@@ -2623,6 +2630,14 @@ tc_gen_reloc (asection * sec ATTRIBUTE_UNUSED, fixS * fixp)
   return reloc;
 }
 
+void
+rx_note_string_insn_use (void)
+{
+  if ((elf_flags & E_FLAG_RX_SINSNS_MASK) == (E_FLAG_RX_SINSNS_SET | E_FLAG_RX_SINSNS_NO))
+    as_bad (_("Use of an RX string instruction detected in a file being assembled without string instruction support"));
+  elf_flags |= E_FLAG_RX_SINSNS_SET | E_FLAG_RX_SINSNS_YES;
+}
+
 /* Set the ELF specific flags.  */
 
 void
diff --git a/gas/doc/c-arm.texi b/gas/doc/c-arm.texi
diff --git a/gas/doc/c-rx.texi b/gas/doc/c-rx.texi
index 0eddb08..abf15cd 100644
--- a/gas/doc/c-rx.texi
+++ b/gas/doc/c-rx.texi
@@ -112,6 +112,21 @@ This option tells the assembler the target CPU type.  Currently the
 cpu names.  Attempting to assemble an instruction not supported by the
 indicated cpu type will result in an error message being generated.
 
+@cindex @samp{-mno-allow-string-insns}
+@item -mno-allow-string-insns
+This option tells the assembler to mark the object file that it is
+building as one that does not use the string instructions
+@code{SMOVF}, @code{SCMPU}, @code {SMOVB}, @code{SMOVU}, @code{SUNTIL} 
+@code {SWHILE} or the @code {RMPA} instruction.  In addition the mark
+tells the linker to complain if an attempt is made to link the binary
+with another one that does use any of these instructions.
+
+Note - the inverse of this option, @code{-mallow-string-insns}, is
+not needed.  The assembler automatically detects the use of the
+the instructions in the source code and labels the resulting
+object file appropriately.  If no string instructions are detected
+then the object file is labelled as being one that can be linked with
+either string-using or string-banned object files.
 @end table
 
 @node RX-Modifiers
diff --git a/include/elf/rx.h b/include/elf/rx.h
index de367d2..f945dac 100644
--- a/include/elf/rx.h
+++ b/include/elf/rx.h
@@ -120,6 +120,11 @@ END_RELOC_NUMBERS (R_RX_max)
 #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.  */
 
+#define E_FLAG_RX_SINSNS_SET		(1 << 6) /* Set if bit-5 is significant.  */
+#define E_FLAG_RX_SINSNS_YES		(1 << 7) /* Set if string instructions are used in the binary.  */
+#define E_FLAG_RX_SINSNS_NO		0        /* Bit-5 if this binary must not be linked with a string instruction using binary.  */
+#define E_FLAG_RX_SINSNS_MASK		(3 << 6) /* Mask of bits used to determine string instruction use.  */
+
 /* These define the addend field of R_RX_RH_RELAX relocations.  */
 #define	RX_RELAXA_IMM6	0x00000010	/* Imm8/16/24/32 at bit offset 6.  */
 #define	RX_RELAXA_IMM12	0x00000020	/* Imm8/16/24/32 at bit offset 12.  */

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