PATCH: PR ld/3223/3267: Properly handle empty output section

H. J. Lu hjl@lucon.org
Tue Sep 26 23:28:00 GMT 2006


This patch restores the old behavior of output section discarding. It
also documents that non-constant output section address will be
ignored when it is discarded.


H.J.
---
bfd/

2006-09-26  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/3223
	PR ld/3267
	* elf.c (assign_file_positions_for_non_load_sections): Don't
	warn zero size allocated sections.

ld/

2006-09-26  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/3223
	PR ld/3267
	* ld.texinfo: Updated Output Section Discarding.

	* ldlang.h (lang_output_section_statement_type): Add ignored_vma
	and section_relative_symbol.
	* ldlang.c (strip_excluded_output_sections): Don't strip a
	section with a symbol relative to it.  Set ignored_vma to TRUE
	if address of an empty output section isn't set to a constant.
	(lang_size_sections_1): Mark if an output section has a symbol
	symbol relative to it.  Check ignored_vma for updating "dot",
	instead of ignored.
	(lang_do_assignments_1): Check ignored_vma for updating "dot",
	instead of ignored.

ld/testsuite/

2006-09-26  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/3223
	PR ld/3267
	* ld-scripts/empty-address-1.d: New file.
	* ld-scripts/empty-address-1.s: Likewise.
	* ld-scripts/empty-address-1.t: Likewise.
	* ld-scripts/empty-address-2.s: Likewise.
	* ld-scripts/empty-address-2a.d: Likewise.
	* ld-scripts/empty-address-2a.t: Likewise.
	* ld-scripts/empty-address-2b.d: Likewise.
	* ld-scripts/empty-address-2b.t: Likewise.
	* ld-scripts/empty-address-3.s: Likewise.
	* ld-scripts/empty-address-3a.d: Likewise.
	* ld-scripts/empty-address-3a.t: Likewise.
	* ld-scripts/empty-address-3b.d: Likewise.
	* ld-scripts/empty-address-3b.t: Likewise.
	* ld-scripts/empty-address-3c.d: Likewise.
	* ld-scripts/empty-address-3c.t: Likewise.
	* ld-scripts/empty-address.exp: Likewise.

--- binutils/bfd/elf.c.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/bfd/elf.c	2006-09-26 15:07:38.000000000 -0700
@@ -4662,12 +4662,13 @@ assign_file_positions_for_non_load_secti
 	hdr->sh_offset = hdr->bfd_section->filepos;
       else if ((hdr->sh_flags & SHF_ALLOC) != 0)
 	{
-	  ((*_bfd_error_handler)
-	   (_("%B: warning: allocated section `%s' not in segment"),
-	    abfd,
-	    (hdr->bfd_section == NULL
-	     ? "*unknown*"
-	     : hdr->bfd_section->name)));
+	  if (hdr->sh_size != 0)
+	    ((*_bfd_error_handler)
+	     (_("%B: warning: allocated section `%s' not in segment"),
+		abfd,
+		(hdr->bfd_section == NULL
+		 ? "*unknown*" 
+		 : hdr->bfd_section->name)));
 	  if ((abfd->flags & D_PAGED) != 0)
 	    off += vma_page_aligned_bias (hdr->sh_addr, off,
 					  bed->maxpagesize);
--- binutils/ld/ld.texinfo.empty	2006-09-26 12:06:35.000000000 -0700
+++ binutils/ld/ld.texinfo	2006-09-26 15:15:18.000000000 -0700
@@ -3688,7 +3688,7 @@ The linker will not create output sectio
 contents.  This is for convenience when referring to input sections that
 may or may not be present in any of the input files.  For example:
 @smallexample
-.foo @{ *(.foo) @}
+.foo : @{ *(.foo) @}
 @end smallexample
 @noindent
 will only create a @samp{.foo} section in the output file if there is a
@@ -3698,6 +3698,9 @@ If you use anything other than an input 
 section command, such as a symbol assignment, then the output section
 will always be created, even if there are no matching input sections.
 
+When a section is discarded, its address (@pxref{Output Section Address})
+will be ignored unless it is provided as a constant.
+
 @cindex /DISCARD/
 The special output section name @samp{/DISCARD/} may be used to discard
 input sections.  Any input sections which are assigned to an output
--- binutils/ld/ldlang.c.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/ldlang.c	2006-09-26 15:07:38.000000000 -0700
@@ -3343,6 +3343,7 @@ strip_excluded_output_sections (void)
 	continue;
 
       exclude = (output_section->rawsize == 0
+		 && !os->section_relative_symbol
 		 && (output_section->flags & SEC_KEEP) == 0
 		 && !bfd_section_removed_from_list (output_bfd,
 						    output_section));
@@ -3373,6 +3374,11 @@ strip_excluded_output_sections (void)
 	  /* We don't set bfd_section to NULL since bfd_section of the
 	     removed output section statement may still be used.  */
 	  os->ignored = TRUE;
+	  /* If address of an empty output section is set to a constant,
+	     we update "dot" even if it is ignored.  */
+	  os->ignored_vma
+	    = (os->addr_tree == NULL
+	       || os->addr_tree->type.node_class != etree_value);
 	  output_section->flags |= SEC_EXCLUDE;
 	  bfd_section_list_remove (output_bfd, output_section);
 	  output_bfd->section_count--;
@@ -4461,7 +4467,7 @@ lang_size_sections_1
 	      }
 	    os->processed_lma = TRUE;
 
