svn commit: r210245 - head/contrib/binutils/ld/emultempl

Andriy Gapon avg at FreeBSD.org
Mon Jul 19 18:20:45 UTC 2010


Author: avg
Date: Mon Jul 19 18:20:44 2010
New Revision: 210245
URL: http://svn.freebsd.org/changeset/base/210245

Log:
  binutils/ld: fix incorrect placement of __start_SECNAME in some cases
  
  __start_SECNAME and __stop_SECNAME symbols are automatically generated
  by ld for orphan sections, i.e. those not explicitely referenced by a
  linker script.  The symbols are supposed to be placed correspondingly
  at the start and the end of the section in output file.  In some cases
  __start_SECNAME may be placed at the address after the end of the
  previous section (if any) and before the start the section.  This
  happens when following conditions are met:
  1. the orphan section is found in more than one input file
  2. the orphan section has different alignment requirements across input
  files
  3. the first instance of the section encountered doesn't have the
  greatest alignment requirement
  In these conditions resulting output section will be placed at address
  after the end of the previous section aligned to the greatest alignment
  requirement in the inputs, but __start_SECNAME will be placed at address
  after the end of the previous section aligned to the alignment
  requirement of the first input in which the section is encountered.
  
  See commit message of r196118 for a concrete example of problems caused
  by this bug.
  
  The fix is to place __start_SECNAME inside the section and use ABSOLUTE
  directive, rather than placing __start_SECNAME outside the section and
  trying to guess address alignment.
  
  This fix is in line with upstream binutils change/fix made between
  versions 2.19 and 2.20 in revision of 1.307 ldlang.c.
  
  MFC after:	3 weeks

Modified:
  head/contrib/binutils/ld/emultempl/elf32.em

Modified: head/contrib/binutils/ld/emultempl/elf32.em
==============================================================================
--- head/contrib/binutils/ld/emultempl/elf32.em	Mon Jul 19 18:01:06 2010	(r210244)
+++ head/contrib/binutils/ld/emultempl/elf32.em	Mon Jul 19 18:20:44 2010	(r210245)
@@ -1314,26 +1314,6 @@ gld${EMULATION_NAME}_place_orphan (lang_
       lang_list_init (stat_ptr);
     }
 
-  if (config.build_constructors)
-    {
-      /* If the name of the section is representable in C, then create
-	 symbols to mark the start and the end of the section.  */
-      for (ps = secname; *ps != '\0'; ps++)
-	if (! ISALNUM (*ps) && *ps != '_')
-	  break;
-      if (*ps == '\0')
-	{
-	  char *symname;
-	  etree_type *e_align;
-
-	  symname = (char *) xmalloc (ps - secname + sizeof "__start_");
-	  sprintf (symname, "__start_%s", secname);
-	  e_align = exp_unop (ALIGN_K,
-			      exp_intop ((bfd_vma) 1 << s->alignment_power));
-	  lang_add_assignment (exp_assop ('=', symname, e_align));
-	}
-    }
-
   address = NULL;
   if (link_info.relocatable || (s->flags & (SEC_LOAD | SEC_ALLOC)) == 0)
     address = exp_intop ((bfd_vma) 0);
@@ -1354,6 +1334,26 @@ gld${EMULATION_NAME}_place_orphan (lang_
 					    (etree_type *) NULL,
 					    load_base);
 
+  if (config.build_constructors)
+    {
+      /* If the name of the section is representable in C, then create
+	 symbols to mark the start and the end of the section.  */
+      for (ps = secname; *ps != '\0'; ps++)
+	if (! ISALNUM (*ps) && *ps != '_')
+	  break;
+      if (*ps == '\0')
+	{
+	  char *symname;
+	  etree_type *e_align;
+
+	  symname = (char *) xmalloc (ps - secname + sizeof "__start_");
+	  sprintf (symname, "__start_%s", secname);
+	  lang_add_assignment (exp_assop ('=', symname,
+					  exp_unop (ABSOLUTE,
+						    exp_nameop (NAME, "."))));
+	}
+    }
+
   lang_add_section (&os->children, s, os, file);
 
   lang_leave_output_section_statement


More information about the svn-src-all mailing list