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: PR 797: Alignment in empty section changes the output layout


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;
 


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