public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* Section sizing + orphan placement bugs
@ 2005-11-23 16:37 Daniel Jacobowitz
  2005-11-24  0:40 ` Alan Modra
                   ` (2 more replies)
  0 siblings, 3 replies; 8+ messages in thread
From: Daniel Jacobowitz @ 2005-11-23 16:37 UTC (permalink / raw)
  To: binutils

The patch at the end of this message is fairly obvious, but the testcase
deserves some explanation.  It shows at least one other serious bug that
this patch does not fix.

Here's a testcase that works on x86_64.  Should work just about anywhere
with a standard page size of 4K.  Assemble and then link with -shared.

	.section .note.foo, "a", %note
	.space 16

	.section .data, "aw"
	.space 3800

	.section .rodata, "a"
	.space 4

./x86/ld/ld-new: section .note.foo [00000000001011a0 -> 00000000001011af] overlaps section .data [00000000001010c8 -> 0000000000101f9f]
./x86/ld/ld-new: note: section .note.foo lma 0x1011a0 overlaps previous sections

The -shared option is necessary to trigger the bug because it will cause
there to be no .interp section in the output.  We try to place notes with
.interp first.  Without that they get stuck into the orphan list for either
the next best flags match (usually .rodata), or *ABS*.

The .rodata section is necessary to trigger the bug because otherwise there
will be no output section for .rodata, so lang_output_section_find_by_flags
will place the orphaned .note.foo section there.  If there is one, we'll see
that it has SHT_PROGBITS instead of SHT_NOTE, and refuse to use .rodata.  We
fall back to *ABS*, which places them at the front of the file.

I suspect we should try to place them with something else for shared
libraries; .rodata isn't a great choice.  But *ABS* works out OK most of the
time (if there aren't too many orphans, the note will end up in the first
page with the phdrs, anyway).

The .data section is necessary to trigger the bug because it causes the
DATA_SECTION_ALIGN mechanism to size sections a second time.  -z relro would
probably have a similar effect.

Now we've placed this output section at the very front of the list of
linker statements.  It ends up before the assignment to
. = . + SIZEOF_HEADERS, which is the other serious bug I mentioned up top.
We need to place orphans after an initial assignment to dot; otherwise, the
program headers will end up outside of the load segment!

Anyway, as a consequence of not having yet assigned to dot, the second call
to one_lang_size_sections_pass gets a stale value of os->region->current,
and places the section in an arbitrary location; then it resets dot
downwards and places everything else, and we end up overlapping .data.
The unreduced testcase somehow put it in the middle of .hash.

I think the attached fix is right for that part of the bug but I'm open to
suggestions on how to handle SIZEOF_HEADERS.

-- 
Daniel Jacobowitz
CodeSourcery, LLC

2005-11-23  Daniel Jacobowitz  <dan@codesourcery.com>

	* ldlang.c (lang_size_sections): Call lang_reset_memory_regions
	before redoing one_lang_size_sections_pass.

Index: ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.208
diff -u -p -r1.208 ldlang.c
--- ldlang.c	18 Nov 2005 04:12:27 -0000	1.208
+++ ldlang.c	23 Nov 2005 15:38:03 -0000
@@ -4499,6 +4499,7 @@ lang_size_sections (bfd_boolean *relax, 
 	  expld.dataseg.base -= maxpage;
 	  relro_end -= maxpage;
 	}
+      lang_reset_memory_regions ();
       one_lang_size_sections_pass (relax, check_regions);
       if (expld.dataseg.relro_end > relro_end)
 	{
@@ -4522,6 +4523,7 @@ lang_size_sections (bfd_boolean *relax, 
 		  < old_min_base)
 		expld.dataseg.base += expld.dataseg.pagesize;
 	      expld.dataseg.base -= (1 << max_alignment_power);
+	      lang_reset_memory_regions ();
 	      one_lang_size_sections_pass (relax, check_regions);
 	    }
 	}
@@ -4542,6 +4544,7 @@ lang_size_sections (bfd_boolean *relax, 
 	  && first + last <= expld.dataseg.pagesize)
 	{
 	  expld.dataseg.phase = exp_dataseg_adjust;
+	  lang_reset_memory_regions ();
 	  one_lang_size_sections_pass (relax, check_regions);
 	}
     }

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

