This is the mail archive of the binutils-cvs@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]

[binutils-gdb] [ARC] 24 bit reloc and overflow detection fix.


https://sourceware.org/git/gitweb.cgi?p=binutils-gdb.git;h=094fb06395d03ac343d1ce14a3621d1b4f78a0cc

commit 094fb06395d03ac343d1ce14a3621d1b4f78a0cc
Author: Claudiu Zissulescu <claziss@synopsys.com>
Date:   Tue Apr 5 17:05:09 2016 +0200

    [ARC] 24 bit reloc and overflow detection fix.
    
    bfd/
    2016-04-05  Cupertino Miranda  <cmiranda@synopsys.com>
    
    	* elf32-arc.c (name_for_global_symbol): Changed assert.
    	(get_replace_function): Created.:
    	(struct arc_relocation_data): Changed to signed types.
    	(defines S, L, P, PDATA): Casted to signed type.
    	(defines SECTSTART, _SDA_BASE_, TLS_REL): Likewise.
    	(PRINT_DEBUG_RELOC_INFO_BEFORE): Changed.
    	(arc_do_relocation): Changed.
    
    include/
    2016-04-05  Cupertino Miranda  <cmiranda@synopsys.com>
    
    	* opcode/arc-func.h (replace_bits24): Changed.
    	(replace_bits24_be): Created.

Diff:
---
 bfd/ChangeLog             | 10 ++++++
 bfd/elf32-arc.c           | 78 +++++++++++++++++++++++++++++------------------
 include/ChangeLog         |  5 +++
 include/opcode/arc-func.h | 17 ++++++++++-
 4 files changed, 80 insertions(+), 30 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 80539b8..4fcb108 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,5 +1,15 @@
 2016-04-05  Cupertino Miranda  <cmiranda@synopsys.com>
 
+	* elf32-arc.c (name_for_global_symbol): Changed assert.
+	(get_replace_function): Created.:
+	(struct arc_relocation_data): Changed to signed types.
+	(defines S, L, P, PDATA): Casted to signed type.
+	(defines SECTSTART, _SDA_BASE_, TLS_REL): Likewise.
+	(PRINT_DEBUG_RELOC_INFO_BEFORE): Changed.
+	(arc_do_relocation): Changed.
+
+2016-04-05  Cupertino Miranda  <cmiranda@synopsys.com>
+
 	* elf32-arc.c (name_for_global_symbol): Added assert to check for
 	symbol index.
 	(elf_arc_relocate_section): Added and changed asserts, validating
diff --git a/bfd/elf32-arc.c b/bfd/elf32-arc.c
index a7c0330..6facd92 100644
--- a/bfd/elf32-arc.c
+++ b/bfd/elf32-arc.c
@@ -375,6 +375,29 @@ static const struct arc_reloc_map arc_reloc_map[] =
 };
 #undef ARC_RELOC_HOWTO
 
+typedef ATTRIBUTE_UNUSED bfd_vma (*replace_func) (unsigned, int ATTRIBUTE_UNUSED);
+
+#define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
+  case TYPE: \
+    func = (void *) RELOC_FUNCTION; \
+    break;
+static replace_func
+get_replace_function (bfd *abfd, unsigned int r_type)
+{
+  void *func = NULL;
+
+  switch (r_type)
+    {
+      #include "elf/arc-reloc.def"
+    }
+
+  if (func == replace_bits24 && bfd_big_endian (abfd))
+    return (replace_func) replace_bits24_be;
+
+  return (replace_func) func;
+}
+#undef ARC_RELOC_HOWTO
+
 static reloc_howto_type *
 arc_elf32_bfd_reloc_type_lookup (bfd * abfd ATTRIBUTE_UNUSED,
 				 bfd_reloc_code_real_type code)
