* elf32-v850.c (bfd_elf32_v850_reloc): Fix handling of
authorJeff Law <law@redhat.com>
Wed, 4 Sep 1996 03:03:53 +0000 (03:03 +0000)
committerJeff Law <law@redhat.com>
Wed, 4 Sep 1996 03:03:53 +0000 (03:03 +0000)
        low order sign bit propogationfor R_V850_HI16_S.
Fixes c-torture execute/950221-1.c, maybe others.

bfd/ChangeLog
bfd/elf32-v850.c

index 8c1b154fabf235590332ae243f5e70577b950fdb..5cde6a58217a27ea2220e73d3d54dc2e1467403b 100644 (file)
@@ -5,7 +5,6 @@ Tue Sep  3 12:16:20 1996  Doug Evans  <dje@canuck.cygnus.com>
        * config.bfd (sparclet-*-aout*): Add case.
        * configure.in (sparcle_aout_vec): Add case.
        * configure: Regenerated.
-       * libaout.h (machine_type): Add M_SPARCLET_LE.
        * targets.c (sparcle_aout_vec): Declare.
        (bfd_target_vector): Add sparcle_aout_vec.
        * aout-sparcle.c: New file.
@@ -13,7 +12,10 @@ Tue Sep  3 12:16:20 1996  Doug Evans  <dje@canuck.cygnus.com>
 start-sanitize-v850
 Tue Sep  3 00:57:02 1996  Jeffrey A Law  (law@cygnus.com)
 
-       * elf32-v850.c (bfd_elf3_v850_reloc): New function for
+       * elf32-v850.c (bfd_elf32_v850_reloc): Fix handling of
+       low order sign bit propogation for R_V850_HI16_S.
+
+       * elf32-v850.c (bfd_elf32_v850_reloc): New function for
        handling V850 specific relocs.
        (elf_v850_howto_table): Use the new function for some
        relocations.  Twiddle masks & shifts for some relocs.
index 22921b70d185706949b3090e8d6a6dc71f7a87b1..4c42d6d2985641937b5a7b062a31ec24b04d78bb 100644 (file)
@@ -26,6 +26,9 @@ static reloc_howto_type *bfd_elf32_bfd_reloc_type_lookup
   PARAMS ((bfd *abfd, bfd_reloc_code_real_type code));
 static void v850_info_to_howto_rel
   PARAMS ((bfd *, arelent *, Elf32_Internal_Rel *));
+static bfd_reloc_status_type bfd_elf32_v850_reloc
+  PARAMS ((bfd *, arelent *, asymbol *, PTR, asection *, bfd *, char **));
+
 
 
 /* Try to minimize the amount of space occupied by relocation tables
@@ -71,7 +74,7 @@ static reloc_howto_type elf_v850_howto_table[] =
         true,                  /* pc_relative */
         0,                     /* bitpos */
         complain_overflow_bitfield, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        bfd_elf32_v850_reloc,  /* special_function */
         "R_V850_9_PCREL",      /* name */
         false,                 /* partial_inplace */
         0x00ffffff,            /* src_mask */
@@ -86,7 +89,7 @@ static reloc_howto_type elf_v850_howto_table[] =
         true,                  /* pc_relative */
         7,                     /* bitpos */
         complain_overflow_signed, /* complain_on_overflow */
-        bfd_elf_generic_reloc, /* special_function */
+        bfd_elf32_v850_reloc,  /* special_function */
         "R_V850_22_PCREL",     /* name */
         false,                 /* partial_inplace */
         0x07ffff80,            /* src_mask */
@@ -99,9 +102,9 @@ static reloc_howto_type elf_v850_howto_table[] =
          1,                     /* size (0 = byte, 1 = short, 2 = long) */
          16,                    /* bitsize */
          false,                 /* pc_relative */
-         16,                    /* bitpos */
+         0,                    /* bitpos */
          complain_overflow_dont,/* complain_on_overflow */
-         bfd_elf_generic_reloc, /* special_function */
+         bfd_elf32_v850_reloc, /* special_function */
          "R_V850_HI16_S",       /* name */
          true,                  /* partial_inplace */
          0xffff,                /* src_mask */
@@ -114,9 +117,9 @@ static reloc_howto_type elf_v850_howto_table[] =
          1,                     /* size (0 = byte, 1 = short, 2 = long) */
          16,                    /* bitsize */
          false,                 /* pc_relative */
-         16,                    /* bitpos */
+         0,                    /* bitpos */
          complain_overflow_dont,/* complain_on_overflow */
-         bfd_elf_generic_reloc, /* special_function */
+         bfd_elf32_v850_reloc, /* special_function */
          "R_V850_HI16",         /* name */
          true,                  /* partial_inplace */
          0xffff,                /* src_mask */
@@ -129,7 +132,7 @@ static reloc_howto_type elf_v850_howto_table[] =
          1,                     /* size (0 = byte, 1 = short, 2 = long) */
          16,                    /* bitsize */
          false,                 /* pc_relative */
-         16,                     /* bitpos */
+         0,                     /* bitpos */
          complain_overflow_dont,/* complain_on_overflow */
          bfd_elf_generic_reloc, /* special_function */
          "R_V850_LO16",         /* name */
@@ -148,8 +151,8 @@ static reloc_howto_type elf_v850_howto_table[] =
          complain_overflow_dont,/* complain_on_overflow */
          bfd_elf_generic_reloc, /* special_function */
          "R_V850_32",         /* name */
