PATCH: PR 797: Alignment in empty section changes the output layout

H. J. Lu hjl@lucon.org
Wed Mar 30 16:30:00 GMT 2005


On Tue, Mar 29, 2005 at 12:29:59PM +0930, Alan Modra wrote:
> On Mon, Mar 28, 2005 at 06:06:31PM -0800, H. J. Lu wrote:
> > On Tue, Mar 29, 2005 at 08:12:31AM +0930, Alan Modra wrote:
> > > On Thu, Mar 24, 2005 at 02:05:56PM -0800, H. J. Lu wrote:
> > > > +	 So we remove the unused output sections without input sections
> > > > +	 and the empty unused output sections created by linker, if
> > > > +	 they don't have any contents.  */
> > > 
> > > Is it possible to do this in strip_excluded_output_sections?  You won't
> > > have sizes set at that stage, but linker_has_input will be set, as will
> > > SEC_HAS_CONTENTS from link script data statements.  So I think most of
> > 
> > But SEC_KEEP may not be set before lang_mark_used_section.
> > 
> > > what you're trying to achieve can be done there.  SEC_LINKER_CREATED
> > > sections ought to be handled by the backend size_dynamic_sections
> > > function calling _bfd_strip_section_from_output.
> > 
> > Or I can check every output section and call _bfd_strip_section_from_output
> > at the end of bfd_elf_size_dynamic_sections so that I don't have to
> > change every backend.
> 
> No, I think that would be a bad idea.  Most SEC_LINKER_CREATED sections
> are created by the backend code, so the backend code should manage them.
> Otherwise you run the risk of removing sections that some backend wants
> to keep.
> 
> > But _bfd_strip_section_from_output will check
> > every input section. It may be expensive.
> 
> Sure.  Let's fix it.  Perhaps by creating bfd_link_order lists earlier,
> after placing orphans.
> 
> > If I have to do it in
> > gld${EMULATION_NAME}_finish for other sections anyway, why not
> > to remove empty unused linker created sections in a same place.
> 
> I don't really like the idea of removing sections so late in the link
> process.  It's a hack that I allowed because removing excess symbols and
> output sections was desirable, but now you're adding hacks upon hacks. 
> As evidenced by the need for yet another section flag.
> 
> The proper place to remove sections is after the backend
> size_dynamic_sections has run and before space for dynamic symbols is
> allocated.  If you do it that way you'll avoid some unnecessary dynamic
> syms too.
> 

This is an updated patch. The new section flag is needed since I
can't set bfd_section to NULL if it is ever created.


H.J.
---
bfd/

2005-03-29  H.J. Lu  <hongjiu.lu@intel.com>

	PR 797
	* elf32-i386.c (elf_i386_size_dynamic_sections): Also remove
	empty sdynbss section.
	* elf64-x86-64.c (elf64_x86_64_size_dynamic_sections): Likewise.

ld/

2005-03-29  H.J. Lu  <hongjiu.lu@intel.com>

	PR 797
	* ldlang.c (lang_output_section_statement_lookup_1): Set the
	ignored field to FALSE.
	(strip_excluded_output_sections): Renamed to ...
	(strip_excluded_or_unused_output_sections): This. Accept an
	argument to check for unused sections.
	(lang_size_sections_1): Skip an output section if it should
	be ignored.
	(lang_do_assignments_1): Likewise.
	(lang_process): Call strip_excluded_or_unused_output_sections
	to remove unused output sections after lang_mark_used_section.

	* ldlang.h (lang_output_section_statement_type): Change
	all_input_readonly to bitfield. Add ignored.