* Re: Section sizing + orphan placement bugs
  2005-11-23 16:37 Section sizing + orphan placement bugs Daniel Jacobowitz
@ 2005-11-24  0:40 ` Alan Modra
  2005-11-24  0:57   ` Alan Modra
  2005-11-24 18:12 ` Khem Raj
  2006-05-04 19:11 ` Daniel Jacobowitz
  2 siblings, 1 reply; 8+ messages in thread
From: Alan Modra @ 2005-11-24  0:40 UTC (permalink / raw)
  To: binutils

On Wed, Nov 23, 2005 at 11:36:54AM -0500, Daniel Jacobowitz wrote:
> I think the attached fix is right for that part of the bug but I'm open to
> suggestions on how to handle SIZEOF_HEADERS.

I'll fix that bit.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: Section sizing + orphan placement bugs
  2005-11-24  0:40 ` Alan Modra
@ 2005-11-24  0:57   ` Alan Modra
  2005-11-24  1:19     ` Alan Modra
  0 siblings, 1 reply; 8+ messages in thread
From: Alan Modra @ 2005-11-24  0:57 UTC (permalink / raw)
  To: binutils

On Thu, Nov 24, 2005 at 11:09:57AM +1030, Alan Modra wrote:
> On Wed, Nov 23, 2005 at 11:36:54AM -0500, Daniel Jacobowitz wrote:
> > I think the attached fix is right for that part of the bug but I'm open to
> > suggestions on how to handle SIZEOF_HEADERS.
> 
> I'll fix that bit.

Like this.

	* ldlang.c (lang_insert_orphan): Skip first assignment to dot
	in script when looking for place to insert orphan statements.

Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.208
diff -u -p -r1.208 ldlang.c
--- ld/ldlang.c	18 Nov 2005 04:12:27 -0000	1.208
+++ ld/ldlang.c	24 Nov 2005 00:54:47 -0000
@@ -1467,13 +1467,20 @@ lang_insert_orphan (asection *s,
 	    {
 	      lang_statement_union_type **where;
 	      lang_statement_union_type **assign = NULL;
+	      bfd_boolean ignore_first;
 
 	      /* Look for a suitable place for the new statement list.
 		 The idea is to skip over anything that might be inside
 		 a SECTIONS {} statement in a script, before we find
 		 another output_section_statement.  Assignments to "dot"
 		 before an output section statement are assumed to
-		 belong to it.  */
+		 belong to it.  An exception to this rule is made for
+		 the first assignment to dot, otherwise we might put an
+		 orphan before . = . + SIZEOF_HEADERS or similar
+		 assignments that set the initial address.  */
+
+	      ignore_first = after == (&lang_output_section_statement.head
+				       ->output_section_statement);
 	      for (where = &after->header.next;
 		   *where != NULL;
 		   where = &(*where)->header.next)
@@ -1487,9 +1494,11 @@ lang_insert_orphan (asection *s,
 			  ass = &(*where)->assignment_statement;
 			  if (ass->exp->type.node_class != etree_assert
 			      && ass->exp->assign.dst[0] == '.'
-			      && ass->exp->assign.dst[1] == 0)
+			      && ass->exp->assign.dst[1] == 0
+			      && !ignore_first)
 			    assign = where;
 			}
+		      ignore_first = FALSE;
 		      continue;
 		    case lang_wild_statement_enum:
 		    case lang_input_section_enum:

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: Section sizing + orphan placement bugs
  2005-11-24  0:57   ` Alan Modra
@ 2005-11-24  1:19     ` Alan Modra
  2005-11-24  5:23       ` Alan Modra
  0 siblings, 1 reply; 8+ messages in thread
From: Alan Modra @ 2005-11-24  1:19 UTC (permalink / raw)
  To: binutils

On Thu, Nov 24, 2005 at 11:27:03AM +1030, Alan Modra wrote:
> 	* ldlang.c (lang_insert_orphan): Skip first assignment to dot
> 	in script when looking for place to insert orphan statements.

