[Patch,AVR]: Fix PR13697: Wrong symbols with --gc-sections

Alan Modra amodra@gmail.com
Wed May 30 04:17:00 GMT 2012


On Tue, May 29, 2012 at 03:37:45PM -0400, Hans-Peter Nilsson wrote:
> On Tue, 29 May 2012, Georg-Johann Lay wrote:
> > At the start of .bss the location counter is moved backwards!
> > I still think this is a linker bug.
> 
> Well yes, but the point was that the bug is not the linker
> script's lack of KEEP.

Whether or not this is a bug depends on how you think zero size
discarded output sections should be treated.  One extreme is to treat
discarded output sections as if they do not exist, so address,
alignment, mapping to segments, and probably other things I've
forgotten, are ignored and so do not affect following sections.  The
other extreme is to just remove them from the section headers, but
otherwise apply all their attributes.  Johann seems to want this
latter behaviour judging from his comment about optimisation.  The
trouble is that whatever ld does, someone will be unhappy.  For
instance, if we always apply alignment then you can get holes in the
memory image caused by unused sections.  Some will view that as a
"bug".

Current ld behaviour is to ignore discarded sections except when they
contain a symbol assignment, or are the last section in an overlay.  I
did think it might be reasonable to modify this further, to not ignore
a section that is mentioned in a -T<section>=<address> command line
option, but that ran foul of two tests:

+FAIL: ld-scripts/empty-address-2a
+FAIL: ld-scripts/empty-address-2b

Seems someone wants this behaviour enough to write a testcase..

I'm going to apply the following without the first hunk, which is the
bit that makes -Tsect keep sections.

	* ldlang.h (lang_output_section_statement_type): Rename
	"section_relative_symbol" field to "update_dot".
	* ldlang.c: Update all uses.
	(strip_excluded_output_sections): Don't test update_dot_tree here..
	(lang_leave_overlay): ..set update_dot here.

Index: ld/ldlang.h
===================================================================
RCS file: /cvs/src/src/ld/ldlang.h,v
retrieving revision 1.104
diff -u -p -r1.104 ldlang.h
--- ld/ldlang.h	14 May 2012 19:45:28 -0000	1.104
+++ ld/ldlang.h	30 May 2012 03:55:45 -0000
@@ -163,8 +163,8 @@ typedef struct lang_output_section_state
   unsigned int all_input_readonly : 1;
   /* If this section should be ignored.  */
   unsigned int ignored : 1; 
-  /* If there is a symbol relative to this section.  */
-  unsigned int section_relative_symbol : 1; 
+  /* If this section should update "dot".  Prevents section being ignored.  */
+  unsigned int update_dot : 1; 
 } lang_output_section_statement_type;
 
 typedef struct
Index: ld/ldlang.c
===================================================================
RCS file: /cvs/src/src/ld/ldlang.c,v
retrieving revision 1.390
diff -u -p -r1.390 ldlang.c
--- ld/ldlang.c	14 May 2012 19:45:28 -0000	1.390
+++ ld/ldlang.c	30 May 2012 03:55:46 -0000
@@ -3654,6 +3654,7 @@ map_input_to_output_sections
 		 likely to surprise naive users.  */
 	      tos = lang_output_section_statement_lookup (name, 0, TRUE);
 	      tos->addr_tree = s->address_statement.address;
+	      tos->update_dot = 1;
 	      if (tos->bfd_section == NULL)
 		init_os (tos, 0);
 	    }
@@ -3889,8 +3890,7 @@ 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.  */
-	  if (!os->section_relative_symbol
-	      && !os->update_dot_tree)
+	  if (!os->update_dot)
 	    os->ignored = TRUE;
 	  output_section->flags |= SEC_EXCLUDE;
 	  bfd_section_list_remove (link_info.output_bfd, output_section);
@@ -5253,7 +5253,7 @@ lang_size_sections_1
 		 || tree->type.node_class == etree_assign)
 		&& (tree->assign.dst [0] != '.'
 		    || tree->assign.dst [1] != '\0'))
-	      output_section_statement->section_relative_symbol = 1;
+	      output_section_statement->update_dot = 1;
 
 	    if (!output_section_statement->ignored)
 	      {
@@ -7390,8 +7390,11 @@ lang_leave_overlay (etree_type *lma_expr
   /* After setting the size of the last section, set '.' to end of the
      overlay region.  */
   if (overlay_list != NULL)
-    overlay_list->os->update_dot_tree
-      = exp_assign (".", exp_binop ('+', overlay_vma, overlay_max));
+    {
+      overlay_list->os->update_dot = 1;
+      overlay_list->os->update_dot_tree
+	= exp_assign (".", exp_binop ('+', overlay_vma, overlay_max));
+    }
 
   l = overlay_list;
   while (l != NULL)

-- 
Alan Modra
Australia Development Lab, IBM



More information about the Binutils mailing list