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] stateful handling of input flags, take 2


Alan suggested to add one pair of push/pop options to handle the state
of the options responsible for input file handling instead of adding an
individual option for some of the options.

I've implemented this in the patch below.  Minimal amount of new code,
documentation included.  OK to apply?


2014-08-08  Ulrich Drepper  <drepper@gmail.com>

	* ldlang.h (struct lang_input_statement_flags): Add pushed
	member.
	* ldlex.h (enum option_values): Add OPTION_PUSH_STATE and
	OPTION_POP_STATE.
	* lexsup.c (ld_options): Add entries for --push-state and
	--pop-state.
	(parse_args): Handle OPTION_PUSH_STATE and OPTION_POP_STATE.
	* ld.texinfo: Document --push-state and --pop-state.


diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 5762dc6..b559b4f 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -827,6 +827,34 @@ the linker may make more use of this option.  Also currently there is
 no difference in the linker's behaviour for different non-zero values
 of this option.  Again this may change with future releases.
 
+@kindex --push-state
+@cindex push state governing input file handling
+@item --push-state
+The @option{--push-state} allows to preserve the current state of the
+flags which govern the input file handling so that they can all be
+restored with one corresponding @option{--pop-state} option.
+
+The option which are covered are: @option{-Bdynamic}, @option{-Bstatic},
+@option{-dn}, @option{-dy}, @option{-call_shared}, @option{-non_shared},
+@option{-static}, @option{-N}, @option{-n}, @option{--whole-archive},
+@option{--no-whole-archive}, @option{-r}, @option{-Ur},
+@option{--copy-dt-needed-entries}, @option{--no-copy-dt-needed-entries},
+@option{--as-needed}, @option{--no-as-needed}, and @option{-a}.
+
+One target for this option are specifications for @file{pkg-config}.  When
+used with the @option{--libs} option all possibly needed libraries are
+listed and then possibly linked with all the time.  It is better to return
+something as follows:
+
+@smallexample
+-Wl,--push-state,--as-needed -libone -libtwo -Wl,--pop-state
+@end smallexample
+
+@kindex --pop-state
+@cindex pop state governing input file handling
+Undoes the effect of --push-state, restores the previous values of the
+flags governing input file handling.
+
 @kindex -q
 @kindex --emit-relocs
 @cindex retain relocations in final executable
diff --git a/ld/ldlang.h b/ld/ldlang.h
index 0f7fdd4..45420cd 100644
--- a/ld/ldlang.h
+++ b/ld/ldlang.h
@@ -282,6 +282,9 @@ struct lang_input_statement_flags
   /* Set if reloading an archive or --as-needed lib.  */
   unsigned int reload : 1;
 #endif /* ENABLE_PLUGINS */
+
+  /* Head of list of pushed flags.  */
+  struct lang_input_statement_flags *pushed;
 };
 
 typedef struct lang_input_statement_struct
diff --git a/ld/ldlex.h b/ld/ldlex.h
index b2753c3..63f4c81 100644
--- a/ld/ldlex.h
+++ b/ld/ldlex.h
@@ -137,6 +137,8 @@ enum option_values
   OPTION_DEFAULT_SCRIPT,
   OPTION_PRINT_OUTPUT_FORMAT,
   OPTION_IGNORE_UNRESOLVED_SYMBOL,
+  OPTION_PUSH_STATE,
+  OPTION_POP_STATE,
 };
 
 /* The initial parser states.  */
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 52b4fdb..3a1ea9e 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -505,6 +505,12 @@ static const struct ld_option ld_options[] =
     OPTION_IGNORE_UNRESOLVED_SYMBOL},
     '\0', N_("SYMBOL"),
     N_("Unresolved SYMBOL will not cause an error or warning"), TWO_DASHES },
+  { {"push-state", no_argument, NULL, OPTION_PUSH_STATE},
+    '\0', NULL, N_("Push state of flags governing input file handling"),
+    TWO_DASHES },
+  { {"pop-state", no_argument, NULL, OPTION_POP_STATE},
+    '\0', NULL, N_("Pop state of flags governing input file handling"),
+    TWO_DASHES },
 };
 
 #define OPTION_COUNT ARRAY_SIZE (ld_options)
@@ -1444,6 +1450,23 @@ parse_args (unsigned argc, char **argv)
               einfo (_("%P%X: --hash-size needs a numeric argument\n"));
           }
           break;
+
+	case OPTION_PUSH_STATE:
+	  input_flags.pushed = xmemdup (&input_flags,
+					sizeof (input_flags),
+					sizeof (input_flags));
+	  break;
+
+	case OPTION_POP_STATE:
+	  if (input_flags.pushed == NULL)
+	    einfo (_("%P%F: no state pushed before popping\n"));
+	  else
+	    {
+	      struct lang_input_statement_flags *oldp = input_flags.pushed;
+	      memcpy (&input_flags, oldp, sizeof (input_flags));
+	      free (oldp);
+	    }
+	  break;
 	}
     }
 


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