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

[iq2000] jump, merge patches


Two random iq2000 patches we've been carrying around internally.  The
first is something we've been doing to many ports - compensating for
merged symbol motion.  The second checks for jump overflow that we
weren't checking for before.

Tested against gcc's testsuite and binutils' testsuite, no regressions
(and some new passes) other than the new jump checks that we silently
ignored before.

Ok?

	* elf32-iq2000.c (iq2000_elf_relocate_section): Adjust addend of
	relocation pointing to local symbol in merged section.

	* elf32-iq2000.c (iq2000_elf_relocate_offset16): New.
	(iq2000_elf_relocate_section): Call it.

Index: bfd/elf32-iq2000.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-iq2000.c,v
retrieving revision 1.24
diff -p -U3 -r1.24  bfd/elf32-iq2000.c
--- bfd/elf32-iq2000.c	28 Sep 2007 08:43:45 -0000	1.24
+++ bfd/elf32-iq2000.c	11 Feb 2008 22:14:11 -0000
@@ -306,6 +306,34 @@ iq2000_elf_relocate_hi16 (bfd *input_bfd
   return bfd_reloc_ok;
 }
 
+static bfd_reloc_status_type
+iq2000_elf_relocate_offset16 (bfd *input_bfd,
+			      Elf_Internal_Rela *rel,
+			      bfd_byte *contents,
+			      bfd_vma value,
+			      bfd_vma location)
+{
+  bfd_vma insn;
+  bfd_vma jtarget;
+
+  insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
+
+  value += rel->r_addend;
+
+  if (value & 3)
+    return bfd_reloc_dangerous;
+
+  jtarget = (value & 0x3fffc) | (location & 0xf0000000L);
+
+  if (jtarget != value)
+    return bfd_reloc_overflow;
+
+  insn = (insn & ~0xFFFF) | ((value >> 2) & 0xFFFF);
+
+  bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
+  return bfd_reloc_ok;
+}
+
 /* Map BFD reloc types to IQ2000 ELF reloc types.  */
 
 static reloc_howto_type *
@@ -572,15 +600,25 @@ iq2000_elf_relocate_section (bfd *		    
       
       if (r_symndx < symtab_hdr->sh_info)
 	{
+	  asection *osec;
+
 	  sym = local_syms + r_symndx;
-	  sec = local_sections [r_symndx];
+	  osec = sec = local_sections [r_symndx];
+	  if ((sec->flags & SEC_MERGE)
+	      && ELF_ST_TYPE (sym->st_info) == STT_SECTION)
+	    /* This relocation is relative to a section symbol that is
+	       going to be merged.  Change it so that it is relative
+	       to the merged section symbol.  */
+	    rel->r_addend = _bfd_elf_rel_local_sym (output_bfd, sym, &sec,
+						    rel->r_addend);
+
 	  relocation = (sec->output_section->vma
 			+ sec->output_offset
 			+ sym->st_value);
 	  
 	  name = bfd_elf_string_from_elf_section
 	    (input_bfd, symtab_hdr->sh_link, sym->st_name);
-	  name = (name == NULL) ? bfd_section_name (input_bfd, sec) : name;
+	  name = (name == NULL) ? bfd_section_name (input_bfd, osec) : name;
 	}
       else
 	{
@@ -615,6 +653,13 @@ iq2000_elf_relocate_section (bfd *		    
 	  r = iq2000_elf_relocate_hi16 (input_bfd, rel, contents, relocation);
 	  break;
 
+	case R_IQ2000_OFFSET_16:
+	  r = iq2000_elf_relocate_offset16 (input_bfd, rel, contents, relocation,
+					    input_section->output_section->vma
+					    + input_section->output_offset
+					    + rel->r_offset);
+	  break;
+
 	case R_IQ2000_PC16:
 	  rel->r_addend -= 4;
 	  /* Fall through.  */


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