@@ -683,20 +706,20 @@ arc_elf_final_write_processing (bfd * abfd,
 
 struct arc_relocation_data
 {
-  bfd_vma	  reloc_offset;
-  bfd_vma	  reloc_addend;
-  bfd_vma	  got_offset_value;
+  bfd_signed_vma  reloc_offset;
+  bfd_signed_vma  reloc_addend;
+  bfd_signed_vma  got_offset_value;
 
-  bfd_vma	  sym_value;
+  bfd_signed_vma  sym_value;
   asection *	  sym_section;
 
   reloc_howto_type *howto;
 
   asection *	  input_section;
 
-  bfd_vma	  sdata_begin_symbol_vma;
+  bfd_signed_vma  sdata_begin_symbol_vma;
   bfd_boolean	  sdata_begin_symbol_vma_set;
-  bfd_vma	  got_symbol_vma;
+  bfd_signed_vma  got_symbol_vma;
 
   bfd_boolean	  should_relocate;
 };
@@ -770,16 +793,14 @@ middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
 #define IS_ME(FORMULA,BFD) ((strstr (FORMULA, "ME") != NULL) \
 			    && (!bfd_big_endian (BFD)))
 
-#define S (reloc_data.sym_value						\
+#define S ((bfd_signed_vma) (reloc_data.sym_value			\
 	   + (reloc_data.sym_section->output_section != NULL ?		\
 	      (reloc_data.sym_section->output_offset			\
-	       + reloc_data.sym_section->output_section->vma) : 0)	\
-	   )
-#define L (reloc_data.sym_value						\
+	       + reloc_data.sym_section->output_section->vma) : 0)))
+#define L ((bfd_signed_vma) (reloc_data.sym_value			\
 	   + (reloc_data.sym_section->output_section != NULL ?		\
 	      (reloc_data.sym_section->output_offset			\
-	      + reloc_data.sym_section->output_section->vma) : 0)	\
-	  )
+	      + reloc_data.sym_section->output_section->vma) : 0)))
 #define A (reloc_data.reloc_addend)
 #define B (0)
 #define G (reloc_data.got_offset_value)
@@ -789,33 +810,32 @@ middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
 #define MES (0)
 	/* P: relative offset to PCL The offset should be to the
 	  current location aligned to 32 bits.  */
-#define P (								\
+#define P ((bfd_signed_vma) (						\
 	   (								\
 	    (reloc_data.input_section->output_section != NULL ?		\
 	     reloc_data.input_section->output_section->vma : 0)		\
 	    + reloc_data.input_section->output_offset			\
-	    + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0))	\
-	    ) & ~0x3)
-#define PDATA ( \
+	    + (reloc_data.reloc_offset - (bitsize >= 32 ? 4 : 0)))	\
+	   & ~0x3))
+#define PDATA ((bfd_signed_vma) ( \
 	    (reloc_data.input_section->output_section->vma \
 	     + reloc_data.input_section->output_offset \
-	     + (reloc_data.reloc_offset) \
-	    ))
-#define SECTSTAR (reloc_data.input_section->output_offset)
-#define SECTSTART (reloc_data.input_section->output_offset)
-#define _SDA_BASE_ (reloc_data.sdata_begin_symbol_vma)
-#define TLS_REL ((elf_hash_table (info))->tls_sec->output_section->vma)
-#define _SDA_BASE_ (reloc_data.sdata_begin_symbol_vma)
+	     + (reloc_data.reloc_offset))))
+#define SECTSTART (bfd_signed_vma) (reloc_data.input_section->output_offset)
+#define _SDA_BASE_ (bfd_signed_vma) (reloc_data.sdata_begin_symbol_vma)
+#define TLS_REL (bfd_signed_vma) \
+  ((elf_hash_table (info))->tls_sec->output_section->vma)
 #define TLS_TBSS (8)
 #define TCB_SIZE (8)
 
 #define none (0)
 
