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

Re: PATCH: BZ/175: Fix dynamic string offset


On Thu, May 20, 2004 at 08:30:24PM -0700, H. J. Lu wrote:
> On Fri, May 21, 2004 at 10:55:03AM +0930, Alan Modra wrote:
> > I think it quite possible that this patch will break other accesses
> > into merged sections.  To properly fix the problem, you would need to
> > distinguish this particular access from others.  Perhaps the reloc used
> > might give you enough information.
> 
> Good idea. Here it is.

> 	* elfxx-ia64.c (elfNN_ia64_relax_section): Call
> 	_bfd_merged_section_offset with irel->r_addend as dynamic
> 	offset if it isn't a branch.

I doubt this patch is complete.  If you need to special case certain
accesses in relax_section, how is it that relocate_section escapes a
need for the same special case code?  This might prove more difficult,
as you might need to pull apart _bfd_elf_rela_local_sym.  I'm also still
concerned that other ia64 code sequences might use R_IA64_LTOFF22X in a
way that requires you include the addend.  Please discuss this with Jim,
I'm not familiar enough with ia64 to know.

> 	* merge.c (merged_section_offset): New. Modified from
> 	_bfd_merged_section_offset.
> 	(_bfd_merged_section_offset): Use it. Handle dynamic offset.

I think we should remove "addend" from _bfd_merged_section_offset.  It
only serves to confuse the real purpose of the function, which is to
return where a data item in a SEC_MERGE section is finally located.

	* merge.c (_bfd_merged_section_offset): Remove "addend" param.
	* libbfd-in.h (_bfd_merged_section_offset): Adjust prototype.
	* libbfd.h: Regenerate.
	* elf.c (_bfd_elf_rela_local_sym): Adjust call.
	(_bfd_elf_rel_local_sym): Likewise.
	* elflink.c (_bfd_elf_link_sec_merge_syms): Likewise.
	(elf_link_input_bfd): Likewise.
	* elf32-ppc.c (ppc_elf_relax_section): Likewise.
	* elf64-alpha.c (elf64_alpha_relocate_section): Likewise.
	* elfxx-ia64.c (elfNN_ia64_relax_section): Likewise.
	(elfNN_ia64_relocate_section): Likewise.

When making this diff, I saw I somehow didn't commit the elf.c change
corresponding to the following ChangLog entry.  So I'm belatedly
committing that too.

2004-05-03  Alan Modra  <amodra@bigpond.net.au>

	* elf.c (_bfd_elf_rela_local_sym): Set kept_section for excluded
	SEC_MERGE sections.
	* elflink.c (elf_link_input_bfd): Adjust output reloc index for
	those against discarded link-once and SEC_MERGE section symbols.


