Dynamic section symbols, ignored output sections

Jakub Jelinek jakub@redhat.com
Sun Oct 22 00:25:00 GMT 2006


On Tue, Oct 17, 2006 at 10:54:27PM +0930, Alan Modra wrote:
> This patch does all of the above, plus adjusts the ld testsuite for
> the changes.

Thanks a lot for this, seems to work fine here.

Only a minor nit, IMHO using the preceeding section isn't always
the best choice.  E.g. .init_array etc. sections usually start the
RW segment (unless there is .tdata or .tbss) and those are often zero sized,
yet contain __init_array_{start,end} etc. symbols.  With current CVS
binutils those symbols are attached to the preceeding section, which
is typically in the RX segment many KBs/MBs away, while there is
usually a section right after the removed .init_array which is kept.
The following patch prefers to use the next section if symbol's value
is not within the preceeding section (or equal to its end) and if
there is a following section that starts at vma equal to symbol value.
Is this ok for trunk or do you prefer to always choose the preceeding
section?

2006-10-21  Jakub Jelinek  <jakub@redhat.com>

	* linker.c (fix_syms): Base symbols in removed sections on
	next section if it has the same vma as the symbol value.

--- bfd/linker.c.jj	2006-10-21 12:55:56.000000000 +0200
+++ bfd/linker.c	2006-10-21 21:31:34.000000000 +0200
@@ -3093,6 +3093,7 @@ fix_syms (struct bfd_link_hash_entry *h,
 	  && bfd_section_removed_from_list (obfd, s->output_section))
 	{
 	  asection *op;
+	  h->u.def.value += s->output_offset + s->output_section->vma;
 	  for (op = s->output_section->prev; op != NULL; op = op->prev)
 	    if ((op->flags & SEC_EXCLUDE) == 0
 		&& !bfd_section_removed_from_list (obfd, op))
@@ -3110,7 +3111,21 @@ fix_syms (struct bfd_link_hash_entry *h,
 	      if (op == NULL)
 		op = bfd_abs_section_ptr;
 	    }
-	  h->u.def.value += s->output_offset + s->output_section->vma;
+	  else if (h->u.def.value > op->vma + op->size)
+	    {
+	      /* If symbol value is equal to the start of the next
+		 section, prefer the next section.  */
+	      asection *op2 = s->output_section->prev->next;
+	      for (; op2 != NULL; op2 = op2->next)
+		if (op2->vma != h->u.def.value)
+		  break;
+		else if ((op2->flags & SEC_EXCLUDE) == 0
+			 && !bfd_section_removed_from_list (obfd, op2))
+		  {
+		    op = op2;
+		    break;
+		  }
+	    }
 	  h->u.def.value -= op->vma;
 	  h->u.def.section = op;
 	}

	Jakub



More information about the Binutils mailing list