This is the mail archive of the binutils@sourceware.org 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]

pe and pep __start_<section> symbols


On Tue, May 12, 2009 at 03:33:35PM +0800, Pan ruochen wrote:
> The symbol ___start_ResData is not the start address of section
> ResData. What's wrong?

This cures the problem with constructor symbols on pe targets.  The
trouble was that pe.em (and pep.em) align output sections to a page
boundary, and the __start_<secname> symbol was added to the internal
linker script before the output section statement alignment.

While poking around in this area I noticed a few other problems.
a) The pe and pep place_orphan functions added non-dollar sections to
   the beginning of the output section.  That meant input sections are
   reversed from their file order, which wouldn't ordinarily cause a
   problem but it's not usual linker behaviour.
b) These functions improperly added their input section statements
   into the output section statement child list without using the tail
   pointer of the input list.  This meant only one statement was added.
c) lang_insert_orphan can be called when an existing output section's
   type or flags are incompatible with an orphan input section.  In
   this case, I think we ought to create a new output section, but I
   don't do that in this patch.  Instead I just ensure we don't
   duplicate the symbols.

	* ldlang.c (lang_insert_orphan): Add __start_<section> symbol
	assignment inside output section statement.  Ensure only one
	set of symbols per output section.
	* emultempl/pe.em (gld_${EMULATION_NAME}_place_orphan): Add non-
	dollar sections before dollar sections.  Correct add_child
	list insertion.
	* emultempl/pep.em (gld_${EMULATION_NAME}_place_orphan): Likewise.

Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.306
diff -u -p -r1.306 ldlang.c
--- ld/ldlang.c	16 Apr 2009 23:07:00 -0000	1.306
+++ ld/ldlang.c	13 May 2009 00:16:36 -0000
@@ -1668,8 +1668,16 @@ lang_insert_orphan (asection *s,
       push_stat_ptr (&add);
     }
 
+  if (link_info.relocatable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
+    address = exp_intop (0);
+
+  os_tail = ((lang_output_section_statement_type **)
+	     lang_output_section_statement.tail);
+  os = lang_enter_output_section_statement (secname, address, 0, NULL, NULL,
+					    NULL, constraint);
+
   ps = NULL;
-  if (config.build_constructors)
+  if (config.build_constructors && *os_tail == os)
     {
       /* If the name of the section is representable in C, then create
 	 symbols to mark the start and the end of the section.  */
@@ -1688,26 +1696,19 @@ lang_insert_orphan (asection *s,
 			      exp_intop ((bfd_vma) 1 << s->alignment_power));
 	  lang_add_assignment (exp_assop ('=', ".", e_align));
 	  lang_add_assignment (exp_provide (symname,
-					    exp_nameop (NAME, "."),
+					    exp_unop (ABSOLUTE,
+						      exp_nameop (NAME, ".")),
 					    FALSE));
 	}
     }
 
