[PATCH] Remove the stripped group section from linker output

Alan Modra amodra@gmail.com
Tue Feb 13 09:58:00 GMT 2018


On Tue, Feb 13, 2018 at 06:12:34PM +1030, Alan Modra wrote:
> On Mon, Feb 12, 2018 at 08:06:29PM -0800, H.J. Lu wrote:
> > Like this?
> 
> Yes, but I'm wondering now if this is really the correct patch.  We
> have _bfd_elf_fixup_group_sections which is supposed to adjust
> SHT_GROUP size when group member sections are discarded.  If the size
> went down to 4, then you could set SEC_EXCLUDE for the SHT_GROUP
> section.
> 
> However, it looks like that function doesn't handle group sections
> with relocs properly.  Fixing that isn't hard, but then I run into
> other problems when setting SEC_EXCLUDE.  :-(
> 
> So I guess you might as well commit your patch, and when/if I sort out
> the other problems I'll remove is_discarded_group.

This is what I'm currently testing.  I intend to add some objcopy
and ld -r tests that check full and partial removal of group sections.

	* elf.c (_bfd_elf_fixup_group_sections): Account for removed
	relocation sections.  If size reduces to just the flag word,
	remove that too and mark with SEC_EXCLUDE.
	* elflink.c (bfd_elf_final_link): Strip empty group sections.

diff --git a/bfd/elf.c b/bfd/elf.c
index 0503154..934052d 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -7604,7 +7604,16 @@ _bfd_elf_fixup_group_sections (bfd *ibfd, asection *discarded)
 	       but the SHT_GROUP section is, then adjust its size.  */
 	    else if (s->output_section == discarded
 		     && isec->output_section != discarded)
-	      removed += 4;
+	      {
+		struct bfd_elf_section_data *elf_sec = elf_section_data (s);
+		removed += 4;
+		if (elf_sec->rel.hdr != NULL
+		    && (elf_sec->rel.hdr->sh_flags & SHF_GROUP) != 0)
+		  removed += 4;
+		if (elf_sec->rela.hdr != NULL
+		    && (elf_sec->rela.hdr->sh_flags & SHF_GROUP) != 0)
+		  removed += 4;
+	      }
 	    s = elf_next_in_group (s);
 	    if (s == first)
 	      break;
@@ -7614,18 +7623,26 @@ _bfd_elf_fixup_group_sections (bfd *ibfd, asection *discarded)
 	    if (discarded != NULL)
 	      {
 		/* If we've been called for ld -r, then we need to
-		   adjust the input section size.  This function may
-		   be called multiple times, so save the original
-		   size.  */
+		   adjust the input section size.  */
 		if (isec->rawsize == 0)
 		  isec->rawsize = isec->size;
 		isec->size = isec->rawsize - removed;
+		if (isec->size <= 4)
+		  {
+		    isec->size = 0;
+		    isec->flags |= SEC_EXCLUDE;
+		  }
 	      }
 	    else
 	      {
 		/* Adjust the output section size when called from
 		   objcopy. */
 		isec->output_section->size -= removed;
+		if (isec->output_section->size <= 4)
+		  {
+		    isec->output_section->size = 0;
+		    isec->output_section->flags |= SEC_EXCLUDE;
+		  }
 	      }
 	  }
       }
diff --git a/bfd/elflink.c b/bfd/elflink.c
index d1eb820..6eb47ee 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -11618,6 +11618,13 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 	  else
 	    o->flags |= SEC_EXCLUDE;
 	}
+      else if ((o->flags & SEC_GROUP) != 0 && o->size == 0)
+	{
+	  /* Remove empty group section from linker output.  */
+	  o->flags |= SEC_EXCLUDE;
+	  bfd_section_list_remove (abfd, o);
+	  abfd->section_count--;
+	}
     }
 
   /* Count up the number of relocations we will output for each output

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list