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]

pe breakage


My 2001-08-18 change to lang_size_sections wasn't quite complete for
pe-dll.c.  Hopefully this place_orphan merge from elf32.em won't break
pe further.  :-)

ld/ChangeLog
	* pe-dll.c (pe_dll_fill_sections): Correct type of "relax" param
	passed to lang_size_sections.
	(pe_exe_fill_sections): Likewise.
	* emultempl/pe.em (output_prev_sec_find): Copied from elf32.em.
	(gld_${EMULATION_NAME}_place_orphan): Merge from elf32.em.

-- 
Alan Modra

Index: ld/pe-dll.c
===================================================================
RCS file: /cvs/src/src/ld/pe-dll.c,v
retrieving revision 1.24
diff -u -p -r1.24 pe-dll.c
--- pe-dll.c	2001/08/02 23:12:02	1.24
+++ pe-dll.c	2001/08/19 23:34:33
@@ -2361,7 +2361,7 @@ pe_dll_fill_sections (abfd, info)
 
       /* Resize the sections.  */
       lang_size_sections (stat_ptr->head, abs_output_section,
-			  &stat_ptr->head, 0, (bfd_vma) 0, false);
+			  &stat_ptr->head, 0, (bfd_vma) 0, NULL);
 
       /* Redo special stuff.  */
       ldemul_after_allocation ();
@@ -2395,7 +2395,7 @@ pe_exe_fill_sections (abfd, info)
 
       /* Resize the sections.  */
       lang_size_sections (stat_ptr->head, abs_output_section,
-			  &stat_ptr->head, 0, (bfd_vma) 0, false);
+			  &stat_ptr->head, 0, (bfd_vma) 0, NULL);
 
       /* Redo special stuff.  */
       ldemul_after_allocation ();
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.47
diff -u -p -r1.47 pe.em
--- pe.em	2001/08/14 02:01:31	1.47
+++ pe.em	2001/08/19 23:34:36
@@ -108,6 +108,8 @@ static void gld_${EMULATION_NAME}_after_
 static void gld_${EMULATION_NAME}_before_parse PARAMS ((void));
 static void gld_${EMULATION_NAME}_after_parse PARAMS ((void));
 static void gld_${EMULATION_NAME}_before_allocation PARAMS ((void));
+static asection *output_prev_sec_find
+  PARAMS ((lang_output_section_statement_type *));
 static boolean gld_${EMULATION_NAME}_place_orphan
   PARAMS ((lang_input_statement_type *, asection *));
 static char *gld_${EMULATION_NAME}_get_script PARAMS ((int *));
@@ -1405,6 +1407,32 @@ gld_${EMULATION_NAME}_finish ()
 }
 
 
+/* Find the last output section before given output statement.
+   Used by place_orphan.  */
+
+static asection *
+output_prev_sec_find (os)
+     lang_output_section_statement_type *os;
+{
+  asection *s = (asection *) NULL;
+  lang_statement_union_type *u;
+  lang_output_section_statement_type *lookup;
+
+  for (u = lang_output_section_statement.head;
+       u != (lang_statement_union_type *) NULL;
+       u = lookup->next)
+    {
+      lookup = &u->output_section_statement;
+      if (lookup == os)
+	return s;
+
+      if (lookup->bfd_section != NULL && lookup->bfd_section->owner != NULL)
+	s = lookup->bfd_section;
+    }
+
+  return NULL;
+}
+
 /* Place an orphan section.
 
    We use this to put sections in a reasonable place in the file, and
@@ -1455,9 +1483,12 @@ gld_${EMULATION_NAME}_place_orphan (file
   lang_list_init (&add_child);
 
   if (os != NULL
-      && os->bfd_section != NULL
-      && ((s->flags ^ os->bfd_section->flags) & (SEC_LOAD | SEC_ALLOC)) == 0)
+      && (os->bfd_section == NULL
+	  || ((s->flags ^ os->bfd_section->flags)
+	      & (SEC_LOAD | SEC_ALLOC)) == 0))
     {
+      /* We already have an output section statement with this
+	 name, and its bfd section, if any, has compatible flags.  */
       lang_add_section (&add_child, s, os, file);
     }
   else
