S12Z: Emit RELOC_S12Z_OPR instead of RELOC_EXT24 where appropriate.

Message ID 20190115184736.23636-1-john@darrington.wattle.id.au
State New
Headers show
Series
  • S12Z: Emit RELOC_S12Z_OPR instead of RELOC_EXT24 where appropriate.
Related show

Commit Message

John Darrington Jan. 15, 2019, 6:47 p.m.
When assembling instructions which involve OPR references, emit
RELOC_S12Z_OPR instead of RELOC_EXT24.

bfd/
	* bfd-in2.h [BFD_RELOC_S12Z_OPR]: New reloc.
	* libbfd.h (bfd_relocl_code_real_names)[BFD_REOLOC_S12Z_OPR]: New
	entry.
	* elf32-s12z.c (eld_s12z_howto_table): R_S12Z_OPR takes non zero
	source field.  (md_apply_fix): Apply final fix
	to BFD_RELOC_S12Z_OPR.
	* reloc.c[BFD_RELOC_S12Z_OPR]: New reloc.

gas/
	* config/tc-s12z.c (emit_opr): Emit BFD_RELOC_S12Z_OPR instead of
	BFD_RELOC_24.
	* testsuite/gas/s12z/opr-indirect-expr.d: Expect R_S12Z_OPR instead
	of R_S12Z_EXT24.
---
 bfd/bfd-in2.h                              |  3 +++
 bfd/elf32-s12z.c                           | 13 +++++++------
 bfd/libbfd.h                               |  1 +
 bfd/reloc.c                                |  5 +++++
 gas/config/tc-s12z.c                       | 18 ++++++++++++------
 gas/testsuite/gas/s12z/opr-indirect-expr.d |  2 +-
 6 files changed, 29 insertions(+), 13 deletions(-)

-- 
2.11.0

Comments

Nick Clifton Jan. 16, 2019, 11:45 a.m. | #1
Hi John,

> bfd/

> 	* bfd-in2.h [BFD_RELOC_S12Z_OPR]: New reloc.

> 	* libbfd.h (bfd_relocl_code_real_names)[BFD_REOLOC_S12Z_OPR]: New

> 	entry.


Note - since libbfd.h is a generated file you could simply have:

        * libbfd.h: Regenerate.

> 	* elf32-s12z.c (eld_s12z_howto_table): R_S12Z_OPR takes non zero

> 	source field.  (md_apply_fix): Apply final fix

> 	to BFD_RELOC_S12Z_OPR.

> 	* reloc.c[BFD_RELOC_S12Z_OPR]: New reloc.

> 

> gas/

> 	* config/tc-s12z.c (emit_opr): Emit BFD_RELOC_S12Z_OPR instead of

> 	BFD_RELOC_24.

> 	* testsuite/gas/s12z/opr-indirect-expr.d: Expect R_S12Z_OPR instead

> 	of R_S12Z_EXT24.


Approved - please apply.

> +      /* Some third party tools seem to use the lower bits

> +	of this addend for flags.   They don't get added

> +	to the final location.   The purpose of these flags

> +	is not known.  We simply set it to zero.  */

> +      fix->fx_addnumber = 0x00;


That sounds a bit naughty.  (Of the third party tools that is).
Is this likely to cause problems in the future ?

Cheers
  Nick
John Darrington Jan. 16, 2019, 1:20 p.m. | #2
On Wed, Jan 16, 2019 at 11:45:23AM +0000, Nick Clifton wrote:
     Hi John,
     
     > bfd/

     > 	* bfd-in2.h [BFD_RELOC_S12Z_OPR]: New reloc.

     > 	* libbfd.h (bfd_relocl_code_real_names)[BFD_REOLOC_S12Z_OPR]: New

     > 	entry.

     
     Note - since libbfd.h is a generated file you could simply have:
     
             * libbfd.h: Regenerate.
     
     > 	* elf32-s12z.c (eld_s12z_howto_table): R_S12Z_OPR takes non zero

     > 	source field.  (md_apply_fix): Apply final fix

     > 	to BFD_RELOC_S12Z_OPR.

     > 	* reloc.c[BFD_RELOC_S12Z_OPR]: New reloc.

     > 

     > gas/

     > 	* config/tc-s12z.c (emit_opr): Emit BFD_RELOC_S12Z_OPR instead of

     > 	BFD_RELOC_24.

     > 	* testsuite/gas/s12z/opr-indirect-expr.d: Expect R_S12Z_OPR instead

     > 	of R_S12Z_EXT24.

     
     Approved - please apply.
     
     > +      /* Some third party tools seem to use the lower bits

     > +	of this addend for flags.   They don't get added

     > +	to the final location.   The purpose of these flags

     > +	is not known.  We simply set it to zero.  */

     > +      fix->fx_addnumber = 0x00;

     
     That sounds a bit naughty.  (Of the third party tools that is).
     Is this likely to cause problems in the future ?
     
It means that 3rd party linkers may have problems linking gas generated
elf files.  But the binutils linker can still link against 3rd party
generated elf files.

J'

-- 
Avoid eavesdropping.  Send strong encrypted email.
PGP Public key ID: 1024D/2DE827B3 
fingerprint = 8797 A26D 0854 2EAB 0285  A290 8A67 719C 2DE8 27B3
See http://sks-keyservers.net or any PGP keyserver for public key.

