[ARC] 24 bit reloc and overflow detection fix.
authorClaudiu Zissulescu <claziss@synopsys.com>
Tue, 5 Apr 2016 15:05:09 +0000 (17:05 +0200)
committerClaudiu Zissulescu <claziss@synopsys.com>
Tue, 5 Apr 2016 15:05:09 +0000 (17:05 +0200)
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.

bfd/ChangeLog
bfd/elf32-arc.c
include/ChangeLog
include/opcode/arc-func.h

index 80539b8d125398c574758c6e197815273a73cb44..4fcb1080d49150cfd4a4dfceeafa0fa2024e01ad 100644 (file)
@@ -1,3 +1,13 @@
+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
index a7c0330450197acc4da10cf477ef7455fa0c18d0..6facd92087817c25292903fa4db6113a991e5903 100644 (file)
@@ -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;
index 874088d5bea792392ff5434dfb9f8459e799ab8c..755c01496b7c18e95cd81971585c4e5070413e88 100644 (file)
@@ -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.
index 47451a6af3b733a904c8bae5562c9871e14c6e32..cafb92fd7e2a3eaaa1d026b53302697992268020 100644 (file)
@@ -65,6 +65,21 @@ replace_bits16 (unsigned insn, int value ATTRIBUTE_UNUSED)
 #define REPLACE_bits24
 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;
@@ -72,7 +87,7 @@ replace_bits24 (unsigned insn, int value ATTRIBUTE_UNUSED)
   return insn;
 }
 
-#endif /* REPLACE_bits24 */
+#endif /* REPLACE_bits24_be */
 
 /* mask  = 11111111111111111111111111111111.  */
 #ifndef REPLACE_word32