-	    if (bfd_is_abs_section (os->bfd_section) || os->ignored)
+	    if (bfd_is_abs_section (os->bfd_section) || os->ignored_vma)
 	      break;
 
 	    /* Keep track of normal sections using the default
@@ -4630,11 +4636,19 @@ lang_size_sections_1
 	case lang_assignment_statement_enum:
 	  {
 	    bfd_vma newdot = dot;
+	    etree_type *tree = s->assignment_statement.exp;
 
-	    exp_fold_tree (s->assignment_statement.exp,
+	    exp_fold_tree (tree,
 			   output_section_statement->bfd_section,
 			   &newdot);
 
+	    /* This symbol is relative to this section.  */
+	    if ((tree->type.node_class == etree_provided 
+		 || tree->type.node_class == etree_assign)
+		&& (tree->assign.dst [0] != '.'
+		    || tree->assign.dst [1] != '\0'))
+	      output_section_statement->section_relative_symbol = 1;
+
 	    if (!output_section_statement->ignored)
 	      {
 		if (output_section_statement == abs_output_section)
@@ -4815,7 +4829,7 @@ lang_do_assignments_1 (lang_statement_un
 	    lang_output_section_statement_type *os;
 
 	    os = &(s->output_section_statement);
-	    if (os->bfd_section != NULL && !os->ignored)
+	    if (os->bfd_section != NULL && !os->ignored_vma)
 	      {
 		dot = os->bfd_section->vma;
 
--- binutils/ld/ldlang.h.empty	2006-09-07 10:16:34.000000000 -0700
+++ binutils/ld/ldlang.h	2006-09-26 15:07:38.000000000 -0700
@@ -153,7 +153,12 @@ typedef struct lang_output_section_state
   unsigned int processed_vma : 1;
   unsigned int processed_lma : 1;
   unsigned int all_input_readonly : 1;
+  /* If this section should be ignored.  */
   unsigned int ignored : 1; 
+  /* If this section VMA should be ignored.  */
+  unsigned int ignored_vma : 1; 
+  /* If there is a symbol relative to this section.  */
+  unsigned int section_relative_symbol : 1; 
 } lang_output_section_statement_type;
 
 typedef struct
--- binutils/ld/testsuite/ld-scripts/empty-address-1.d.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/testsuite/ld-scripts/empty-address-1.d	2006-09-26 15:07:38.000000000 -0700
@@ -0,0 +1,8 @@
+#ld: -T empty-address-1.t
+#nm: -n
+#...
+0+0 T _start
+#...
+0+2000000 A __data_end
+0+2000000 D __data_start
+#pass
--- binutils/ld/testsuite/ld-scripts/empty-address-1.s.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/testsuite/ld-scripts/empty-address-1.s	2006-09-26 15:07:38.000000000 -0700
@@ -0,0 +1,5 @@
+	.text
+	.global _start
+_start:
+	.long __data_start
+	.long __data_end
--- binutils/ld/testsuite/ld-scripts/empty-address-1.t.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/testsuite/ld-scripts/empty-address-1.t	2006-09-26 15:07:38.000000000 -0700
@@ -0,0 +1,11 @@
+SECTIONS
+{
+  .text 0x0000000: { *(.text) }
+  .data 0x2000000:
+  {
+    __data_start = . ;
+    *(.data)
+  }
+  __data_end = .;
+  /DISCARD/ : { *(.*) }
+}
--- binutils/ld/testsuite/ld-scripts/empty-address-2.s.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/testsuite/ld-scripts/empty-address-2.s	2006-09-26 15:07:38.000000000 -0700
@@ -0,0 +1,4 @@
+	.text
+	.global _start
+_start:
+	.long __data_end
--- binutils/ld/testsuite/ld-scripts/empty-address-2a.d.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/testsuite/ld-scripts/empty-address-2a.d	2006-09-26 15:07:38.000000000 -0700
@@ -0,0 +1,8 @@
+#source: empty-address-2.s
+#ld: -Ttext 0x0000000 -Tdata 0x2000000 -T empty-address-2a.t
+#nm: -n
+#...
+0+0 T _start
+#...
+0+2000000 A __data_end
+#pass
--- binutils/ld/testsuite/ld-scripts/empty-address-2a.t.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/testsuite/ld-scripts/empty-address-2a.t	2006-09-26 15:07:38.000000000 -0700
@@ -0,0 +1,7 @@
+SECTIONS
+{
+  .text : { *(.text) }
+  .data : { *(.data) }
+  __data_end = .;
+  /DISCARD/ : { *(.*) }
+}
--- binutils/ld/testsuite/ld-scripts/empty-address-2b.d.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/testsuite/ld-scripts/empty-address-2b.d	2006-09-26 15:07:38.000000000 -0700
@@ -0,0 +1,8 @@
+#source: empty-address-2.s
+#ld: -Ttext 0x0000000 -Tdata 0x2000000 -T empty-address-2b.t
+#nm: -n
+#...
+0+0 T _start
+#...
+0+2000000 A __data_end
+#pass
--- binutils/ld/testsuite/ld-scripts/empty-address-2b.t.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/testsuite/ld-scripts/empty-address-2b.t	2006-09-26 15:07:38.000000000 -0700
@@ -0,0 +1,11 @@
+SECTIONS
+{
+  .text 0x0000000: { *(.text) }
+  .data :
+  {
+    PROVIDE (__data_start = .);
+    *(.data)
+  }
+  __data_end = .;
+  /DISCARD/ : { *(.*) }
+}
--- binutils/ld/testsuite/ld-scripts/empty-address-3.s.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/testsuite/ld-scripts/empty-address-3.s	2006-09-26 15:07:38.000000000 -0700
@@ -0,0 +1,5 @@
+	.text
+	.global _start
+_start:
+	.byte 0,0,0,0,0,0,0,0
+	.byte 0,0,0,0,0,0,0,0
--- binutils/ld/testsuite/ld-scripts/empty-address-3a.d.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/testsuite/ld-scripts/empty-address-3a.d	2006-09-26 15:07:38.000000000 -0700
@@ -0,0 +1,8 @@
+#source: empty-address-3.s
+#ld: -T empty-address-3a.t
+#nm: -n
+#...
+0+0 T _start
+#...
+0+10 A __data_end
+#pass
--- binutils/ld/testsuite/ld-scripts/empty-address-3a.t.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/testsuite/ld-scripts/empty-address-3a.t	2006-09-26 15:07:38.000000000 -0700
@@ -0,0 +1,10 @@
+SECTIONS
+{
+  .text 0x00000000: { *(.text) }
+  .data ALIGN(0x1000) + (. & (0x1000 - 1)):
+  {
+    *(.data)
+  }
+  __data_end = .;
+  /DISCARD/ : { *(.*) }
+}
--- binutils/ld/testsuite/ld-scripts/empty-address-3b.d.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/testsuite/ld-scripts/empty-address-3b.d	2006-09-26 15:07:38.000000000 -0700
@@ -0,0 +1,8 @@
+#source: empty-address-3.s
+#ld: -T empty-address-3b.t
+#nm: -n
+#...
+0+0 T _start
+#...
+0+10 A __data_end
+#pass
--- binutils/ld/testsuite/ld-scripts/empty-address-3b.t.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/testsuite/ld-scripts/empty-address-3b.t	2006-09-26 15:07:38.000000000 -0700
@@ -0,0 +1,11 @@
+SECTIONS
+{
+  .text 0x00000000: { *(.text) }
+  .data ALIGN(0x1000) + (. & (0x1000 - 1)):
+  {
+    PROVIDE (__data_start = .);
+    *(.data)
+  }
+  __data_end = .;
+  /DISCARD/ : { *(.*) }
+}
--- binutils/ld/testsuite/ld-scripts/empty-address-3c.d.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/testsuite/ld-scripts/empty-address-3c.d	2006-09-26 15:07:38.000000000 -0700
@@ -0,0 +1,10 @@
+#source: empty-address-3.s
+#ld: -T empty-address-3c.t
+#nm: -n
+#...
+0+0 T _start
+#...
+0+1010 A __data_end
+#...
+0+1010 D __data_start
+#pass
--- binutils/ld/testsuite/ld-scripts/empty-address-3c.t.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/testsuite/ld-scripts/empty-address-3c.t	2006-09-26 15:07:38.000000000 -0700
@@ -0,0 +1,11 @@
+SECTIONS
+{
+  .text 0x00000000: { *(.text) }
+  .data ALIGN(0x1000) + (. & (0x1000 - 1)):
+  {
+    __data_start = .;
+    *(.data)
+  }
+  __data_end = .;
+  /DISCARD/ : { *(.*) }
+}
--- binutils/ld/testsuite/ld-scripts/empty-address.exp.empty	2006-09-26 15:07:38.000000000 -0700
+++ binutils/ld/testsuite/ld-scripts/empty-address.exp	2006-09-26 15:07:38.000000000 -0700
@@ -0,0 +1,25 @@
+# Make sure that "dot" is updated for empty sections if their addresses
+# are set.
+#   Copyright 2006
+#   Free Software Foundation, Inc.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+# 
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+# 
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA.
+
+run_dump_test empty-address-1
+run_dump_test empty-address-2a
+run_dump_test empty-address-2b
+run_dump_test empty-address-3a
+run_dump_test empty-address-3b
+run_dump_test empty-address-3c



More information about the Binutils mailing list