BTW, this causes "FAIL: map addresses".  When I first looked at the
failure, I thought it was just a matter of tweaking the testsuite, but
on looking closer I see that it's another case where
lang_output_section_find_by_flags does the wrong thing since HJ's patch
to check section type.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: Section sizing + orphan placement bugs
  2005-11-24  1:19     ` Alan Modra
@ 2005-11-24  5:23       ` Alan Modra
  0 siblings, 0 replies; 8+ messages in thread
From: Alan Modra @ 2005-11-24  5:23 UTC (permalink / raw)
  To: binutils

On Thu, Nov 24, 2005 at 11:49:02AM +1030, Alan Modra wrote:
> On Thu, Nov 24, 2005 at 11:27:03AM +1030, Alan Modra wrote:
> > 	* ldlang.c (lang_insert_orphan): Skip first assignment to dot
> > 	in script when looking for place to insert orphan statements.
> 
> BTW, this causes "FAIL: map addresses".  When I first looked at the
> failure, I thought it was just a matter of tweaking the testsuite, but
> on looking closer I see that it's another case where
> lang_output_section_find_by_flags does the wrong thing since HJ's patch
> to check section type.

The simple fix of removing bfd_match_sections_by_type in the loop
looking for a place for .bss fixes the testcase, but I think this is
better.  Here, we give ELF section types priority over BFD section flags
for all sections.  I also removed bfd_match_sections_by_type from the
BFD target vector, as it seems likely to me that this function will only
ever be called from linker emulation files.

bfd/
	* elf-bfd.h (_bfd_generic_match_sections_by_type): Don't define.
	* libbfd-in.h (_bfd_generic_match_sections_by_type): Delete.
	* libbfd.c (_bfd_generic_match_sections_by_type): Delete.
	* targets.c (bfd_match_sections_by_type): Don't define.
	(BFD_JUMP_TABLE_LINK): Remove _bfd_generic_match_sections_by_type.
	* coff-rs6000.c (rs6000coff_vec, pmac_xcoff_vec): Likewise.
	* coff64-rs6000.c (rs6000coff64_vec, aix5coff64_vec): Likewise.
	* bfd-in2.h: Regenerate.
	* libbfd.h: Regenerate.

ld/
	* ldlang.c (lang_output_section_find_by_flags): Add match_type param.
	Run two passes, first using match_type, second without.
	* ldlang.h (lang_match_sec_type_func): New typedef.
	(lang_output_section_find_by_flags): Update prototype.
	* emultempl/elf32.em (place_orphan): Update calls to
	bfd_match_sections_by_type and lang_output_section_find_by_flags.
	* emultempl/pe.em (place_orphan): Likewise.

Index: bfd/coff-rs6000.c
===================================================================
RCS file: /cvs/src/src/bfd/coff-rs6000.c,v
retrieving revision 1.74
diff -u -p -r1.74 coff-rs6000.c
--- bfd/coff-rs6000.c	24 Oct 2005 02:50:27 -0000	1.74
+++ bfd/coff-rs6000.c	24 Nov 2005 04:25:01 -0000
@@ -4196,7 +4196,6 @@ const bfd_target rs6000coff_vec =
     _bfd_generic_link_split_section,
     bfd_generic_gc_sections,
     bfd_generic_merge_sections,
-    _bfd_generic_match_sections_by_type,
     bfd_generic_is_group_section,
     bfd_generic_discard_group,
     _bfd_generic_section_already_linked,
@@ -4447,7 +4446,6 @@ const bfd_target pmac_xcoff_vec =
     _bfd_generic_link_split_section,
     bfd_generic_gc_sections,
     bfd_generic_merge_sections,
-    _bfd_generic_match_sections_by_type,
     bfd_generic_is_group_section,
     bfd_generic_discard_group,
     _bfd_generic_section_already_linked,
Index: bfd/coff64-rs6000.c
===================================================================
RCS file: /cvs/src/src/bfd/coff64-rs6000.c,v
retrieving revision 1.65
diff -u -p -r1.65 coff64-rs6000.c
--- bfd/coff64-rs6000.c	24 Oct 2005 02:50:27 -0000	1.65
+++ bfd/coff64-rs6000.c	24 Nov 2005 04:25:04 -0000
@@ -2743,7 +2743,6 @@ const bfd_target rs6000coff64_vec =
     _bfd_generic_link_split_section,
     bfd_generic_gc_sections,
     bfd_generic_merge_sections,