--- binutils/bfd/elf32-i386.c.empty	2005-02-11 09:28:10.000000000 -0800
+++ binutils/bfd/elf32-i386.c	2005-03-29 12:13:09.000000000 -0800
@@ -1830,7 +1830,8 @@ elf_i386_size_dynamic_sections (bfd *out
 
       if (s == htab->splt
 	  || s == htab->sgot
-	  || s == htab->sgotplt)
+	  || s == htab->sgotplt
+	  || s == htab->sdynbss)
 	{
 	  /* Strip this section if we don't need it; see the
 	     comment below.  */
--- binutils/bfd/elf64-x86-64.c.empty	2005-03-21 13:13:36.000000000 -0800
+++ binutils/bfd/elf64-x86-64.c	2005-03-29 12:13:09.000000000 -0800
@@ -1622,7 +1622,8 @@ elf64_x86_64_size_dynamic_sections (bfd 
 
       if (s == htab->splt
 	  || s == htab->sgot
-	  || s == htab->sgotplt)
+	  || s == htab->sgotplt
+	  || s == htab->sdynbss)
 	{
 	  /* Strip this section if we don't need it; see the
 	     comment below.  */
--- binutils/ld/ldlang.c.empty	2005-03-24 11:13:06.000000000 -0800
+++ binutils/ld/ldlang.c	2005-03-29 13:50:42.351403473 -0800
@@ -637,6 +637,7 @@ lang_output_section_statement_lookup_1 (
       lookup->bfd_section = NULL;
       lookup->processed = 0;
       lookup->constraint = constraint;
+      lookup->ignored = FALSE;
       lookup->sectype = normal_section;
       lookup->addr_tree = NULL;
       lang_list_init (&lookup->children);
@@ -2643,7 +2644,7 @@ map_input_to_output_sections
    sections if they turn out to be not needed.  Clean them up here.  */
 
 static void
-strip_excluded_output_sections (void)
+strip_excluded_or_unused_output_sections (bfd_boolean unused)
 {
   lang_output_section_statement_type *os;
 
@@ -2656,11 +2657,20 @@ strip_excluded_output_sections (void)
       if (os->constraint == -1)
 	continue;
       s = os->bfd_section;
-      if (s != NULL && (s->flags & SEC_EXCLUDE) != 0)
+      if (s != NULL
+	  && ((!unused && (s->flags & SEC_EXCLUDE) != 0)
+	      || (unused
+		  && s->linker_has_input == 0
+		  && (s->flags & (SEC_KEEP | SEC_HAS_CONTENTS)) == 0)))
 	{
 	  asection **p;
 
-	  os->bfd_section = NULL;
+	  /* We don't set bfd_section to NULL since bfd_section of 
+	     the used output section may still be used.  */
+	  if (unused)
+	    os->ignored = TRUE;
+	  else
+	    os->bfd_section = NULL;
 
 	  for (p = &output_bfd->sections; *p; p = &(*p)->next)
 	    if (*p == s)
@@ -3418,8 +3428,8 @@ lang_size_sections_1
 	    lang_output_section_statement_type *os;
 
 	    os = &s->output_section_statement;
-	    if (os->bfd_section == NULL)
-	      /* This section was never actually created.  */
+	    if (os->bfd_section == NULL || os->ignored)
+	      /* This section was removed or never actually created.  */
 	      break;
 
 	    /* If this is a COFF shared library section, use the size and
@@ -3914,7 +3924,7 @@ lang_do_assignments_1
 	    lang_output_section_statement_type *os;
 
 	    os = &(s->output_section_statement);
-	    if (os->bfd_section != NULL)
+	    if (os->bfd_section != NULL && !os->ignored)
 	      {
 		dot = os->bfd_section->vma;
 		lang_do_assignments_1 (os->children.head, os, os->fill, dot);
@@ -3928,7 +3938,7 @@ lang_do_assignments_1
 	      {
 		/* If nothing has been placed into the output section then
 		   it won't have a bfd_section.  */
-		if (os->bfd_section)
+		if (os->bfd_section && !os->ignored)
 		  {
 		    os->bfd_section->lma
 		      = exp_get_abs_int (os->load_base, 0, "load base",
@@ -4819,7 +4829,7 @@ lang_process (void)
   ldemul_before_allocation ();
 
   if (!link_info.relocatable)
-    strip_excluded_output_sections ();
+    strip_excluded_or_unused_output_sections (FALSE);
 
   /* We must record the program headers before we try to fix the
      section positions, since they will affect SIZEOF_HEADERS.  */
@@ -4867,9 +4877,19 @@ lang_process (void)
 	    }
 	}
       while (relax_again);
+    }
 
+  if (command_line.relax || !link_info.relocatable)
+    {
       /* Final extra sizing to report errors.  */
       lang_do_assignments (statement_list.head, abs_output_section, NULL, 0);
+      if (!link_info.relocatable)
+	{
+	  lang_mark_used_section ();
+	  /* Do it here so that the unused output_sections won't affect
+	     memory layout.  */ 
+	  strip_excluded_or_unused_output_sections (TRUE);
+	}
       lang_reset_memory_regions ();
       lang_size_sections (statement_list.head, abs_output_section,
 			  &statement_list.head, 0, 0, NULL, TRUE);
@@ -4893,7 +4913,7 @@ lang_process (void)
     lang_check_section_addresses ();
 
   /* Final stuffs.  */
-  lang_mark_used_section ();
+
   ldemul_finish ();
   lang_finish ();
 }
--- binutils/ld/ldlang.h.empty	2005-03-03 08:56:33.000000000 -0800
+++ binutils/ld/ldlang.h	2005-03-29 12:13:09.000000000 -0800
@@ -147,7 +147,8 @@ typedef struct lang_output_section_state
   int subsection_alignment;	/* Alignment of components.  */
   int section_alignment;	/* Alignment of start of section.  */
   int constraint;
-  bfd_boolean all_input_readonly;
+  unsigned int all_input_readonly : 1;
+  unsigned int ignored : 1; 
 
   union etree_union *load_base;
 



More information about the Binutils mailing list