Patch

diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index b78d212ec5..e25da50aaf 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -6696,6 +6696,9 @@  assembler and not (currently) written to any object files.  */
   BFD_RELOC_CKCORE_IRELATIVE,
   BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4,
   BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4,
+
+/* S12Z relocations.  */
+  BFD_RELOC_S12Z_OPR,
   BFD_RELOC_UNUSED };
 
 typedef enum bfd_reloc_code_real bfd_reloc_code_real_type;
diff --git a/bfd/elf32-s12z.c b/bfd/elf32-s12z.c
index 57681cf8ca..a8f9b4aae1 100644
--- a/bfd/elf32-s12z.c
+++ b/bfd/elf32-s12z.c
@@ -119,7 +119,7 @@  static reloc_howto_type elf_s12z_howto_table[] =
 	 shift_addend_reloc,
 	 "R_S12Z_OPR",	/* name */
 	 FALSE,			/* partial_inplace */
-	 0x00000000,            /* src_mask */
+	 0x00ffffff,            /* src_mask */
 	 0x00ffffff,		/* dst_mask */
 	 FALSE),		/* pcrel_offset */
 
@@ -232,11 +232,12 @@  struct s12z_reloc_map
 
 static const struct s12z_reloc_map s12z_reloc_map[] =
 {
-  /* bfd reloc val */ /* elf reloc val */
-  {BFD_RELOC_NONE, R_S12Z_NONE},
-  {BFD_RELOC_32, R_S12Z_EXT32},
-  {BFD_RELOC_24, R_S12Z_EXT24},
-  {BFD_RELOC_16_PCREL, R_S12Z_PCREL_7_15}
+  /* bfd reloc val */  /* elf reloc val */
+  {BFD_RELOC_NONE,     R_S12Z_NONE},
+  {BFD_RELOC_32,       R_S12Z_EXT32},
+  {BFD_RELOC_24,       R_S12Z_EXT24},
+  {BFD_RELOC_16_PCREL, R_S12Z_PCREL_7_15},
+  {BFD_RELOC_S12Z_OPR, R_S12Z_OPR}
 };
 
 static reloc_howto_type *
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index e56ef37742..36284d71a9 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -3320,6 +3320,7 @@  static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_CKCORE_IRELATIVE",
   "BFD_RELOC_CKCORE_PCREL_BLOOP_IMM4BY4",
   "BFD_RELOC_CKCORE_PCREL_BLOOP_IMM12BY4",
+  "BFD_RELOC_S12Z_OPR",
  "@@overflow: BFD_RELOC_UNUSED@@",
 };
 #endif
diff --git a/bfd/reloc.c b/bfd/reloc.c
index b8a1cfe6e2..e6446a7809 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -8052,6 +8052,11 @@  ENUMX
 ENUMDOC
   C-SKY relocations.
 
+ENUM
+  BFD_RELOC_S12Z_OPR
+ENUMDOC
+  S12Z relocations.
+
 ENDSENUM
   BFD_RELOC_UNUSED
 CODE_FRAGMENT
diff --git a/gas/config/tc-s12z.c b/gas/config/tc-s12z.c
index 2f98c04d02..7d1ddf6643 100644
--- a/gas/config/tc-s12z.c
+++ b/gas/config/tc-s12z.c
@@ -732,12 +732,17 @@  emit_opr (char *f, const uint8_t *buffer, int n_bytes, expressionS *exp)
   number_to_chars_bigendian (f++, buffer[0], 1);
   if (exp->X_op != O_absent && exp->X_op != O_constant)
     {
-      fix_new_exp (frag_now,
-		   f - frag_now->fr_literal,
-		   3,
-		   exp,
-		   FALSE,
-		   BFD_RELOC_24);
+      fixS *fix = fix_new_exp (frag_now,
+			       f - frag_now->fr_literal,
+			       3,
+			       exp,
+			       FALSE,
+			       BFD_RELOC_S12Z_OPR);
+      /* Some third party tools seem to use the lower bits
+	of this addend for flags.   They don't get added
+	to the final location.   The purpose of these flags
+	is not known.  We simply set it to zero.  */
+      fix->fx_addnumber = 0x00;
     }
   for (i = 1; i < n_bytes; ++i)
     number_to_chars_bigendian (f++,  buffer[i], 1);
@@ -3821,6 +3826,7 @@  md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
       bfd_putb16 ((bfd_vma) value, (unsigned char *) where);
       break;
     case BFD_RELOC_24:
+    case BFD_RELOC_S12Z_OPR:
       bfd_putb24 ((bfd_vma) value, (unsigned char *) where);
       break;
     case BFD_RELOC_32:
diff --git a/gas/testsuite/gas/s12z/opr-indirect-expr.d b/gas/testsuite/gas/s12z/opr-indirect-expr.d
index f7a1fcdf73..8facde578e 100644
--- a/gas/testsuite/gas/s12z/opr-indirect-expr.d
+++ b/gas/testsuite/gas/s12z/opr-indirect-expr.d
@@ -11,4 +11,4 @@  Disassembly of section .text:
 00000000 <.text>:
    0:	a7 fe 00 00 	ld d7, \[1\]
    4:	01 
-			2: R_S12Z_EXT24	FOO
+			2: R_S12Z_OPR	FOO