-    _bfd_generic_match_sections_by_type,
     bfd_generic_is_group_section,
     bfd_generic_discard_group,
     _bfd_generic_section_already_linked,
@@ -2995,7 +2994,6 @@ const bfd_target aix5coff64_vec =
     _bfd_generic_link_split_section,
     bfd_generic_gc_sections,
     bfd_generic_merge_sections,
-    _bfd_generic_match_sections_by_type,
     bfd_generic_is_group_section,
     bfd_generic_discard_group,
     _bfd_generic_section_already_linked,
Index: bfd/elf-bfd.h
===================================================================
RCS file: /cvs/src/src/bfd/elf-bfd.h,v
retrieving revision 1.199
diff -u -p -r1.199 elf-bfd.h
--- bfd/elf-bfd.h	25 Oct 2005 16:19:06 -0000	1.199
+++ bfd/elf-bfd.h	24 Nov 2005 04:25:09 -0000
@@ -1476,8 +1476,6 @@ extern bfd_boolean _bfd_elf_merge_sectio
   (bfd *, struct bfd_link_info *);
 extern bfd_boolean _bfd_elf_match_sections_by_type
   (bfd *, const asection *, bfd *, const asection *);
-#define _bfd_generic_match_sections_by_type \
-  _bfd_elf_match_sections_by_type
 extern bfd_boolean bfd_elf_is_group_section
   (bfd *, const struct bfd_section *);
 extern void _bfd_elf_section_already_linked
Index: bfd/libbfd-in.h
===================================================================
RCS file: /cvs/src/src/bfd/libbfd-in.h,v
retrieving revision 1.59
diff -u -p -r1.59 libbfd-in.h
--- bfd/libbfd-in.h	3 Nov 2005 16:06:11 -0000	1.59
+++ bfd/libbfd-in.h	24 Nov 2005 04:25:28 -0000
@@ -402,8 +402,6 @@ extern bfd_boolean _bfd_generic_set_sect
   ((bfd_boolean (*) (bfd *, struct bfd_section *)) bfd_false)
 #define _bfd_nolink_section_already_linked \
   ((void (*) (bfd *, struct bfd_section *)) bfd_void)
