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] Handle R_M32C_24 specially


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

commit 055173ca8d1dd3d886e88392a7b2c63c5ff20bda
Author: DJ Delorie <dj@redhat.com>
Date:   Thu Jan 22 17:30:58 2015 -0500

    Handle R_M32C_24 specially
    
    2015-01-22  DJ Delorie  <dj@redhat.com>
    
    	* elf32-m32c.c (m32c_apply_reloc_24): New.
    	(m32c_elf_howto_table): Use it for R_M32C_24.
    	(m32c_elf_relocate_section): Handle R_M32C_24 specially.

Diff:
---
 bfd/ChangeLog    |  6 +++++
 bfd/elf32-m32c.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++---
 2 files changed, 77 insertions(+), 4 deletions(-)

diff --git a/bfd/ChangeLog b/bfd/ChangeLog
index bd2f0c1..e3a428a 100644
--- a/bfd/ChangeLog
+++ b/bfd/ChangeLog
@@ -1,3 +1,9 @@
+2015-01-22  DJ Delorie  <dj@redhat.com>
+
+	* elf32-m32c.c (m32c_apply_reloc_24): New.
+	(m32c_elf_howto_table): Use it for R_M32C_24.
+	(m32c_elf_relocate_section): Handle R_M32C_24 specially.
+
 2015-01-22  Nick Clifton  <nickc@redhat.com>
 
 	PR binutils/17512
diff --git a/bfd/elf32-m32c.c b/bfd/elf32-m32c.c
index cbc1765..7572581 100644
--- a/bfd/elf32-m32c.c
+++ b/bfd/elf32-m32c.c
@@ -40,6 +40,8 @@ void dump_symtab (bfd *, void *, void *);
 #endif
 static bfd_boolean m32c_elf_relax_section
 (bfd *abfd, asection *sec, struct bfd_link_info *link_info, bfd_boolean *again);
+static bfd_reloc_status_type m32c_apply_reloc_24
+  (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
 
 
 static reloc_howto_type m32c_elf_howto_table [] =
@@ -83,7 +85,7 @@ static reloc_howto_type m32c_elf_howto_table [] =
 	 FALSE,			/* pc_relative */
 	 0,			/* bitpos */
 	 complain_overflow_dont, /* complain_on_overflow */
-	 bfd_elf_generic_reloc,	/* special_function */
+	 m32c_apply_reloc_24,	/* special_function */
 	 "R_M32C_24",		/* name */
 	 FALSE,			/* partial_inplace */
 	 0,			/* src_mask */
@@ -307,6 +309,48 @@ m32c_info_to_howto_rela
 
 
 
+/* Apply R_M32C_24 relocations.  We have to do this because it's not a
+   power-of-two size, and the generic code may think it overruns the
+   section if it's right at the end.
+
+   Must return something other than bfd_reloc_continue to avoid the
+   above problem.  Typical return values include bfd_reloc_ok or
+   bfd_reloc_overflow.
+*/
+
+static bfd_reloc_status_type m32c_apply_reloc_24 (bfd *abfd ATTRIBUTE_UNUSED,
+						  arelent *reloc_entry,
+						  asymbol *symbol,
+						  void *vdata_start ATTRIBUTE_UNUSED,
+						  asection *input_section,
+						  bfd *ibfd ATTRIBUTE_UNUSED,
+						  char **error_msg ATTRIBUTE_UNUSED)
+{
+  bfd_vma relocation;
+  bfd_reloc_status_type s;
+
+  s = bfd_elf_generic_reloc (abfd, reloc_entry, symbol,
+			     vdata_start,
+			     input_section, ibfd, error_msg);
+  if (s != bfd_reloc_continue)
+    return s;
+
+  /* Get symbol value.  (Common symbols are special.)  */
+  if (bfd_is_com_section (symbol->section))
+    relocation = 0;
+  else
+    relocation = symbol->value;
+
+  relocation += symbol->section->output_offset;
+
+  /* Add in supplied addend.  */
+  relocation += reloc_entry->addend;
+
+  reloc_entry->addend = relocation;
+  reloc_entry->address += input_section->output_offset;
+  return bfd_reloc_ok;
+}
+
 /* Relocate an M32C ELF section.
    There is some attempt to make this function usable for many architectures,
    both USE_REL and USE_RELA ['twould be nice if such a critter existed],
@@ -535,9 +579,32 @@ m32c_elf_relocate_section
 	printf ("\n");
       }
 #endif
-      r = _bfd_final_link_relocate (howto, input_bfd, input_section,
-                                    contents, rel->r_offset, relocation,
-                                    rel->r_addend);
+      switch (ELF32_R_TYPE(rel->r_info))
+	{
+	case R_M32C_24:
+	  /* Like m32c_apply_reloc_24, we must handle this one separately.  */
+	  relocation += rel->r_addend;
+
+	  /* Sanity check the address.  */
+	  if (rel->r_offset + 3
+	      > bfd_get_section_limit_octets (input_bfd, input_section))
+	    r = bfd_reloc_outofrange;
+	  else
+	    {
+	      bfd_put_8 (input_bfd, relocation & 0xff, contents + rel->r_offset);
+	      bfd_put_8 (input_bfd, (relocation >> 8) & 0xff, contents + rel->r_offset + 1);
+	      bfd_put_8 (input_bfd, (relocation >> 16) & 0xff, contents + rel->r_offset + 2);
+	      r = bfd_reloc_ok;
+	    }
+
+	  break;
+
+	default:
+	  r = _bfd_final_link_relocate (howto, input_bfd, input_section,
+					contents, rel->r_offset, relocation,
+					rel->r_addend);
+	  break;
+	}
 
       if (r != bfd_reloc_ok)
 	{


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