From Craig Silverstein: add support for searching for input files
authorIan Lance Taylor <iant@google.com>
Tue, 2 Oct 2007 21:24:41 +0000 (21:24 +0000)
committerIan Lance Taylor <iant@google.com>
Tue, 2 Oct 2007 21:24:41 +0000 (21:24 +0000)
named in linker scripts.

gold/fileread.cc
gold/options.cc
gold/options.h
gold/readsyms.cc
gold/script.cc

index d87f773..9e6cd90 100644 (file)
@@ -27,6 +27,7 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/mman.h>
+#include "filenames.h"
 
 #include "options.h"
 #include "dirsearch.h"
@@ -371,21 +372,38 @@ Input_file::Input_file(const char* name, const unsigned char* contents,
   : file_()
 {
   this->input_argument_ =
-    new Input_file_argument(name, false, Position_dependent_options());
+    new Input_file_argument(name, false, "", Position_dependent_options());
   bool ok = file_.open(name, contents, size);
   gold_assert(ok);
 }
 
 // Open the file.
 
+// If the filename is not absolute, we assume it is in the current
+// directory *except* when:
+//    A) input_argument_->is_lib() is true; or
+//    B) input_argument_->extra_search_path() is not empty.
+// In both cases, we look in extra_search_path + library_path to find
+// the file location, rather than the current directory.
+
 void
 Input_file::open(const General_options& options, const Dirsearch& dirpath)
 {
   std::string name;
-  if (!this->input_argument_->is_lib())
+
+  // Case 1: name is an absolute file, just try to open it
+  // Case 2: name is relative but is_lib is false and extra_search_path
+  //         is empty
+  if (IS_ABSOLUTE_PATH (this->input_argument_->name())
+      || (!this->input_argument_->is_lib()
+         && this->input_argument_->extra_search_path() == NULL))
     name = this->input_argument_->name();
-  else
+
+  // Case 3: is_lib is true
+  else if (this->input_argument_->is_lib())
     {
+      // We don't yet support extra_search_path with -l.
+      gold_assert(this->input_argument_->extra_search_path() == NULL);
       std::string n1("lib");
       n1 += this->input_argument_->name();
       std::string n2;
@@ -405,6 +423,31 @@ Input_file::open(const General_options& options, const Dirsearch& dirpath)
        }
     }
 
+  // Case 4: extra_search_path is not empty
+  else
+    {
+      gold_assert(this->input_argument_->extra_search_path() != NULL);
+
+      // First, check extra_search_path.
+      name = this->input_argument_->extra_search_path();
+      if (!IS_DIR_SEPARATOR (name[name.length() - 1]))
+        name += '/';
+      name += this->input_argument_->name();
+      struct stat dummy_stat;
+      if (::stat(name.c_str(), &dummy_stat) < 0)
+        {
+          // extra_search_path failed, so check the normal search-path.
+          name = dirpath.find(this->input_argument_->name(), "");
+          if (name.empty())
+            {
+              fprintf(stderr, _("%s: cannot find %s\n"), program_name,
+                      this->input_argument_->name());
+              gold_exit(false);
+            }
+        }
+    }
+
+  // Now that we've figured out where the file lives, try to open it.
   if (!this->file_.open(name))
     {
       fprintf(stderr, _("%s: cannot open %s: %s\n"), program_name,
index 577c604..4df21b0 100644 (file)
@@ -285,6 +285,8 @@ options::Command_line_options::options[] =
                NULL, ONE_DASH, &General_options::set_shared),
   GENERAL_NOARG('\0', "static", N_("Do not link against shared libraries"),
                NULL, ONE_DASH, &General_options::set_static),
+  GENERAL_ARG('\0', "sysroot", N_("Currently ignored"), NULL, TWO_DASHES,
+             &General_options::ignore),
   POSDEP_NOARG('\0', "as-needed",
               N_("Only set DT_NEEDED for dynamic libs if used"),
               NULL, TWO_DASHES, &Position_dependent_options::set_as_needed),
@@ -550,7 +552,7 @@ Command_line::apply_option(const options::One_option& opt,
 void
 Command_line::add_file(const char* name, bool is_lib)
 {
-  Input_file_argument file(name, is_lib, this->position_options_);
+  Input_file_argument file(name, is_lib, "", this->position_options_);
   this->inputs_.add_file(file);
 }
 
index 85a7aee..3b7c051 100644 (file)
@@ -244,13 +244,23 @@ class Position_dependent_options
 class Input_file_argument
 {
  public:
+  // name: file name or library name
+  // is_lib: true if name is a library name: that is, emits the leading
+  //         "lib" and trailing ".so"/".a" from the name
+  // extra_search_path: an extra directory to look for the file, prior
+  //         to checking the normal library search path.  If this is "",
+  //         then no extra directory is added.
+  // options: The position dependent options at this point in the
+  //         command line, such as --group.
   Input_file_argument()
-    : name_(), is_lib_(false), options_()
+    : name_(), is_lib_(false), extra_search_path_(""), options_()
   { }
 
   Input_file_argument(const char* name, bool is_lib,
+                      const char* extra_search_path,
                      const Position_dependent_options& options)
-    : name_(name), is_lib_(is_lib), options_(options)
+    : name_(name), is_lib_(is_lib), extra_search_path_(extra_search_path),
+      options_(options)
   { }
 
   const char*
@@ -265,12 +275,27 @@ class Input_file_argument
   is_lib() const
   { return this->is_lib_; }
 
+  const char*
+  extra_search_path() const
+  {
+    return (this->extra_search_path_.empty()
+            ? NULL
+           : this->extra_search_path_.c_str());
+  }
+
+  // Return whether this file may require a search using the -L
+  // options.
+  bool
+  may_need_search() const
+  { return this->is_lib_ || !this->extra_search_path_.empty(); }
+
  private:
   // We use std::string, not const char*, here for convenience when
   // using script files, so that we do not have to preserve the string
   // in that case.
   std::string name_;
   bool is_lib_;
+  std::string extra_search_path_;
   Position_dependent_options options_;
 };
 
index bbeb425..87e4fa4 100644 (file)
@@ -52,7 +52,7 @@ Task::Is_runnable_type
 Read_symbols::is_runnable(Workqueue*)
 {
   if (this->input_argument_->is_file()
-      && this->input_argument_->file().is_lib()
+      && this->input_argument_->file().may_need_search()
       && this->dirpath_.token().is_blocked())
     return IS_BLOCKED;
 
index 950fa15..b003add 100644 (file)
@@ -1166,20 +1166,14 @@ extern "C" void
 script_add_file(void* closurev, const char* name)
 {
   Parser_closure* closure = static_cast<Parser_closure*>(closurev);
-  std::string absname;
-  if (name[0] == '/')
-    {
-      absname = name;
-    }
-  else
-    {
-      // Prepend `dirname closure->filename()` to make the path absolute.
-      char *slash = strrchr(closure->filename(), '/');
-      absname.assign(closure->filename(),
-                     slash ? slash - closure->filename() + 1 : 0);
-      absname += name;
-    }
-  Input_file_argument file(absname.c_str(), false, closure->position_dependent_options());
+  // In addition to checking the normal library search path, we also
+  // want to check in the script-directory.
+  const char *slash = strrchr(closure->filename(), '/');
+  std::string script_directory(closure->filename(),
+                               slash ? slash - closure->filename() + 1 : 0);
+  Input_file_argument file(name, false,
+                           slash ? script_directory.c_str() : ".",
+                           closure->position_dependent_options());
   closure->inputs()->add_file(file);
 }