-  if (link_info.relocatable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
-    address = exp_intop (0);
-
-  os_tail = ((lang_output_section_statement_type **)
-	     lang_output_section_statement.tail);
-  os = lang_enter_output_section_statement (secname, address, 0, NULL, NULL,
-					    NULL, constraint);
-
   if (add_child == NULL)
     add_child = &os->children;
   lang_add_section (add_child, s, os);
 
   lang_leave_output_section_statement (0, "*default*", NULL, NULL);
 
-  if (config.build_constructors && *ps == '\0')
+  if (ps != NULL && *ps == '\0')
     {
       char *symname;
 
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.148
diff -u -p -r1.148 pe.em
--- ld/emultempl/pe.em	2 Apr 2009 14:42:41 -0000	1.148
+++ ld/emultempl/pe.em	12 May 2009 23:19:34 -0000
@@ -1771,6 +1771,7 @@ gld_${EMULATION_NAME}_place_orphan (asec
   char *dollar = NULL;
   lang_output_section_statement_type *os;
   lang_statement_list_type add_child;
+  lang_statement_union_type **pl;
 
   /* Look through the script to see where to place this section.  */
   if (!link_info.relocatable
@@ -1876,47 +1877,29 @@ gld_${EMULATION_NAME}_place_orphan (asec
 			       &add_child);
     }
 
-  {
-    lang_statement_union_type **pl = &os->children.head;
-
-    if (dollar != NULL)
-      {
-	bfd_boolean found_dollar;
-
-	/* The section name has a '\$'.  Sort it with the other '\$'
-	   sections.  */
-	found_dollar = FALSE;
-	for ( ; *pl != NULL; pl = &(*pl)->header.next)
-	  {
-	    lang_input_section_type *ls;
-	    const char *lname;
+  /* If the section name has a '\$', sort it with the other '\$'
+     sections.  */
+  for (pl = &os->children.head; *pl != NULL; pl = &(*pl)->header.next)
+    {
+      lang_input_section_type *ls;
+      const char *lname;
 
-	    if ((*pl)->header.type != lang_input_section_enum)
-	      continue;
+      if ((*pl)->header.type != lang_input_section_enum)
+	continue;
 
-	    ls = &(*pl)->input_section;
+      ls = &(*pl)->input_section;
 
-	    lname = bfd_get_section_name (ls->section->owner, ls->section);
-	    if (strchr (lname, '\$') == NULL)
-	      {
-		if (found_dollar)
-		  break;
-	      }
-	    else
-	      {
-		found_dollar = TRUE;
-		if (strcmp (orig_secname, lname) < 0)
-		  break;
-	      }
-	  }
-      }
+      lname = bfd_get_section_name (ls->section->owner, ls->section);
+      if (strchr (lname, '\$') != NULL
+	  && (dollar == NULL || strcmp (orig_secname, lname) < 0))
+	break;
+    }
 
-    if (add_child.head != NULL)
-      {
-	add_child.head->header.next = *pl;
-	*pl = add_child.head;
-      }
-  }
+  if (add_child.head != NULL)
+    {
+      *add_child.tail = *pl;
+      *pl = add_child.head;
+    }
 
   return os;
 }
Index: ld/emultempl/pep.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pep.em,v
retrieving revision 1.25
diff -u -p -r1.25 pep.em
--- ld/emultempl/pep.em	2 Apr 2009 14:42:41 -0000	1.25
+++ ld/emultempl/pep.em	12 May 2009 23:19:35 -0000
@@ -1546,6 +1546,7 @@ gld_${EMULATION_NAME}_place_orphan (asec
   char *dollar = NULL;
   lang_output_section_statement_type *os;
   lang_statement_list_type add_child;
+  lang_statement_union_type **pl;
 
   /* Look through the script to see where to place this section.  */
   if (!link_info.relocatable
@@ -1651,47 +1652,29 @@ gld_${EMULATION_NAME}_place_orphan (asec
 			       &add_child);
     }
 
-  {
-    lang_statement_union_type **pl = &os->children.head;
-
-    if (dollar != NULL)
-      {
-	bfd_boolean found_dollar;
-
-	/* The section name has a '\$'.  Sort it with the other '\$'
-	   sections.  */
-	found_dollar = FALSE;
-	for ( ; *pl != NULL; pl = &(*pl)->header.next)
-	  {
-	    lang_input_section_type *ls;
-	    const char *lname;
+  /* If the section name has a '\$', sort it with the other '\$'
+     sections.  */
+  for (pl = &os->children.head; *pl != NULL; pl = &(*pl)->header.next)
+    {
+      lang_input_section_type *ls;
+      const char *lname;
 
-	    if ((*pl)->header.type != lang_input_section_enum)
-	      continue;
+      if ((*pl)->header.type != lang_input_section_enum)
+	continue;
 
-	    ls = &(*pl)->input_section;
+      ls = &(*pl)->input_section;
 
-	    lname = bfd_get_section_name (ls->section->owner, ls->section);
-	    if (strchr (lname, '\$') == NULL)
-	      {
-		if (found_dollar)
-		  break;
-	      }
-	    else
-	      {
-		found_dollar = TRUE;
-		if (strcmp (orig_secname, lname) < 0)
-		  break;
-	      }
-	  }
-      }
+      lname = bfd_get_section_name (ls->section->owner, ls->section);
+      if (strchr (lname, '\$') != NULL
+	  && (dollar == NULL || strcmp (orig_secname, lname) < 0))
+	break;
+    }
 
-    if (add_child.head != NULL)
-      {
-	add_child.head->header.next = *pl;
-	*pl = add_child.head;
-      }
-  }
+  if (add_child.head != NULL)
+    {
+      *add_child.tail = *pl;
+      *pl = add_child.head;
+    }
 
   return os;
 }

-- 
Alan Modra
Australia Development Lab, IBM


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