-extern bfd_boolean _bfd_generic_match_sections_by_type
-  (bfd *, const asection *, bfd *, const asection *);
 
 /* Routines to use for BFD_JUMP_TABLE_DYNAMIC for targets which do not
    have dynamic symbols or relocs.  Use BFD_JUMP_TABLE_DYNAMIC
Index: bfd/libbfd.c
===================================================================
RCS file: /cvs/src/src/bfd/libbfd.c,v
retrieving revision 1.43
diff -u -p -r1.43 libbfd.c
--- bfd/libbfd.c	24 Oct 2005 01:40:58 -0000	1.43
+++ bfd/libbfd.c	24 Nov 2005 04:25:28 -0000
@@ -1035,15 +1035,6 @@ _bfd_generic_find_line (bfd *abfd ATTRIB
 }
 
 bfd_boolean
-_bfd_generic_match_sections_by_type (bfd *abfd ATTRIBUTE_UNUSED,
-				     const asection *asec ATTRIBUTE_UNUSED,
-				     bfd *bbfd ATTRIBUTE_UNUSED,
-				     const asection *bsec ATTRIBUTE_UNUSED)
-{
-  return TRUE;
-}
-
-bfd_boolean
 _bfd_generic_init_private_section_data (bfd *ibfd ATTRIBUTE_UNUSED,
 					asection *isec ATTRIBUTE_UNUSED,
 					bfd *obfd ATTRIBUTE_UNUSED,
Index: bfd/targets.c
===================================================================
RCS file: /cvs/src/src/bfd/targets.c,v
retrieving revision 1.139
diff -u -p -r1.139 targets.c
--- bfd/targets.c	25 Oct 2005 17:40:10 -0000	1.139
+++ bfd/targets.c	24 Nov 2005 04:25:35 -0000
@@ -434,7 +434,6 @@ BFD_JUMP_TABLE macros.
 .  NAME##_bfd_link_split_section, \
 .  NAME##_bfd_gc_sections, \
 .  NAME##_bfd_merge_sections, \
-.  _bfd_generic_match_sections_by_type, \
 .  NAME##_bfd_is_group_section, \
 .  NAME##_bfd_discard_group, \
 .  NAME##_section_already_linked \
@@ -474,12 +473,6 @@ BFD_JUMP_TABLE macros.
 .  {* Attempt to merge SEC_MERGE sections.  *}
 .  bfd_boolean (*_bfd_merge_sections) (bfd *, struct bfd_link_info *);
 .
-.#define bfd_match_sections_by_type(abfd, asec, bbfd, bsec) \
-.  BFD_SEND (abfd, _bfd_match_sections_by_type, (abfd, asec, bbfd, bsec))
-.  {* Return TRUE if 2 section types are compatible.  *}
-.  bfd_boolean (*_bfd_match_sections_by_type)
-.    (bfd *, const asection *, bfd *, const asection *);
-.
 .  {* Is this section a member of a group?  *}
 .  bfd_boolean (*_bfd_is_group_section) (bfd *, const struct bfd_section *);
 .
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.209
diff -u -p -r1.209 ldlang.c
--- ld/ldlang.c	24 Nov 2005 00:58:28 -0000	1.209
+++ ld/ldlang.c	24 Nov 2005 04:26:02 -0000
@@ -1147,7 +1147,8 @@ lang_output_section_statement_lookup (co
 
 lang_output_section_statement_type *
 lang_output_section_find_by_flags (const asection *sec,
-				   lang_output_section_statement_type **exact)
+				   lang_output_section_statement_type **exact,
+				   lang_match_sec_type_func match_type)
 {
   lang_output_section_statement_type *first, *look, *found;
   flagword flags;
@@ -1165,9 +1166,8 @@ lang_output_section_find_by_flags (const
       if (look->bfd_section != NULL)
 	{
 	  flags = look->bfd_section->flags;
-	  if (!bfd_match_sections_by_type (output_bfd,
-					   look->bfd_section,
-					   sec->owner, sec))
+	  if (match_type && !match_type (output_bfd, look->bfd_section,
+					 sec->owner, sec))
 	    continue;
 	}
       flags ^= sec->flags;
@@ -1177,7 +1177,8 @@ lang_output_section_find_by_flags (const
     }
   if (found != NULL)
     {
-      *exact = found;
+      if (exact != NULL)
+	*exact = found;
       return found;
     }
 
@@ -1190,9 +1191,8 @@ lang_output_section_find_by_flags (const
 	  if (look->bfd_section != NULL)
 	    {
 	      flags = look->bfd_section->flags;
-	      if (!bfd_match_sections_by_type (output_bfd,
-					       look->bfd_section,
-					       sec->owner, sec))
+	      if (match_type && !match_type (output_bfd, look->bfd_section,
+					     sec->owner, sec))
 		continue;
 	    }
 	  flags ^= sec->flags;
@@ -1200,10 +1200,8 @@ lang_output_section_find_by_flags (const
 			 | SEC_CODE | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
 	    found = look;
 	}
-      return found;
     }
-
-  if (sec->flags & (SEC_READONLY | SEC_THREAD_LOCAL))
+  else if (sec->flags & (SEC_READONLY | SEC_THREAD_LOCAL))
     {
       /* .rodata can go after .text, .sdata2 after .rodata.  */
       for (look = first; look; look = look->next)