@@ -1498,7 +1529,7 @@ gld_${EMULATION_NAME}_place_orphan (file
 
       /* Choose a unique name for the section.  This will be needed if
 	 the same section name appears in the input file with
-	 different loadable or allocateable characteristics.  */
+	 different loadable or allocatable characteristics.  */
       outsecname = xstrdup (hold_section_name);
       if (bfd_get_section_by_name (output_bfd, outsecname) != NULL)
 	{
@@ -1590,28 +1621,30 @@ gld_${EMULATION_NAME}_place_orphan (file
 	  asection *snew, **pps;
 
 	  snew = os->bfd_section;
-	  if (place->os->bfd_section != NULL || place->section != NULL)
+
+	  /* Shuffle the bfd section list to make the output file look
+	     neater.  This is really only cosmetic.  */
+	  if (place->section == NULL)
 	    {
-	      /* Shuffle the section to make the output file look neater.  */
-	      if (place->section == NULL)
-		{
-#if 0
-		  /* Finding the end of the list is a little tricky.  We
-		     make a wild stab at it by comparing section flags.  */
-		  flagword first_flags = place->os->bfd_section->flags;
-		  for (pps = &place->os->bfd_section->next;
-		       *pps != NULL && (*pps)->flags == first_flags;
-		       pps = &(*pps)->next)
-		    ;
-		  place->section = pps;
-#else
-		  /* Put orphans after the first section on the list.  */
-		  place->section = &place->os->bfd_section->next;
-#endif
-		}
+	      asection *bfd_section = place->os->bfd_section;
+
+	      /* If the output statement hasn't been used to place
+		 any input sections (and thus doesn't have an output
+		 bfd_section), look for the closest prior output statement
+		 having an output section.  */
+	      if (bfd_section == NULL)
+		bfd_section = output_prev_sec_find (place->os);
+
+	      if (bfd_section != NULL && bfd_section != snew)
+		place->section = &bfd_section->next;
+	    }
 
+	  if (place->section != NULL)
+	    {
 	      /*  Unlink the section.  */
-	      for (pps = &output_bfd->sections; *pps != snew; pps = &(*pps)->next)
+	      for (pps = &output_bfd->sections;
+		   *pps != snew;
+		   pps = &(*pps)->next)
 		;
 	      *pps = snew->next;
 
@@ -1619,21 +1652,43 @@ gld_${EMULATION_NAME}_place_orphan (file
 	      snew->next = *place->section;
 	      *place->section = snew;
 	    }
-	  place->section = &snew->next;	/* Save the end of this list.  */
 
-	  if (place->stmt == NULL)
-	    {
-	      /* Put the new statement list right at the head.  */
-	      *add.tail = place->os->header.next;
-	      place->os->header.next = add.head;
-	    }
-	  else
+	  /* Save the end of this list.  Further ophans of this type will
+	     follow the one we've just added.  */
+	  place->section = &snew->next;
+
+	  /* The following is non-cosmetic.  We try to put the output
+	     statements in some sort of reasonable order here, because
+	     they determine the final load addresses of the orphan
+	     sections.  In addition, placing output statements in the
+	     wrong order may require extra segments.  For instance,
+	     given a typical situation of all read-only sections placed
+	     in one segment and following that a segment containing all
+	     the read-write sections, we wouldn't want to place an orphan
+	     read/write section before or amongst the read-only ones.  */
+	  if (add.head != NULL)
 	    {
-	      /* Put it after the last orphan statement we added.  */
-	      *add.tail = *place->stmt;
-	      *place->stmt = add.head;
+	      if (place->stmt == NULL)
+		{
+		  /* Put the new statement list right at the head.  */
+		  *add.tail = place->os->header.next;
+		  place->os->header.next = add.head;
+		}
+	      else
+		{
+		  /* Put it after the last orphan statement we added.  */
+		  *add.tail = *place->stmt;
+		  *place->stmt = add.head;
+		}
+
+	      /* Fix the global list pointer if we happened to tack our
+		 new list at the tail.  */
+	      if (*old->tail == add.head)
+		old->tail = add.tail;
+
+	      /* Save the end of this list.  */
+	      place->stmt = add.tail;
 	    }
-	  place->stmt = add.tail;	/* Save the end of this list.  */
 	}
     }
 


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