-#define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA) \
+#define PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA, TYPE) \
     {\
       asection *sym_section = reloc_data.sym_section; \
       asection *input_section = reloc_data.input_section; \
-      ARC_DEBUG ("FORMULA = " #FORMULA "\n"); \
+      ARC_DEBUG ("RELOC_TYPE = " TYPE "\n"); \
+      ARC_DEBUG ("FORMULA = " FORMULA "\n"); \
       ARC_DEBUG ("S = 0x%x\n", S); \
       ARC_DEBUG ("A = 0x%x\n", A); \
       ARC_DEBUG ("L = 0x%x\n", L); \
@@ -856,11 +876,11 @@ middle_endian_convert (bfd_vma insn, bfd_boolean do_it)
 #define ARC_RELOC_HOWTO(TYPE, VALUE, SIZE, BITSIZE, RELOC_FUNCTION, OVERFLOW, FORMULA) \
   case R_##TYPE: \
     { \
-      bfd_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
+      bfd_signed_vma bitsize ATTRIBUTE_UNUSED = BITSIZE; \
       relocation = FORMULA  ; \
-      PRINT_DEBUG_RELOC_INFO_BEFORE(FORMULA) \
+      PRINT_DEBUG_RELOC_INFO_BEFORE (#FORMULA, #TYPE); \
       insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
-      insn = RELOC_FUNCTION (insn, relocation); \
+      insn = (* get_replace_function (abfd, TYPE)) (insn, relocation); \
       insn = middle_endian_convert (insn, IS_ME (#FORMULA, abfd)); \
       PRINT_DEBUG_RELOC_INFO_AFTER \
     } \
@@ -871,7 +891,7 @@ arc_do_relocation (bfd_byte * contents,
 		   struct arc_relocation_data reloc_data,
 		   struct bfd_link_info *info)
 {
-  bfd_vma relocation = 0;
+  bfd_signed_vma relocation = 0;
   bfd_vma insn;
   bfd_vma orig_insn ATTRIBUTE_UNUSED;
   bfd * abfd = reloc_data.input_section->owner;
diff --git a/include/ChangeLog b/include/ChangeLog
index 874088d..755c014 100644
--- a/include/ChangeLog
+++ b/include/ChangeLog
@@ -1,3 +1,8 @@
+2016-04-05  Cupertino Miranda  <cmiranda@synopsys.com>
+
+	* opcode/arc-func.h (replace_bits24): Changed.
+	(replace_bits24_be): Created.
+
 2016-03-29  Claudiu Zissulescu  <claziss@synopsys.com>
 
         * opcode/arc.h (insn_subclass_t): Add QUARKSE subclass.
diff --git a/include/opcode/arc-func.h b/include/opcode/arc-func.h
index 47451a6..cafb92f 100644
--- a/include/opcode/arc-func.h
+++ b/include/opcode/arc-func.h
@@ -66,13 +66,28 @@ replace_bits16 (unsigned insn, int value ATTRIBUTE_UNUSED)
 ATTRIBUTE_UNUSED static unsigned
 replace_bits24 (unsigned insn, int value ATTRIBUTE_UNUSED)
 {
+  insn = insn & ~0xffffff;
+  insn |= ((value >> 0) & 0xffffff) << 0;
+
+  return insn;
+}
+
+#endif /* REPLACE_bits24 */
+
+/* Special 24 bit replace for big endian.  */
+/* mask  = 111111111111111111111111.  */
+#ifndef REPLACE_bits24_be
+#define REPLACE_bits24_be
+ATTRIBUTE_UNUSED static unsigned
+replace_bits24_be (unsigned insn, int value ATTRIBUTE_UNUSED)
+{
   insn = insn & ~0xffffff00;
   insn |= ((value >> 0) & 0xffffff) << 8;
 
   return insn;
 }
 
-#endif /* REPLACE_bits24 */
+#endif /* REPLACE_bits24_be */
 
 /* mask  = 11111111111111111111111111111111.  */
 #ifndef REPLACE_word32


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