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

H. J. Lu hjl@lucon.org
Wed May 4 19:53:00 GMT 2005


The recent linker change makes this bug easier to fix. Here is an
updated patch.


H.J.
---
bfd/

2005-05-04  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-05-04  H.J. Lu  <hongjiu.lu@intel.com>

	PR 797
	* ldlang.c (lang_output_section_statement_lookup_1): Set the
	ignored field to FALSE.
	(strip_unused_output_sections): New.
	(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_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-05-04 08:52:10.000000000 -0700
+++ binutils/bfd/elf32-i386.c	2005-05-04 10:08:02.000000000 -0700
@@ -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-05-04 08:52:16.000000000 -0700
+++ binutils/bfd/elf64-x86-64.c	2005-05-04 10:08:02.000000000 -0700
@@ -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-05-04 08:52:34.000000000 -0700
+++ binutils/ld/ldlang.c	2005-05-04 11:03:09.000000000 -0700
@@ -1022,6 +1022,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);
@@ -3084,6 +3085,41 @@ strip_excluded_output_sections (void)
   stripped_excluded_sections = TRUE;
 }
 
+/* An output section might have been removed after its statement was
+   added if it isn't used at all. Clean them up here.  */
+
+static void
+strip_unused_output_sections (void)
+{
+  lang_output_section_statement_type *os;
+
+  for (os = &lang_output_section_statement.head->output_section_statement;
+       os != NULL;
+       os = os->next)
+    {
+      asection *s;
+
+      if (os->constraint == -1)
+	continue;
+
+      s = os->bfd_section;
+
+      if (s != NULL
+	  && s->linker_has_input == 0
+	  && (s->flags & (SEC_KEEP | SEC_HAS_CONTENTS)) == 0)
+	{
+	  /* We don't set bfd_section to NULL since bfd_section of the
+	     removed output section statement may still be used.  */
+	  os->ignored = TRUE;
+	  if (!bfd_section_removed_from_list (output_bfd, s))
+	    {
+	      bfd_section_list_remove (output_bfd, s);
+	      output_bfd->section_count--;
+	    }
+	}
+    }
+}
+
 static void
 print_output_section_statement
   (lang_output_section_statement_type *output_section_statement)
@@ -3855,8 +3891,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
@@ -4351,7 +4387,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);
@@ -4365,7 +4401,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",
@@ -5301,9 +5337,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_unused_output_sections ();
+	}
       lang_reset_memory_regions ();
       lang_size_sections (statement_list.head, abs_output_section,
 			  &statement_list.head, 0, 0, NULL, TRUE);
@@ -5327,7 +5373,7 @@ lang_process (void)
     lang_check_section_addresses ();
 
   /* Final stuffs.  */
-  lang_mark_used_section ();
+
   ldemul_finish ();
   lang_finish ();
 }
--- binutils/ld/ldlang.h.empty	2005-05-04 08:52:34.000000000 -0700
+++ binutils/ld/ldlang.h	2005-05-04 10:36:53.000000000 -0700
@@ -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