-         false,                  /* partial_inplace */
-         0,                /* src_mask */
+         true,                  /* partial_inplace */
+         0xffffffff,                /* src_mask */
          0xffffffff,                /* dst_mask */
          false),                /* pcrel_offset */
 
@@ -163,8 +166,8 @@ static reloc_howto_type elf_v850_howto_table[] =
          complain_overflow_dont,/* complain_on_overflow */
          bfd_elf_generic_reloc, /* special_function */
          "R_V850_16",         /* name */
-         false,                  /* partial_inplace */
-         0,                /* src_mask */
+         true,                  /* partial_inplace */
+         0xffff,                /* src_mask */
          0xffff,                /* dst_mask */
          false),                /* pcrel_offset */
 
@@ -178,8 +181,8 @@ static reloc_howto_type elf_v850_howto_table[] =
          complain_overflow_dont,/* complain_on_overflow */
          bfd_elf_generic_reloc, /* special_function */
          "R_V850_8",         /* name */
-         false,                  /* partial_inplace */
-         0,                /* src_mask */
+         true,                  /* partial_inplace */
+         0xff,                /* src_mask */
          0xff,                /* dst_mask */
          false),                /* pcrel_offset */
 };
@@ -238,8 +241,110 @@ v850_info_to_howto_rel (abfd, cache_ptr, dst)
   cache_ptr->howto = &elf_v850_howto_table[r_type];
 }
 
-#define TARGET_BIG_SYM         bfd_elf32_v850_vec
-#define TARGET_BIG_NAME                "elf32-v850"
+static bfd_reloc_status_type
+bfd_elf32_v850_reloc (abfd, reloc, symbol, data, isection, obfd, err)
+     bfd *abfd;
+     arelent *reloc;
+     asymbol *symbol;
+     PTR data;
+     asection *isection;
+     bfd *obfd;
+     char **err;
+{
+  if (obfd != (bfd *) NULL
+      && (symbol->flags & BSF_SECTION_SYM) == 0
+      && (! reloc->howto->partial_inplace
+         || reloc->addend == 0))
+    {
+      reloc->address += isection->output_offset;
+      return bfd_reloc_ok;
+    }
+  else if (obfd != NULL)
+    {
+      return bfd_reloc_continue;
+    }
+
+  /* We handle final linking of some relocs ourselves.  */
+    {
+      long relocation, insn;
+
+      /* Is the address of the relocation really within the section?  */
+      if (reloc->address > isection->_cooked_size)
+       return bfd_reloc_outofrange;
+
+      /* Work out which section the relocation is targetted at and the
+        initial relocation command value.  */
+
+      /* Get symbol value.  (Common symbols are special.)  */
+      if (bfd_is_com_section (symbol->section))
+       relocation = 0;
+      else
+       relocation = symbol->value;
+
+      /* Convert input-section-relative symbol value to absolute + addend.  */
+      relocation += symbol->section->output_section->vma;
+      relocation += symbol->section->output_offset;
+      relocation += reloc->addend;
+
+      if (reloc->howto->pc_relative == true)
+       {
+         /* Here the variable relocation holds the final address of the
+            symbol we are relocating against, plus any addend.  */
+         relocation -= isection->output_section->vma + isection->output_offset;
+
+         /* Deal with pcrel_offset */
+         relocation -= reloc->address;
+       }
+
+      /* I've got no clue... */
+      reloc->addend = 0;       
+
+      if (reloc->howto->type == R_V850_22_PCREL)
+       {
+         if (relocation > 0x1ffff || relocation < -0x200000)
+           return bfd_reloc_overflow;
+
+         if ((relocation % 2) != 0)
+           return bfd_reloc_dangerous;
+
+         insn = bfd_get_32 (abfd, (bfd_byte *) data + reloc->address);
+         insn |= (((relocation & 0xfffe) << 16)
+                  | ((relocation & 0x3f0000) >> 16));
+         bfd_put_32 (abfd, insn, (bfd_byte *)data + reloc->address);
+         return bfd_reloc_ok;
+       }
+      else if (reloc->howto->type == R_V850_9_PCREL)
+       {
+         if (relocation > 0xff || relocation < -0x100)
+           return bfd_reloc_overflow;
+
+         if ((relocation % 2) != 0)
+           return bfd_reloc_dangerous;
+
+         insn = bfd_get_16 (abfd, (bfd_byte *) data + reloc->address);
+         insn |= ((relocation & 0x1f0) << 7) | ((relocation & 0x0e) << 3);
+         bfd_put_16 (abfd, insn, (bfd_byte *)data + reloc->address);
+         return bfd_reloc_ok;
+       }
+      else if (reloc->howto->type == R_V850_HI16_S)
+       {
+         relocation = (relocation >> 16) + ((relocation & 0x8000) != 0);
+         bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
+         return bfd_reloc_ok;
+       }
+      else if (reloc->howto->type == R_V850_HI16)
+       {
+         relocation = (relocation >> 16);
+         bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
+         return bfd_reloc_ok;
+       }
+    }
+
+  return bfd_reloc_continue;
+}
+
+#define TARGET_LITTLE_SYM              bfd_elf32_v850_vec
+#define TARGET_LITTLE_NAME             "elf32-v850"
 #define ELF_ARCH               bfd_arch_v850
 #define ELF_MACHINE_CODE       EM_CYGNUS_V850
 #define ELF_MAXPAGESIZE                0x1000