From 5bb28764085071f64e6eae9de388ea72893150df Mon Sep 17 00:00:00 2001
From: Nick Clifton <nickc@redhat.com>
Date: Tue, 16 Sep 1997 21:21:30 +0000
Subject: Add support for a 16 bit reloc against the TDA pointer!

---
 bfd/ChangeLog    |  8 ++++++++
 bfd/bfd-in2.h    |  3 +++
 bfd/elf32-v850.c | 43 +++++++++++++++++++++++++++++++++++++++++++
 bfd/libbfd.h     |  1 +
 bfd/reloc.c      |  4 ++++
 5 files changed, 59 insertions(+)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index 7531a36..bae50f8 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,11 @@
+Tue Sep 16 14:20:27 1997  Nick Clifton  <nickc@cygnus.com>
+
+	* reloc.c: Add BFR_RELOC_V850_TDA_16_16_OFFSET.
+
+	* elf32-v850.c (v850_elf_reloc, v850_elf_final_link_relocate,
+	v850_elf_howto_table, v850_elf_reloc_map): Add support for a 16
+	bit reloc in the tiny data area.
+
 start-sanitize-d30v
 Mon Sep 15 11:27:36 1997  Ken Raeburn  <raeburn@cygnus.com>
 
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 4d0ac33..b117532 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -1989,6 +1989,9 @@ data area pointer. */
 
 /* This is a 7 bit offset from the tiny data area pointer. */
   BFD_RELOC_V850_TDA_7_7_OFFSET,
+
+/* This is a 16 bit offset from the tiny data area pointer. */
+  BFD_RELOC_V850_TDA_16_16_OFFSET,
 /* start-sanitize-v850e */
 
 /* This is a 5 bit offset (of which only 4 bits are used) from the tiny
diff --git a/bfd/elf32-v850.c b/bfd/elf32-v850.c
index 4dbfe5e..feb298e 100644
--- a/bfd/elf32-v850.c
+++ b/bfd/elf32-v850.c
@@ -293,6 +293,21 @@ static reloc_howto_type v850_elf_howto_table[] =
 	 0x7f,				/* dst_mask */
 	 false),			/* pcrel_offset */
 
+  /* 16 bit offset from the tiny data area pointer!  */
+  HOWTO (R_V850_TDA_16_16_OFFSET,	/* type */
+	 0,				/* rightshift */
+	 1,				/* size (0 = byte, 1 = short, 2 = long) */
+	 16,				/* bitsize */
+	 false,				/* pc_relative */
+	 0,				/* bitpos */
+	 complain_overflow_dont,	/* complain_on_overflow */
+	 v850_elf_reloc,		/* special_function */
+	 "R_V850_TDA_16_16_OFFSET",	/* name */
+	 false,				/* partial_inplace */
+	 0xffff,			/* src_mask */
+	 0xfff,				/* dst_mask */
+	 false),			/* pcrel_offset */
+
 /* start-sanitize-v850e */
   
   /* 5 bit offset from the tiny data area pointer.  */
@@ -384,6 +399,7 @@ static const struct v850_elf_reloc_map v850_elf_reloc_map[] =
   { BFD_RELOC_V850_TDA_6_8_OFFSET,   R_V850_TDA_6_8_OFFSET },
   { BFD_RELOC_V850_TDA_7_8_OFFSET,   R_V850_TDA_7_8_OFFSET },
   { BFD_RELOC_V850_TDA_7_7_OFFSET,   R_V850_TDA_7_7_OFFSET },
+  { BFD_RELOC_V850_TDA_16_16_OFFSET, R_V850_TDA_16_16_OFFSET },
 /* start-sanitize-v850e */
   { BFD_RELOC_V850_TDA_4_5_OFFSET,         R_V850_TDA_4_5_OFFSET },
   { BFD_RELOC_V850_TDA_4_4_OFFSET,         R_V850_TDA_4_4_OFFSET },
@@ -520,6 +536,7 @@ v850_elf_check_relocs (abfd, info, sec, relocs)
 	case R_V850_TDA_6_8_OFFSET:
 	case R_V850_TDA_7_8_OFFSET:
 	case R_V850_TDA_7_7_OFFSET:
+	case R_V850_TDA_16_16_OFFSET:
 	  other = V850_OTHER_TDA;
 	  common = ".tcommon";
 	  /* fall through */
@@ -716,6 +733,7 @@ v850_elf_reloc (abfd, reloc, symbol, data, isection, obfd, err)
       
     case R_V850_SDA_16_16_OFFSET:
     case R_V850_ZDA_16_16_OFFSET:
+    case R_V850_TDA_16_16_OFFSET:
       if ((long)relocation > 0x7fff || (long)relocation < -0x8000)
 	return bfd_reloc_overflow;
       bfd_put_16 (abfd, relocation, (bfd_byte *)data + reloc->address);
@@ -1115,6 +1133,31 @@ v850_elf_final_link_relocate (howto, input_bfd, output_bfd,
 	return bfd_reloc_ok;
       }
     
+    case R_V850_TDA_16_16_OFFSET:
+      {
+	unsigned long                ep;
+	struct bfd_link_hash_entry * h;
+
+	/* Get the value of __ep.  */
+	h = bfd_link_hash_lookup (info->hash, "__ep", false, false, true);
+	if (h == (struct bfd_link_hash_entry *) NULL
+	    || h->type != bfd_link_hash_defined)
+	  return bfd_reloc_other;
+
+	ep = (h->u.def.value
+	      + h->u.def.section->output_section->vma
+	      + h->u.def.section->output_offset);
+	value -= ep;
+	
+	value += (short) bfd_get_16 (input_bfd, hit_data);
+
+	if ((long)value > 0x7fff || (long)value < -0x8000)
+	  return bfd_reloc_overflow;
+
+	bfd_put_16 (input_bfd, value, hit_data);
+	return bfd_reloc_ok;
+      }
+
 /* start-sanitize-v850e */
     case R_V850_TDA_4_5_OFFSET:
       {
diff --git a/bfd/libbfd.h b/bfd/libbfd.h
index c6f9ccc..f22f322 100644
--- a/bfd/libbfd.h
+++ b/bfd/libbfd.h
@@ -781,6 +781,7 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
   "BFD_RELOC_V850_TDA_6_8_OFFSET",
   "BFD_RELOC_V850_TDA_7_8_OFFSET",
   "BFD_RELOC_V850_TDA_7_7_OFFSET",
+  "BFD_RELOC_V850_TDA_16_16_OFFSET",
 /* start-sanitize-v850e */
   "BFD_RELOC_V850_TDA_4_5_OFFSET",
   "BFD_RELOC_V850_TDA_4_4_OFFSET",
diff --git a/bfd/reloc.c b/bfd/reloc.c
index e878ce3..9e31e49 100644
--- a/bfd/reloc.c
+++ b/bfd/reloc.c
@@ -2414,6 +2414,10 @@ ENUM
   BFD_RELOC_V850_TDA_7_7_OFFSET
 ENUMDOC
   This is a 7 bit offset from the tiny data area pointer.
+ENUM
+  BFD_RELOC_V850_TDA_16_16_OFFSET
+ENUMDOC
+  This is a 16 bit offset from the tiny data area pointer.
 COMMENT
 {* start-sanitize-v850e *}
 ENUM
-- 
cgit v1.1