public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* PATCH: PR 797: Alignment in empty section changes the output layout
@ 2005-05-04 19:53 H. J. Lu
  2005-05-05  3:48 ` Alan Modra
  0 siblings, 1 reply; 17+ messages in thread
From: H. J. Lu @ 2005-05-04 19:53 UTC (permalink / raw)
  To: binutils

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;
 

^ permalink raw reply	[flat|nested] 17+ messages in thread
* PATCH: PR 797: Alignment in empty section changes the output layout
@ 2005-03-24 11:45 H. J. Lu
  2005-03-25  2:22 ` H. J. Lu
  0 siblings, 1 reply; 17+ messages in thread
From: H. J. Lu @ 2005-03-24 11:45 UTC (permalink / raw)
  To: binutils

This patch tries to undo the damange caused by the unused output
sections in linker script by removing them and resizing the remaining
sections.


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

	PR 797
	* emultempl/elf32.em (gld${EMULATION_NAME}_finish): Remove
	the unused output sections without input sections and the empty
	unused output sections created by linker, if they don't have
	any contents. Resize sections.

	* ldlang.c (lang_output_section_statement_lookup_1): Set the
	ignored field to FALSE.
	(lang_size_sections_1): Skip an output section if it should
	be ignored.

	* ldlang.h (lang_output_section_statement_type): Add ignored.

--- ld/emultempl/elf32.em.empty	2005-03-23 11:05:04.000000000 -0800
+++ ld/emultempl/elf32.em	2005-03-23 16:27:44.511115226 -0800
@@ -1472,20 +1472,76 @@ gld${EMULATION_NAME}_finish (void)
   if (!link_info.relocatable)
     {
       lang_output_section_statement_type *os;
+      asection *s, **p;
+      bfd_boolean resize = FALSE;
+
+      /* We want to remove unused output sections and resize the
+	 remaining sections so that any alignment changes caused by
+	 those removed output sections are reverted. Possible unused
+	 output sections are those without input sections or empty.
+	 We can't remove all unused output sections without input
+	 sections since they may be created by linker scripts. We can't
+	 remove all empty unused output sections since they may have
+	 empty input sections whose alignments may affect the memory
+	 layout of output sections which we don't want to change.
+	 
+	 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.  */
 
       for (os = &lang_output_section_statement.head->output_section_statement;
 	   os != NULL;
 	   os = os->next)
 	{
-	  asection *s;
+	  if (os == abs_output_section || os->constraint == -1)
+	    continue;
+	  s = os->bfd_section;
+	  if (s != NULL
+	      && (s->linker_has_input == 0
+		  || (s->size == 0
+		      && (s->flags & SEC_LINKER_CREATED) != 0))
+	      && (s->flags & (SEC_KEEP | SEC_HAS_CONTENTS)) == 0)
+	    {
+	      os->ignored = TRUE;
+	      resize = TRUE;
+
+	      for (p = &output_bfd->sections; *p; p = &(*p)->next)
+		if (*p == s)
+		  {
+		    bfd_section_list_remove (output_bfd, p);
+		    output_bfd->section_count--;
+		    break;
+		  }
+	    }
+	}
+
+      /* Resize to revert the changes from those removed sections.  */
+      if (resize)
+	{
+	  lang_reset_memory_regions ();
+
+	  /* Resize the sections.  */
+	  lang_size_sections (stat_ptr->head, abs_output_section,
+			      &stat_ptr->head, 0, (bfd_vma) 0,
+			      NULL, TRUE);
+
+	  /* Redo special stuff.  */
+	  ldemul_after_allocation ();
+
+	  /* Do the assignments again.  */
+	  lang_do_assignments (stat_ptr->head, abs_output_section,
+			       (fill_type *) 0, (bfd_vma) 0);
+	}
 
+      for (os = &lang_output_section_statement.head->output_section_statement;
+	   os != NULL;
+	   os = os->next)
+	{
 	  if (os == abs_output_section || os->constraint == -1)
 	    continue;
 	  s = os->bfd_section;
 	  if (s != NULL && s->size == 0 && (s->flags & SEC_KEEP) == 0)
 	    {
-	      asection **p;
-
 	      for (p = &output_bfd->sections; *p; p = &(*p)->next)
 		if (*p == s)
 		  {
--- ld/ldlang.c.empty	2005-03-18 06:23:45.000000000 -0800
+++ ld/ldlang.c	2005-03-23 16:03:11.799216976 -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);
@@ -3418,8 +3419,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
--- ld/ldlang.h.empty	2005-03-03 08:56:33.000000000 -0800
+++ ld/ldlang.h	2005-03-23 14:11:11.000000000 -0800
@@ -148,6 +148,7 @@ typedef struct lang_output_section_state
   int section_alignment;	/* Alignment of start of section.  */
   int constraint;
   bfd_boolean all_input_readonly;
+  bfd_boolean ignored; 
 
   union etree_union *load_base;
 

^ permalink raw reply	[flat|nested] 17+ messages in thread

end of thread, other threads:[~2005-05-17 15:10 UTC | newest]

Thread overview: 17+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-05-04 19:53 PATCH: PR 797: Alignment in empty section changes the output layout H. J. Lu
2005-05-05  3:48 ` Alan Modra
2005-05-05  4:52   ` H. J. Lu
2005-05-05  5:35     ` Alan Modra
2005-05-05  5:56       ` H. J. Lu
2005-05-05  6:33         ` Alan Modra
2005-05-05 16:12           ` H. J. Lu
2005-05-06  6:20             ` Alan Modra
2005-05-07 19:16               ` H. J. Lu
2005-05-07 20:08                 ` H. J. Lu
2005-05-17 15:13                   ` Nick Clifton
  -- strict thread matches above, loose matches on Subject: below --
2005-03-24 11:45 H. J. Lu
2005-03-25  2:22 ` H. J. Lu
2005-03-29  4:21   ` Alan Modra
2005-03-29  7:13     ` H. J. Lu
2005-03-29  8:12       ` Alan Modra
2005-03-30 16:30         ` H. J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).