@@ -1212,9 +1210,8 @@ lang_output_section_find_by_flags (const
 	  if (look->bfd_section != NULL)
 	    {
 	      flags = look->bfd_section->flags;
-	      if (!bfd_match_sections_by_type (output_bfd,
-					       look->bfd_section,
-					       sec->owner, sec))
+	      if (match_type && !match_type (output_bfd, look->bfd_section,
+					     sec->owner, sec))
 		continue;
 	    }
 	  flags ^= sec->flags;
@@ -1223,10 +1220,8 @@ lang_output_section_find_by_flags (const
 	      && !(look->flags & (SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
 	    found = look;
 	}
-      return found;
     }
-
-  if (sec->flags & SEC_SMALL_DATA)
+  else if (sec->flags & SEC_SMALL_DATA)
     {
       /* .sdata goes after .data, .sbss after .sdata.  */
       for (look = first; look; look = look->next)
@@ -1235,9 +1230,8 @@ lang_output_section_find_by_flags (const
 	  if (look->bfd_section != NULL)
 	    {
 	      flags = look->bfd_section->flags;
-	      if (!bfd_match_sections_by_type (output_bfd,
-					       look->bfd_section,
-					       sec->owner, sec))
+	      if (match_type && !match_type (output_bfd, look->bfd_section,
+					     sec->owner, sec))
 		continue;
 	    }
 	  flags ^= sec->flags;
@@ -1247,10 +1241,8 @@ lang_output_section_find_by_flags (const
 		  && !(sec->flags & SEC_HAS_CONTENTS)))
 	    found = look;
 	}
-      return found;
     }
-
-  if (sec->flags & SEC_HAS_CONTENTS)
+  else if (sec->flags & SEC_HAS_CONTENTS)
     {
       /* .data goes after .rodata.  */
       for (look = first; look; look = look->next)
@@ -1259,9 +1251,8 @@ lang_output_section_find_by_flags (const
 	  if (look->bfd_section != NULL)
 	    {
 	      flags = look->bfd_section->flags;
-	      if (!bfd_match_sections_by_type (output_bfd,
-					       look->bfd_section,
-					       sec->owner, sec))
+	      if (match_type && !match_type (output_bfd, look->bfd_section,
+					     sec->owner, sec))
 		continue;
 	    }
 	  flags ^= sec->flags;
@@ -1269,27 +1260,30 @@ lang_output_section_find_by_flags (const
 			 | SEC_SMALL_DATA | SEC_THREAD_LOCAL)))
 	    found = look;
 	}
-      return found;
     }
-
-  /* .bss goes last.  */
-  for (look = first; look; look = look->next)
+  else
     {
-      flags = look->flags;
-      if (look->bfd_section != NULL)
+      /* .bss goes last.  */
+      for (look = first; look; look = look->next)
 	{
-	  flags = look->bfd_section->flags;
-	  if (!bfd_match_sections_by_type (output_bfd,
-					   look->bfd_section,
-					   sec->owner, sec))
-	    continue;
+	  flags = look->flags;
+	  if (look->bfd_section != NULL)
+	    {
+	      flags = look->bfd_section->flags;
+	      if (match_type && !match_type (output_bfd, look->bfd_section,
+					     sec->owner, sec))
+		continue;
+	    }
+	  flags ^= sec->flags;
+	  if (!(flags & SEC_ALLOC))
+	    found = look;
 	}
-      flags ^= sec->flags;
-      if (!(flags & SEC_ALLOC))
-	found = look;
     }
 