Index: bfd/merge.c
===================================================================
RCS file: /cvs/src/src/bfd/merge.c,v
retrieving revision 1.18
diff -u -p -r1.18 merge.c
--- bfd/merge.c	29 Oct 2003 22:59:37 -0000	1.18
+++ bfd/merge.c	22 May 2004 01:32:23 -0000
@@ -780,7 +780,7 @@ _bfd_write_merged_section (bfd *output_b
 
 bfd_vma
 _bfd_merged_section_offset (bfd *output_bfd ATTRIBUTE_UNUSED, asection **psec,
-			    void *psecinfo, bfd_vma offset, bfd_vma addend)
+			    void *psecinfo, bfd_vma offset)
 {
   struct sec_merge_sec_info *secinfo;
   struct sec_merge_hash_entry *entry;
@@ -789,13 +789,13 @@ _bfd_merged_section_offset (bfd *output_
 
   secinfo = (struct sec_merge_sec_info *) psecinfo;
 
-  if (offset + addend >= sec->_raw_size)
+  if (offset >= sec->_raw_size)
     {
-      if (offset + addend > sec->_raw_size)
+      if (offset > sec->_raw_size)
 	{
 	  (*_bfd_error_handler)
-	    (_("%s: access beyond end of merged section (%ld + %ld)"),
-	     bfd_get_filename (sec->owner), (long) offset, (long) addend);
+	    (_("%s: access beyond end of merged section (%ld)"),
+	     bfd_get_filename (sec->owner), (long) offset);
 	}
       return (secinfo->first ? sec->_cooked_size : 0);
     }
@@ -804,15 +804,14 @@ _bfd_merged_section_offset (bfd *output_
     {
       if (sec->entsize == 1)
 	{
-	  p = secinfo->contents + offset + addend - 1;
+	  p = secinfo->contents + offset - 1;
 	  while (p >= secinfo->contents && *p)
 	    --p;
 	  ++p;
 	}
       else
 	{
-	  p = secinfo->contents
-	      + ((offset + addend) / sec->entsize) * sec->entsize;
+	  p = secinfo->contents + (offset / sec->entsize) * sec->entsize;
 	  p -= sec->entsize;
 	  while (p >= secinfo->contents)
 	    {
@@ -830,8 +829,7 @@ _bfd_merged_section_offset (bfd *output_
     }
   else
     {
-      p = secinfo->contents
-	  + ((offset + addend) / sec->entsize) * sec->entsize;
+      p = secinfo->contents + (offset / sec->entsize) * sec->entsize;
     }
   entry = sec_merge_hash_lookup (secinfo->htab, p, 0, FALSE);
   if (!entry)
@@ -845,9 +843,8 @@ _bfd_merged_section_offset (bfd *output_
       if (! secinfo->htab->first)
 	abort ();
       entry = secinfo->htab->first;
-      p = secinfo->contents
-	  + ((offset + addend) / sec->entsize + 1) * sec->entsize
-	  - entry->len;
+      p = (secinfo->contents + (offset / sec->entsize + 1) * sec->entsize
+	   - entry->len);
     }
 
   *psec = entry->secinfo->sec;
Index: bfd/libbfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/libbfd-in.h,v
retrieving revision 1.34
diff -u -p -r1.34 libbfd-in.h
--- bfd/libbfd-in.h	17 May 2004 16:40:00 -0000	1.34
+++ bfd/libbfd-in.h	22 May 2004 01:32:23 -0000
@@ -538,7 +538,7 @@ extern bfd_boolean _bfd_write_merged_sec
 /* Find an offset within a modified SEC_MERGE section.  */
 
 extern bfd_vma _bfd_merged_section_offset
-  (bfd *, asection **, void *, bfd_vma, bfd_vma);
+  (bfd *, asection **, void *, bfd_vma);
 
 /* Create a string table.  */
 extern struct bfd_strtab_hash *_bfd_stringtab_init
Index: bfd/elf.c
===================================================================
RCS file: /cvs/src/src/bfd/elf.c,v
retrieving revision 1.226
diff -u -p -r1.226 elf.c
--- bfd/elf.c	17 May 2004 16:40:00 -0000	1.226
+++ bfd/elf.c	22 May 2004 01:32:27 -0000
@@ -7537,9 +7537,18 @@ _bfd_elf_rela_local_sym (bfd *abfd,
       rel->r_addend =
 	_bfd_merged_section_offset (abfd, psec,
 				    elf_section_data (sec)->sec_info,
-				    sym->st_value + rel->r_addend,
-				    0);
-      sec = *psec;
+				    sym->st_value + rel->r_addend);
+      if (sec != *psec)
+	{
+	  /* If we have changed the section, and our original section is
+	     marked with SEC_EXCLUDE, it means that the original
+	     SEC_MERGE section has been completely subsumed in some
+	     other SEC_MERGE section.  In this case, we need to leave
+	     some info around for --emit-relocs.  */
+	  if ((sec->flags & SEC_EXCLUDE) != 0)
+	    sec->kept_section = *psec;
+	  sec = *psec;
+	}
       rel->r_addend -= relocation;
       rel->r_addend += sec->output_section->vma + sec->output_offset;
     }
@@ -7559,7 +7568,7 @@ _bfd_elf_rel_local_sym (bfd *abfd,
 
   return _bfd_merged_section_offset (abfd, psec,
 				     elf_section_data (sec)->sec_info,
-				     sym->st_value + addend, 0);
+				     sym->st_value + addend);
 }
 
 bfd_vma
Index: bfd/elflink.c
===================================================================
RCS file: /cvs/src/src/bfd/elflink.c,v
retrieving revision 1.69
diff -u -p -r1.69 elflink.c
--- bfd/elflink.c	11 May 2004 17:08:37 -0000	1.69
+++ bfd/elflink.c	22 May 2004 01:32:34 -0000
@@ -2362,7 +2362,7 @@ _bfd_elf_link_sec_merge_syms (struct elf
 	_bfd_merged_section_offset (output_bfd,
 				    &h->root.u.def.section,
 				    elf_section_data (sec)->sec_info,
-				    h->root.u.def.value, 0);
+				    h->root.u.def.value);
     }
 
   return TRUE;
@@ -6392,7 +6392,7 @@ elf_link_input_bfd (struct elf_final_lin
 	    isym->st_value =
 	      _bfd_merged_section_offset (output_bfd, &isec,
 					  elf_section_data (isec)->sec_info,
-					  isym->st_value, 0);
+					  isym->st_value);
 	}
       else if (isym->st_shndx == SHN_ABS)
 	isec = bfd_abs_section_ptr;
Index: bfd/elf32-ppc.c
===================================================================
RCS file: /cvs/src/src/bfd/elf32-ppc.c,v
retrieving revision 1.118
diff -u -p -r1.118 elf32-ppc.c
--- bfd/elf32-ppc.c	22 Apr 2004 14:45:31 -0000	1.118
+++ bfd/elf32-ppc.c	22 May 2004 01:32:35 -0000
@@ -1811,7 +1811,7 @@ ppc_elf_relax_section (bfd *abfd,
       if (tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
 	toff = _bfd_merged_section_offset (abfd, &tsec,
 					   elf_section_data (tsec)->sec_info,
-					   toff, 0);
+					   toff);
 
       symaddr = tsec->output_section->vma + tsec->output_offset + toff;
 
Index: bfd/elf64-alpha.c
===================================================================
RCS file: /cvs/src/src/bfd/elf64-alpha.c,v
retrieving revision 1.118
diff -u -p -r1.118 elf64-alpha.c
--- bfd/elf64-alpha.c	27 Apr 2004 03:13:14 -0000	1.118
+++ bfd/elf64-alpha.c	22 May 2004 01:32:38 -0000
@@ -4381,8 +4381,7 @@ elf64_alpha_relocate_section (output_bfd
 		    _bfd_merged_section_offset (output_bfd, &msec,
 						elf_section_data (sec)->
 						  sec_info,
-						sym->st_value + ent->addend,
-						(bfd_vma) 0);
+						sym->st_value + ent->addend);
 		  ent->addend -= sym->st_value;
 		  ent->addend += msec->output_section->vma
 				 + msec->output_offset
Index: bfd/elfxx-ia64.c
===================================================================
RCS file: /cvs/src/src/bfd/elfxx-ia64.c,v
retrieving revision 1.126
diff -u -p -r1.126 elfxx-ia64.c
--- bfd/elfxx-ia64.c	27 Apr 2004 03:13:15 -0000	1.126
+++ bfd/elfxx-ia64.c	22 May 2004 01:32:40 -0000
@@ -913,8 +913,7 @@ elfNN_ia64_relax_section (abfd, sec, lin
       if (tsec->sec_info_type == ELF_INFO_TYPE_MERGE)
 	toff = _bfd_merged_section_offset (abfd, &tsec,
 					   elf_section_data (tsec)->sec_info,
-					   toff + irel->r_addend,
-					   (bfd_vma) 0);
+					   toff + irel->r_addend);
       else
 	toff += irel->r_addend;
 
@@ -3963,8 +3962,7 @@ elfNN_ia64_relocate_section (output_bfd,
 						    elf_section_data (msec)->
 						    sec_info,
 						    sym->st_value
-						    + dynent->addend,
-						    (bfd_vma) 0);
+						    + dynent->addend);
 		      dynent->addend -= sym->st_value;
 		      dynent->addend += msec->output_section->vma
 					+ msec->output_offset

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre


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