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]

gold patch committed: --no-undefined-version


I committed this patch to gold to add support for
--no-undefined-version.

Ian


2010-01-05  Ian Lance Taylor  <iant@google.com>

	PR 10980
	* options.h (class General_options): Add --undefined-version.
	* script.cc (struct Version_expression): Add was_matched_by_symbol
	field.
	(Version_script_info::matched_symbol): New function.
	(Version_script_info::get_symbol_version_helper): Call
	matched_symbol.
	(Version_script_info::check_unmatched_names): New function.
	* script.h (class Version_script_info): Update declarations.
	* gold.cc (queue_middle_tasks): Handle --no-undefined-version.


Index: gold.cc
===================================================================
RCS file: /cvs/src/src/gold/gold.cc,v
retrieving revision 1.75
diff -p -u -r1.75 gold.cc
--- gold.cc	29 Dec 2009 00:22:43 -0000	1.75
+++ gold.cc	6 Jan 2010 01:55:30 -0000
@@ -1,6 +1,6 @@
 // gold.cc -- main linker functions
 
-// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -443,6 +443,13 @@ queue_middle_tasks(const General_options
   // TODO: if this is too slow, do this as a task, rather than inline.
   symtab->detect_odr_violations(task, options.output_file_name());
 
+  // Do the --no-undefined-version check.
+  if (!parameters->options().undefined_version())
+    {
+      Script_options* so = layout->script_options();
+      so->version_script_info()->check_unmatched_names(symtab);
+    }
+
   // Create any automatic note sections.
   layout->create_notes();
 
Index: options.h
===================================================================
RCS file: /cvs/src/src/gold/options.h,v
retrieving revision 1.130
diff -p -u -r1.130 options.h
--- options.h	5 Jan 2010 22:55:08 -0000	1.130
+++ options.h	6 Jan 2010 01:55:30 -0000
@@ -971,6 +971,10 @@ class General_options
   DEFINE_set(trace_symbol, options::TWO_DASHES, 'y',
              N_("Trace references to symbol"), N_("SYMBOL"));
 
+  DEFINE_bool(undefined_version, options::TWO_DASHES, '\0', true,
+	      N_("Allow unused version in script (default)"),
+	      N_("Do not allow unused version in script"));
+
   DEFINE_string(Y, options::EXACTLY_ONE_DASH, 'Y', "",
 		N_("Default search path for Solaris compatibility"),
 		N_("PATH"));
Index: script.cc
===================================================================
RCS file: /cvs/src/src/gold/script.cc,v
retrieving revision 1.64
diff -p -u -r1.64 script.cc
--- script.cc	31 Dec 2009 03:48:46 -0000	1.64
+++ script.cc	6 Jan 2010 01:55:31 -0000
@@ -1,6 +1,6 @@
 // script.cc -- handle linker scripts for gold.
 
-// Copyright 2006, 2007, 2008, 2009 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -1793,23 +1793,25 @@ Keyword_to_parsecode::keyword_to_parseco
 
 // A single version expression.
 // For example, pattern="std::map*" and language="C++".
-// PATTERN should be from the stringpool.
-struct
-Version_expression
+struct Version_expression
 {
   Version_expression(const std::string& a_pattern,
 		     Version_script_info::Language a_language,
                      bool a_exact_match)
-    : pattern(a_pattern), language(a_language), exact_match(a_exact_match)
+    : pattern(a_pattern), language(a_language), exact_match(a_exact_match),
+      was_matched_by_symbol(false)
   { }
 
   std::string pattern;
   Version_script_info::Language language;
   // If false, we use glob() to match pattern.  If true, we use strcmp().
   bool exact_match;
+  // True if --no-undefined-version is in effect and we found this
+  // version in get_symbol_version.  We use mutable because this
+  // struct is generally not modifiable after it has been created.
+  mutable bool was_matched_by_symbol;
 };
 
-
 // A list of expressions.
 struct Version_expression_list
 {
@@ -1965,6 +1967,27 @@ Version_script_info::build_expression_li
     }
 }
 