-  return found;
+  if (found || !match_type)
+    return found;
+
+  return lang_output_section_find_by_flags (sec, NULL, NULL);
 }
 
 /* Find the last output section before given output statement.
Index: ld/ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.57
diff -u -p -r1.57 ldlang.h
--- ld/ldlang.h	17 Nov 2005 00:10:05 -0000	1.57
+++ ld/ldlang.h	24 Nov 2005 04:26:02 -0000
@@ -304,6 +304,9 @@ typedef void (*walk_wild_section_handler
 					     callback_t callback,
 					     void *data);
 
+typedef bfd_boolean (*lang_match_sec_type_func) (bfd *, const asection *,
+						 bfd *, const asection *);
+
 struct lang_wild_statement_struct
 {
   lang_statement_header_type header;
@@ -521,7 +524,8 @@ extern void ldlang_add_file
 extern lang_output_section_statement_type *lang_output_section_find
   (const char * const);
 extern lang_output_section_statement_type *lang_output_section_find_by_flags
-  (const asection *, lang_output_section_statement_type **exact);
+  (const asection *, lang_output_section_statement_type **,
+   lang_match_sec_type_func);
 extern lang_output_section_statement_type *lang_insert_orphan
   (asection *, const char *, lang_output_section_statement_type *,
    struct orphan_save *, etree_type *, lang_statement_list_type *);
Index: ld/emultempl/elf32.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/elf32.em,v
retrieving revision 1.159
diff -u -p -r1.159 elf32.em
--- ld/emultempl/elf32.em	17 Nov 2005 00:10:05 -0000	1.159
+++ ld/emultempl/elf32.em	24 Nov 2005 04:26:05 -0000
@@ -1362,9 +1362,9 @@ gld${EMULATION_NAME}_place_orphan (asect
       if (os != NULL
 	  && (os->bfd_section == NULL
 	      || os->bfd_section->flags == 0
-	      || (bfd_match_sections_by_type (output_bfd,
-					      os->bfd_section,
-					      s->owner, s)
+	      || (_bfd_elf_match_sections_by_type (output_bfd,
+						   os->bfd_section,
+						   s->owner, s)
 		  && ((s->flags ^ os->bfd_section->flags)
 		      & (SEC_LOAD | SEC_ALLOC)) == 0)))
 	{
@@ -1443,7 +1443,8 @@ gld${EMULATION_NAME}_place_orphan (asect
 	}
       after = place->os;
       if (after == NULL)
-	after = lang_output_section_find_by_flags (s, &place->os);
+	after = lang_output_section_find_by_flags
+	  (s, &place->os, _bfd_elf_match_sections_by_type);
       if (after == NULL)
 	/* *ABS* is always the first output section statement.  */
 	after = &lang_output_section_statement.head->output_section_statement;
