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]

PR24806, Linking with -T inside --start-group/--end-group


This patch processes INSERT AFTER and INSERT BEFORE in a user -T
script when such a script is invoked on the command line inside
--start-group/--end-group.  Also, ld now warns when the user simply
forgot --end-group.

	PR 24806
	* ldlang.c (process_insert_statements): Add start of list
	parameter.  Use rather than lang_os_list.head.  Process insert
	statements inside group statements with a recursive call.
	(lang_process): Adjust process_insert_statements call.
	* lexsup.c (parse_args): Warn when adding missing --end-group.

diff --git a/ld/ldlang.c b/ld/ldlang.c
index 617f76919c..96daf0ef11 100644
--- a/ld/ldlang.c
+++ b/ld/ldlang.c
@@ -3916,21 +3916,26 @@ map_input_to_output_sections
    start of the list and places them after the output section
    statement specified by the insert.  This operation is complicated
    by the fact that we keep a doubly linked list of output section
-   statements as well as the singly linked list of all statements.  */
+   statements as well as the singly linked list of all statements.
+   FIXME someday: Twiddling with the list not only moves statements
+   from the user's script but also input and group statements that are
+   built from command line object files and --start-group.  We only
+   get away with this because the list pointers used by file_chain
+   and input_file_chain are not reordered, and processing via
+   statement_list after this point mostly ignores input statements.
+   One exception is the map file, where LOAD and START GROUP/END GROUP
+   can end up looking odd.  */
 
 static void
-process_insert_statements (void)
+process_insert_statements (lang_statement_union_type **start)
 {
   lang_statement_union_type **s;
   lang_output_section_statement_type *first_os = NULL;
   lang_output_section_statement_type *last_os = NULL;
   lang_output_section_statement_type *os;
 
-  /* "start of list" is actually the statement immediately after
-     the special abs_section output statement, so that it isn't
-     reordered.  */
-  s = &lang_os_list.head;
-  while (*(s = &(*s)->header.next) != NULL)
+  s = start;
+  while (*s != NULL)
     {
       if ((*s)->header.type == lang_output_section_statement_enum)
 	{
@@ -3949,6 +3954,18 @@ process_insert_statements (void)
 	  if (first_os == NULL)
 	    first_os = last_os;
 	}
+      else if ((*s)->header.type == lang_group_statement_enum)
+	{
+	  /* A user might put -T between --start-group and
+	     --end-group.  One way this odd construct might arise is
+	     from a wrapper around ld to change library search
+	     behaviour.  For example:
+	     #! /bin/sh
+	     exec real_ld --start-group "$@" --end-group
+	     This isn't completely unreasonable so go looking inside a
+	     group statement for insert statements.  */
+	  process_insert_statements (&(*s)->group_statement.children.head);
+	}
       else if ((*s)->header.type == lang_insert_statement_enum)
 	{
 	  lang_insert_statement_type *i = &(*s)->insert_statement;
@@ -4049,18 +4066,19 @@ process_insert_statements (void)
 	    }
 
 	  ptr = insert_os_after (where);
-	  /* Snip everything after the abs_section output statement we
-	     know is at the start of the list, up to and including
-	     the insert statement we are currently processing.  */
-	  first = lang_os_list.head->header.next;
-	  lang_os_list.head->header.next = (*s)->header.next;
-	  /* Add them back where they belong.  */
+	  /* Snip everything from the start of the list, up to and
+	     including the insert statement we are currently processing.  */
+	  first = *start;
+	  *start = (*s)->header.next;
+	  /* Add them back where they belong, minus the insert.  */
 	  *s = *ptr;
 	  if (*s == NULL)
 	    statement_list.tail = s;
 	  *ptr = first;
-	  s = &lang_os_list.head;
+	  s = start;
+	  continue;
 	}
+      s = &(*s)->header.next;
     }
 
   /* Undo constraint twiddling.  */
@@ -7544,7 +7562,9 @@ lang_process (void)
   lang_statement_iteration++;
   map_input_to_output_sections (statement_list.head, NULL, NULL);
 
-  process_insert_statements ();
+  /* Start at the statement immediately after the special abs_section
+     output statement, so that it isn't reordered.  */
+  process_insert_statements (&lang_os_list.head->header.next);
 
   /* Find any sections not attached explicitly and handle them.  */
   lang_place_orphans ();
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 2539356baa..d4f198125c 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -1602,6 +1602,7 @@ parse_args (unsigned argc, char **argv)
 
   while (ingroup)
     {
+      einfo (_("%P: missing --end-group; added as last command line option\n"));
       lang_leave_group ();
       ingroup--;
     }

-- 
Alan Modra
Australia Development Lab, IBM


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