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]

[PATCH] Fix GC and SHF_MERGE interaction (was Re: bfd is broken)


On Fri, Jan 11, 2002 at 11:13:58AM -0800, Geoff Keating wrote:
> That makes sense.  Why do we set SEC_EXCLUDE on this section, if it
> has size 0 anyway and so wouldn't take up any space in the output?

Here is a fix:

It worked before I changed ->stab_info, ->merge_info into ->sec_info_type,
->sec_merge (_bfd_merge_sections was clearing merge_info if it encountered
something (e.g. GC) deleted one of the SEC_MERGE sections), but now it just
cleared it and didn't know there is section info type encoded somewhere.
One solution would be to always check both that
sec_info_type == ELF_INFO_TYPE_MERGE && sec_info != NULL
but IMHO just clearing sec_info_type in this case is better.
Bootstrapped on i386-redhat-linux, no failures, fixes gcsec-1.c.
Ok to commit?

2002-01-14  Jakub Jelinek  <jakub@redhat.com>

	* elflink.h (elf_link_input_bfd): Back out 2002-01-07 change.
	* elf.c (merge_sections_remove_hook): New function.
	(_bfd_elf_merge_sections): Pass it as 3rd argument to
	_bfd_merge_sections.
	* libbfd-in.h (_bfd_merge_sections): Add 3rd argument.
	* libbfd.h: Rebuilt.
	* merge.c (_bfd_merge_sections): Add remove_hook argument.
	Call remove_hook if a SEC_EXCLUDE section is encountered.

--- bfd/elflink.h.jj	Mon Jan 14 17:02:47 2002
+++ bfd/elflink.h	Mon Jan 14 17:44:31 2002
@@ -6375,8 +6375,6 @@ elf_link_input_bfd (finfo, input_bfd)
 	  isec = section_from_elf_index (input_bfd, isym->st_shndx);
 	  if (isec
 	      && elf_section_data (isec)->sec_info_type == ELF_INFO_TYPE_MERGE
-	      && (finfo->info->relocateable
-		  || ! (isec->flags & SEC_EXCLUDE))
 	      && ELF_ST_TYPE (isym->st_info) != STT_SECTION)
 	    isym->st_value =
 	      _bfd_merged_section_offset (output_bfd, &isec,
--- bfd/elf.c.jj	Mon Jan 14 17:02:46 2002
+++ bfd/elf.c	Mon Jan 14 18:17:59 2002
@@ -53,6 +53,7 @@ static boolean swap_out_syms PARAMS ((bf
 static boolean copy_private_bfd_data PARAMS ((bfd *, bfd *));
 static char *elf_read PARAMS ((bfd *, file_ptr, bfd_size_type));
 static boolean setup_group PARAMS ((bfd *, Elf_Internal_Shdr *, asection *));
+static void merge_sections_remove_hook PARAMS ((bfd *, asection *));
 static void elf_fake_sections PARAMS ((bfd *, asection *, PTR));
 static void set_group_contents PARAMS ((bfd *, asection *, PTR));
 static boolean assign_section_numbers PARAMS ((bfd *));
@@ -770,6 +771,20 @@ bfd_elf_generic_reloc (abfd,
   return bfd_reloc_continue;
 }
 
+/* Make sure sec_info_type is cleared if sec_info is cleared too.  */
+
+static void
+merge_sections_remove_hook (abfd, sec)
+     bfd *abfd ATTRIBUTE_UNUSED;
+     asection *sec;
+{
+  struct bfd_elf_section_data *sec_data;
+    
+  sec_data = elf_section_data (sec);
+  BFD_ASSERT (sec_data->sec_info_type == ELF_INFO_TYPE_MERGE);
+  sec_data->sec_info_type = ELF_INFO_TYPE_NONE;
+}
+
 /* Finish SHF_MERGE section merging.  */
 
 boolean
@@ -780,7 +795,8 @@ _bfd_elf_merge_sections (abfd, info)
   if (!is_elf_hash_table (info))
     return false;
   if (elf_hash_table (info)->merge_info)
-    _bfd_merge_sections (abfd, elf_hash_table (info)->merge_info);
+    _bfd_merge_sections (abfd, elf_hash_table (info)->merge_info,
+			 merge_sections_remove_hook);
   return true;
 }
 
--- bfd/libbfd-in.h.jj	Mon Jan 14 17:02:48 2002
+++ bfd/libbfd-in.h	Mon Jan 14 17:50:16 2002
@@ -478,7 +478,7 @@ extern boolean _bfd_merge_section
 /* Attempt to merge SEC_MERGE sections.  */
 
 extern boolean _bfd_merge_sections
-  PARAMS ((bfd *, PTR));
+  PARAMS ((bfd *, PTR, void (*)(bfd *, asection *)));
 
 /* Write out a merged section.  */
 
--- bfd/libbfd.h.jj	Mon Jan 14 17:02:48 2002
+++ bfd/libbfd.h	Mon Jan 14 17:50:28 2002
@@ -483,7 +483,7 @@ extern boolean _bfd_merge_section
 /* Attempt to merge SEC_MERGE sections.  */
 
 extern boolean _bfd_merge_sections
-  PARAMS ((bfd *, PTR));
+  PARAMS ((bfd *, PTR, void (*)(bfd *, asection *)));
 
 /* Write out a merged section.  */
 
--- bfd/merge.c.jj	Fri Oct  5 13:02:24 2001
+++ bfd/merge.c	Mon Jan 14 17:53:10 2002
@@ -771,9 +771,10 @@ alloc_failure:
    with _bfd_merge_section.  */
 
 boolean
-_bfd_merge_sections (abfd, xsinfo)
+_bfd_merge_sections (abfd, xsinfo, remove_hook)
      bfd *abfd ATTRIBUTE_UNUSED;
      PTR xsinfo;
+     void (*remove_hook) PARAMS((bfd *, asection *));
 {
   struct sec_merge_info *sinfo;
 
@@ -792,7 +793,11 @@ _bfd_merge_sections (abfd, xsinfo)
       /* Record the sections into the hash table.  */
       for (secinfo = sinfo->chain; secinfo; secinfo = secinfo->next)
 	if (secinfo->sec->flags & SEC_EXCLUDE)
-	  *secinfo->psecinfo = NULL;
+	  {
+	    *secinfo->psecinfo = NULL;
+	    if (remove_hook)
+	      (*remove_hook) (abfd, secinfo->sec);
+	  }
 	else if (! record_section (sinfo, secinfo))
 	  break;
 


	Jakub


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