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]

fix frv eh_frame relaxation bug


elf-eh-frame.c removes CIEs that are redundant with previous CIEs, and
this requires the relocation for __gxx_personality_v0 to be dropped as
well.

However, the relocation code failed to take into account the
possibility of this kind of relaxation, and used the result of
_bfd_elf_section_offset() without testing whether it's -1, which
indicates that (re)location is to be dropped entirely because the
underlying construct was removed.

AFAICT we've already taken care of ensuring it would never be -2
(cross-segment relocations don't work), so this should be good enough.

I'm checking it in.  Tested by building a functional libstdc++.so.6
(EH wouldn't work at all before the patch.)

Index: bfd/ChangeLog
from  Alexandre Oliva  <aoliva@redhat.com>

	* elf32-frv.c (elf32_frv_relocate_section): Discard dynamic relocs
	for which _bfd_elf_section_offset returns -1.

Index: bfd/elf32-frv.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-frv.c,v
retrieving revision 1.52
diff -u -p -r1.52 elf32-frv.c
--- bfd/elf32-frv.c 26 Apr 2007 14:46:56 -0000 1.52
+++ bfd/elf32-frv.c 8 May 2007 06:05:17 -0000
@@ -3644,6 +3644,8 @@ elf32_frv_relocate_section (output_bfd, 
 						input_section->output_section)
 			 & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
 		      {
+			bfd_vma offset;
+
 			if (_frvfdpic_osec_readonly_p (output_bfd,
 						       input_section
 						       ->output_section))
@@ -3654,22 +3656,27 @@ elf32_frv_relocate_section (output_bfd, 
 			       name, input_bfd, input_section, rel->r_offset);
 			    return FALSE;
 			  }
-			_frvfdpic_add_rofixup (output_bfd,
-					       frvfdpic_gotfixup_section
-					       (info),
-					       _bfd_elf_section_offset
-					       (output_bfd, info,
-						input_section, rel->r_offset)
-					       + input_section
-					       ->output_section->vma
-					       + input_section->output_offset,
-					       picrel);
+
+			offset = _bfd_elf_section_offset
+			  (output_bfd, info,
+			   input_section, rel->r_offset);
+
+			if (offset != (bfd_vma)-1)
+			  _frvfdpic_add_rofixup (output_bfd,
+						 frvfdpic_gotfixup_section
+						 (info),
+						 offset + input_section
+						 ->output_section->vma
+						 + input_section->output_offset,
+						 picrel);
 		      }
 		  }
 		else if ((bfd_get_section_flags (output_bfd,
 						 input_section->output_section)
 			  & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
 		  {
+		    bfd_vma offset;
+
 		    if (_frvfdpic_osec_readonly_p (output_bfd,
 						   input_section
 						   ->output_section))
@@ -3680,15 +3687,18 @@ elf32_frv_relocate_section (output_bfd, 
 			   name, input_bfd, input_section, rel->r_offset);
 			return FALSE;
 		      }
-		    _frvfdpic_add_dyn_reloc (output_bfd,
-					     frvfdpic_gotrel_section (info),
-					     _bfd_elf_section_offset
-					     (output_bfd, info,
-					      input_section, rel->r_offset)
-					     + input_section
-					     ->output_section->vma
-					     + input_section->output_offset,
-					     r_type, dynindx, addend, picrel);
+
+		    offset = _bfd_elf_section_offset
+		      (output_bfd, info,
+		       input_section, rel->r_offset);
+
+		    if (offset != (bfd_vma)-1)
+		      _frvfdpic_add_dyn_reloc (output_bfd,
+					       frvfdpic_gotrel_section (info),
+					       offset + input_section
+					       ->output_section->vma
+					       + input_section->output_offset,
+					       r_type, dynindx, addend, picrel);
 		  }
 		else
 		  addend += frvfdpic_got_section (info)->output_section->vma;
@@ -3769,25 +3779,27 @@ elf32_frv_relocate_section (output_bfd, 
 		      }
 		    if (!h || h->root.type != bfd_link_hash_undefweak)
 		      {
-			_frvfdpic_add_rofixup (output_bfd,
-					       frvfdpic_gotfixup_section
-					       (info),
-					       _bfd_elf_section_offset
-					       (output_bfd, info,
-						input_section, rel->r_offset)
-					       + input_section
-					       ->output_section->vma
-					       + input_section->output_offset,
-					       picrel);
-			if (r_type == R_FRV_FUNCDESC_VALUE)
-			  _frvfdpic_add_rofixup
-			    (output_bfd,
-			     frvfdpic_gotfixup_section (info),
-			     _bfd_elf_section_offset
-			     (output_bfd, info,
-			      input_section, rel->r_offset)
-			     + input_section->output_section->vma
-			     + input_section->output_offset + 4, picrel);
+			bfd_vma offset = _bfd_elf_section_offset
+			  (output_bfd, info,
+			   input_section, rel->r_offset);
+
+			if (offset != (bfd_vma)-1)
+			  {
+			    _frvfdpic_add_rofixup (output_bfd,
+						   frvfdpic_gotfixup_section
+						   (info),
+						   offset + input_section
+						   ->output_section->vma
+						   + input_section->output_offset,
+						   picrel);
+			    if (r_type == R_FRV_FUNCDESC_VALUE)
+			      _frvfdpic_add_rofixup
+				(output_bfd,
+				 frvfdpic_gotfixup_section (info),
+				 offset
+				 + input_section->output_section->vma
+				 + input_section->output_offset + 4, picrel);
+			  }
 		      }
 		  }
 	      }
@@ -3797,6 +3809,8 @@ elf32_frv_relocate_section (output_bfd, 
 					    input_section->output_section)
 		     & (SEC_ALLOC | SEC_LOAD)) == (SEC_ALLOC | SEC_LOAD))
 		  {
+		    bfd_vma offset;
+
 		    if (_frvfdpic_osec_readonly_p (output_bfd,
 						   input_section
 						   ->output_section))
@@ -3807,15 +3821,18 @@ elf32_frv_relocate_section (output_bfd, 
 			   name, input_bfd, input_section, rel->r_offset);
 			return FALSE;
 		      }
-		    _frvfdpic_add_dyn_reloc (output_bfd,
-					     frvfdpic_gotrel_section (info),
-					     _bfd_elf_section_offset
-					     (output_bfd, info,
-					      input_section, rel->r_offset)
-					     + input_section
-					     ->output_section->vma
-					     + input_section->output_offset,
-					     r_type, dynindx, addend, picrel);
+
+		    offset = _bfd_elf_section_offset
+		      (output_bfd, info,
+		       input_section, rel->r_offset);
+
+		    if (offset != (bfd_vma)-1)
+		      _frvfdpic_add_dyn_reloc (output_bfd,
+					       frvfdpic_gotrel_section (info),
+					       offset + input_section
+					       ->output_section->vma
+					       + input_section->output_offset,
+					       r_type, dynindx, addend, picrel);
 		  }
 		else if (osec)
 		  addend += osec->output_section->vma;
-- 
Alexandre Oliva         http://www.lsd.ic.unicamp.br/~oliva/
FSF Latin America Board Member         http://www.fsfla.org/
Red Hat Compiler Engineer   aoliva@{redhat.com, gcc.gnu.org}
Free Software Evangelist  oliva@{lsd.ic.unicamp.br, gnu.org}

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