+// Record that we have matched a name found in the version script.
+
+void
+Version_script_info::matched_symbol(const Version_tree* version_tree,
+				    const char* name) const
+{
+  const struct Version_expression_list* global = version_tree->global;
+  for (size_t i = 0; i < global->expressions.size(); ++i)
+    {
+      const Version_expression& expression(global->expressions[i]);
+      if (expression.pattern == name
+	  && (expression.exact_match
+	      || strpbrk(expression.pattern.c_str(), "?*[") == NULL))
+	{
+	  expression.was_matched_by_symbol = true;
+	  return;
+	}
+    }
+  gold_unreachable();
+}
+
 // Look up SYMBOL_NAME in the list of versions.  If CHECK_GLOBAL is
 // true look at the globally visible symbols, otherwise look at the
 // symbols listed as "local:".  Return true if the symbol is found,
@@ -2015,8 +2038,19 @@ Version_script_info::get_symbol_version_
 	{
 	  if (pversion != NULL)
 	    *pversion = pe->second->tag;
+
+	  // If we are using --no-undefined-version, and this is a
+	  // global symbol, we have to record that we have found this
+	  // symbol, so that we don't warn about it.  We have to do
+	  // this now, because otherwise we have no way to get from a
+	  // non-C language back to the demangled name that we
+	  // matched.
+	  if (check_global && !parameters->options().undefined_version())
+	    this->matched_symbol(pe->second, name_to_match);
+
 	  if (allocated != NULL)
 	    free (allocated);
+
 	  return true;
 	}
 
@@ -2043,6 +2077,50 @@ Version_script_info::get_symbol_version_
   return false;
 }
 
+// Give an error if any exact symbol names (not wildcards) appear in a
+// version script, but there is no such symbol.
+
+void
+Version_script_info::check_unmatched_names(const Symbol_table* symtab) const
+{
+  for (size_t i = 0; i < this->version_trees_.size(); ++i)
+    {
+      const Version_tree* vt = this->version_trees_[i];
+      if (vt->global == NULL)
+	continue;
+      for (size_t j = 0; j < vt->global->expressions.size(); ++j)
+	{
+	  const Version_expression& expression(vt->global->expressions[j]);
+
+	  // Ignore cases where we used the version because we saw a
+	  // symbol that we looked up.  Note that
+	  // WAS_MATCHED_BY_SYMBOL will be true even if the symbol was
+	  // not a definition.  That's OK as in that case we most
+	  // likely gave an undefined symbol error anyhow.
+	  if (expression.was_matched_by_symbol)
+	    continue;
+
+	  // Just ignore names which are in languages other than C.
+	  // We have no way to look them up in the symbol table.
+	  if (expression.language != LANGUAGE_C)
+	    continue;
+
+	  // Ignore wildcard patterns.
+	  if (!expression.exact_match
+	      && strpbrk(expression.pattern.c_str(), "?*[") != NULL)
+	    continue;
+
+	  if (symtab->lookup(expression.pattern.c_str(),
+			     vt->tag.c_str()) == NULL)
+	    {
+	      gold_error(_("version script assignment of %s to symbol %s "
+			   "failed: symbol not defined"),
+			 vt->tag.c_str(), expression.pattern.c_str());
+	    }
+	}
+    }
+}
+
 struct Version_dependency_list*
 Version_script_info::allocate_dependency_list()
 {
Index: script.h
===================================================================
RCS file: /cvs/src/src/gold/script.h,v
retrieving revision 1.30
diff -p -u -r1.30 script.h
--- script.h	30 Dec 2009 22:35:48 -0000	1.30
+++ script.h	6 Jan 2010 01:55:31 -0000
@@ -1,6 +1,6 @@
 // script.h -- handle linker scripts for gold   -*- C++ -*-
 
-// Copyright 2006, 2007, 2008 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -196,6 +196,11 @@ class Version_script_info
   void
   build_lookup_tables();
 
+  // Give an error if there are any unmatched names in the version
+  // script.
+  void
+  check_unmatched_names(const Symbol_table*) const;
+
   // Print contents to the FILE.  This is for debugging.
   void
   print(FILE*) const;
@@ -209,6 +214,9 @@ class Version_script_info
 			    bool check_global,
 			    std::string* pversion) const;
 
+  void
+  matched_symbol(const Version_tree*, const char*) const;
+
   // Fast lookup information for a glob pattern.
   struct Glob
   {

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