This is the mail archive of the binutils@sourceware.org mailing list for the binutils project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: PR ld/2065: "ld -r" is broken


I am resending this with proper subject.

H.J.
---
On Sun, Dec 18, 2005 at 03:42:23PM -0800, H. J. Lu wrote:
> On Sat, Dec 17, 2005 at 12:46:44PM +1030, Alan Modra wrote:
> > On Fri, Dec 16, 2005 at 05:46:40PM -0800, H. J. Lu wrote:
> > > bad.o is generated by the new linker. Alan, can you take a look?
> > 
> > Sorry, not immediately.  I'm just about to leave for a week at the
> > beach with my family.
> > 
> 
> I opened a PR:
> 
> http://sourceware.org/bugzilla/show_bug.cgi?id=2065
> 
> and I am checking this testcase.
> 

The problem is introduced by

http://sourceware.org/ml/binutils/2005-11/msg00239.html

where the new prev field is never really set properly since the last
field used to set it points to the next field of the last element on
the list.

This hack seems to work for me. But I'd like to see the tail field in
lang_statement_list_type be removed if possible. Alan, can you take
a look after you come back?

Thanks.


H.J.
----
2005-12-18  H.J. Lu  <hongjiu.lu@intel.com>

	PR ld/2065
	* ldlang.h (lang_statement_list_type): Add last.
	* ldlang.c (file_chain): Set the last field.
	(lang_list_init): Likewise.
	(lang_insert_orphan): Likewise.
	(lang_statement_append): Likewise.
	(output_statement_newfunc): Set os.prev with last.

--- ld/ldlang.c.prev	2005-12-18 09:40:59.000000000 -0800
+++ ld/ldlang.c	2005-12-18 14:29:57.000000000 -0800
@@ -89,7 +89,7 @@ static void lang_do_version_exports_sect
 lang_output_section_statement_type *abs_output_section;
 lang_statement_list_type lang_output_section_statement;
 lang_statement_list_type *stat_ptr = &statement_list;
-lang_statement_list_type file_chain = { NULL, NULL };
+lang_statement_list_type file_chain = { NULL, NULL, NULL };
 struct bfd_sym_chain entry_symbol = { NULL, NULL };
 static const char *entry_symbol_default = "start";
 const char *entry_section = ".text";
@@ -742,6 +742,7 @@ void
 lang_list_init (lang_statement_list_type *list)
 {
   list->head = NULL;
+  list->last = NULL;
   list->tail = &list->head;
 }
 
@@ -912,8 +913,10 @@ output_statement_newfunc (struct bfd_has
 			 (lang_statement_union_type *) &ret->os,
 			 &ret->os.header.next);
 
-  ret->os.prev = &((*lang_output_section_statement.tail)
-		   ->output_section_statement);
+  if (lang_output_section_statement.last)
+    ret->os.prev
+      = &(lang_output_section_statement.last->output_section_statement);
+
   /* GCC's strict aliasing rules prevent us from just casting the
      address, so we store the pointer in a variable and cast that
      instead.  */
@@ -1531,7 +1534,10 @@ lang_insert_orphan (lang_input_statement
 	  /* Fix the global list pointer if we happened to tack our
 	     new list at the tail.  */
 	  if (*old->tail == add.head)
-	    old->tail = add.tail;
+	    {
+	      old->last = add.last;
+	      old->tail = add.tail;
+	    }
 
 	  /* Save the end of this list.  */
 	  place->stmt = add.tail;
@@ -5836,6 +5842,7 @@ lang_statement_append (lang_statement_li
 		       lang_statement_union_type **field)
 {
   *(list->tail) = element;
+  list->last = element;
   list->tail = field;
 }
 
--- ld/ldlang.h.prev	2005-12-18 09:40:59.000000000 -0800
+++ ld/ldlang.h	2005-12-18 14:12:14.000000000 -0800
@@ -44,6 +44,7 @@ struct _fill_type
 typedef struct statement_list
 {
   union lang_statement_union *head;
+  union lang_statement_union *last;
   union lang_statement_union **tail;
 } lang_statement_list_type;
 


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]