Index: ld/emultempl/pe.em
===================================================================
RCS file: /cvs/src/src/ld/emultempl/pe.em,v
retrieving revision 1.112
diff -u -p -r1.112 pe.em
--- ld/emultempl/pe.em	17 Nov 2005 00:10:05 -0000	1.112
+++ ld/emultempl/pe.em	24 Nov 2005 04:26:06 -0000
@@ -1621,7 +1621,7 @@ gld_${EMULATION_NAME}_place_orphan (asec
 	    place->os = lang_output_section_find (place->name);
 	  after = place->os;
 	  if (after == NULL)
-	    after = lang_output_section_find_by_flags (s, &place->os);
+	    after = lang_output_section_find_by_flags (s, &place->os, NULL);
 	  if (after == NULL)
 	    /* *ABS* is always the first output section statement.  */
 	    after = (&lang_output_section_statement.head

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

* Re: Section sizing + orphan placement bugs
  2005-11-23 16:37 Section sizing + orphan placement bugs Daniel Jacobowitz
  2005-11-24  0:40 ` Alan Modra
@ 2005-11-24 18:12 ` Khem Raj
  2006-05-04 19:11 ` Daniel Jacobowitz
  2 siblings, 0 replies; 8+ messages in thread
From: Khem Raj @ 2005-11-24 18:12 UTC (permalink / raw)
  To: binutils


Daniel Jacobowitz wrote:
> The patch at the end of this message is fairly obvious, but the testcase
> deserves some explanation.  It shows at least one other serious bug that
> this patch does not fix.
>
> Here's a testcase that works on x86_64.  Should work just about anywhere
> with a standard page size of 4K.  Assemble and then link with -shared.
>
> 	.section .note.foo, "a", %note
> 	.space 16
>
> 	.section .data, "aw"
> 	.space 3800
>
> 	.section .rodata, "a"
> 	.space 4
>   
probably test case should also be added to regression testsuites.
> ./x86/ld/ld-new: section .note.foo [00000000001011a0 -> 00000000001011af] overlaps section .data [00000000001010c8 -> 0000000000101f9f]
> ./x86/ld/ld-new: note: section .note.foo lma 0x1011a0 overlaps previous sections
>
> The -shared option is necessary to trigger the bug because it will cause
> there to be no .interp section in the output.  We try to place notes with
> .interp first.  Without that they get stuck into the orphan list for either
> the next best flags match (usually .rodata), or *ABS*.
>
> The .rodata section is necessary to trigger the bug because otherwise there
> will be no output section for .rodata, so lang_output_section_find_by_flags
> will place the orphaned .note.foo section there.  If there is one, we'll see
> that it has SHT_PROGBITS instead of SHT_NOTE, and refuse to use .rodata.  We
> fall back to *ABS*, which places them at the front of the file.
>
> I suspect we should try to place them with something else for shared
> libraries; .rodata isn't a great choice.  But *ABS* works out OK most of the
> time (if there aren't too many orphans, the note will end up in the first
> page with the phdrs, anyway).
>
> The .data section is necessary to trigger the bug because it causes the
> DATA_SECTION_ALIGN mechanism to size sections a second time.  -z relro would
> probably have a similar effect.
>
> Now we've placed this output section at the very front of the list of
> linker statements.  It ends up before the assignment to
> . = . + SIZEOF_HEADERS, which is the other serious bug I mentioned up top.
> We need to place orphans after an initial assignment to dot; otherwise, the
> program headers will end up outside of the load segment!
>
> Anyway, as a consequence of not having yet assigned to dot, the second call
> to one_lang_size_sections_pass gets a stale value of os->region->current,
> and places the section in an arbitrary location; then it resets dot
> downwards and places everything else, and we end up overlapping .data.
> The unreduced testcase somehow put it in the middle of .hash.
>
> I think the attached fix is right for that part of the bug but I'm open to
> suggestions on how to handle SIZEOF_HEADERS.
>
>   

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

* Re: Section sizing + orphan placement bugs
  2005-11-23 16:37 Section sizing + orphan placement bugs Daniel Jacobowitz
  2005-11-24  0:40 ` Alan Modra
  2005-11-24 18:12 ` Khem Raj
@ 2006-05-04 19:11 ` Daniel Jacobowitz
  2006-05-04 22:56   ` Alan Modra
  2 siblings, 1 reply; 8+ messages in thread
From: Daniel Jacobowitz @ 2006-05-04 19:11 UTC (permalink / raw)
  To: binutils

On Wed, Nov 23, 2005 at 11:36:54AM -0500, Daniel Jacobowitz wrote:
> 2005-11-23  Daniel Jacobowitz  <dan@codesourcery.com>
> 
> 	* ldlang.c (lang_size_sections): Call lang_reset_memory_regions
> 	before redoing one_lang_size_sections_pass.

Hey Alan,

You fixed the other bug I described along with this patch, but I think
this patch still applies; does it look OK?

Patch at:
  http://sourceware.org/ml/binutils/2005-11/msg00343.html

-- 
Daniel Jacobowitz
CodeSourcery

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

* Re: Section sizing + orphan placement bugs
  2006-05-04 19:11 ` Daniel Jacobowitz
@ 2006-05-04 22:56   ` Alan Modra
  0 siblings, 0 replies; 8+ messages in thread
From: Alan Modra @ 2006-05-04 22:56 UTC (permalink / raw)
  To: binutils

On Thu, May 04, 2006 at 03:11:40PM -0400, Daniel Jacobowitz wrote:
> On Wed, Nov 23, 2005 at 11:36:54AM -0500, Daniel Jacobowitz wrote:
> > 2005-11-23  Daniel Jacobowitz  <dan@codesourcery.com>
> > 
> > 	* ldlang.c (lang_size_sections): Call lang_reset_memory_regions
> > 	before redoing one_lang_size_sections_pass.
> 
> Hey Alan,
> 
> You fixed the other bug I described along with this patch, but I think
> this patch still applies; does it look OK?
> 
> Patch at:
>   http://sourceware.org/ml/binutils/2005-11/msg00343.html

Yes, it looks fine to me.

-- 
Alan Modra
IBM OzLabs - Linux Technology Centre

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

end of thread, other threads:[~2006-05-04 22:56 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2005-11-23 16:37 Section sizing + orphan placement bugs Daniel Jacobowitz
2005-11-24  0:40 ` Alan Modra
2005-11-24  0:57   ` Alan Modra
2005-11-24  1:19     ` Alan Modra
2005-11-24  5:23       ` Alan Modra
2005-11-24 18:12 ` Khem Raj
2006-05-04 19:11 ` Daniel Jacobowitz
2006-05-04 22:56   ` Alan Modra

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).