2011-11-17 Sterling Augustine <saugustine@google.com>
authorSterling Augustine <saugustine@google.com>
Thu, 17 Nov 2011 17:46:54 +0000 (17:46 +0000)
committerSterling Augustine <saugustine@google.com>
Thu, 17 Nov 2011 17:46:54 +0000 (17:46 +0000)
* script.cc (script_include_directive): Implement.
(read_script_file): New local variables name and search_path. Update
comment. Call IS_ABSOLUTE_PATH and Dirsearch::find_file_in_dir_list.
* dirsearch.h (Dirsearch::find_file_in_dir_list): Declare new method.
* dirsearch.cc (Dirsearch::find_file_in_dir_list): Implement it.

gold/ChangeLog
gold/dirsearch.cc
gold/dirsearch.h
gold/script.cc

index 20b5485c4b9dbe0adfd38a07422dbc4babf52566..fc3a55c847235a4a18f6be80004b01008a26b374 100644 (file)
@@ -1,3 +1,11 @@
+2011-11-17  Sterling Augustine  <saugustine@google.com>
+
+       * script.cc (script_include_directive): Implement.
+       (read_script_file): New local variables name and search_path. Update
+       comment. Call IS_ABSOLUTE_PATH and Dirsearch::find_file_in_dir_list.
+       * dirsearch.h (Dirsearch::find_file_in_dir_list): Declare new method.
+       * dirsearch.cc (Dirsearch::find_file_in_dir_list): Implement it.
+
 2011-11-11  Sterling Augustine  <saugustine@google.com>
 
        * yyscript.y (section_cmd): Add support for INCLUDE directive.
index 1ae2055dc467d776e0775c58917c284112666c85..a6114a442dbeb182ef4429b06359dcaa10d47fd4 100644 (file)
@@ -25,6 +25,7 @@
 #include <cerrno>
 #include <cstring>
 #include <sys/types.h>
+#include <sys/stat.h>
 #include <dirent.h>
 
 #include "debug.h"
@@ -277,4 +278,28 @@ Dirsearch::find(const std::vector<std::string>& names,
   return std::string();
 }
 
+// Search for a file in a directory list.  This is a low-level function and
+// therefore can be used before options and parameters are set.
+
+std::string
+Dirsearch::find_file_in_dir_list(const std::string& name,
+                                 const General_options::Dir_list& directories,
+                                 const std::string& extra_search_dir)
+{
+  struct stat buf;
+  std::string extra_name = extra_search_dir + '/' + name;
+
+  if (stat(extra_name.c_str(), &buf) == 0)
+    return extra_name;
+  for (General_options::Dir_list::const_iterator dir = directories.begin();
+       dir != directories.end();
+       ++dir)
+    {
+      std::string full_name = dir->name() + '/' + name;
+      if (stat(full_name.c_str(), &buf) == 0)
+        return full_name;
+    }
+  return name;
+}
+
 } // End namespace gold.
index 270cef6d8f68a2d0d764b379afc91bfb0c6f37cd..ebc0b5b3928b85749b9949981a77a4a562f86b72 100644 (file)
@@ -67,6 +67,13 @@ class Dirsearch
   token()
   { return &this->token_; }
 
+  // Search for a file in a directory list.  This is a low-level function and
+  // therefore can be used before options and parameters are set.
+  static std::string
+  find_file_in_dir_list(const std::string& name,
+                        const General_options::Dir_list& directories,
+                        const std::string& extra_search_dir);
+
  private:
   // We can not copy this class.
   Dirsearch(const Dirsearch&);
index b471cf9583152084b58692254be45fe76d142a7c..6a10c40e206e2911e90a6694695348a7153b1a26 100644 (file)
@@ -1535,18 +1535,26 @@ read_input_script(Workqueue* workqueue, Symbol_table* symtab, Layout* layout,
   return true;
 }
 
-// Helper function for read_version_script() and
-// read_commandline_script().  Processes the given file in the mode
-// indicated by first_token and lex_mode.
+// Helper function for read_version_script(), read_commandline_script() and
+// script_include_directive().  Processes the given file in the mode indicated
+// by first_token and lex_mode.
 
 static bool
 read_script_file(const char* filename, Command_line* cmdline,
                  Script_options* script_options,
                  int first_token, Lex::Mode lex_mode)
 {
-  // TODO: if filename is a relative filename, search for it manually
-  // using "." + cmdline->options()->search_path() -- not dirsearch.
   Dirsearch dirsearch;
+  std::string name = filename;
+
+  // If filename is a relative filename, search for it manually using "." +
+  // cmdline->options()->library_path() -- not dirsearch.
+  if (!IS_ABSOLUTE_PATH(filename))
+    {
+      const General_options::Dir_list& search_path =
+          cmdline->options().library_path();
+      name = Dirsearch::find_file_in_dir_list(name, search_path, ".");
+    }
 
   // The file locking code wants to record a Task, but we haven't
   // started the workqueue yet.  This is only for debugging purposes,
@@ -1557,7 +1565,7 @@ read_script_file(const char* filename, Command_line* cmdline,
   Position_dependent_options posdep = cmdline->position_dependent_options();
   if (posdep.format_enum() == General_options::OBJECT_FORMAT_BINARY)
     posdep.set_format_enum(General_options::OBJECT_FORMAT_ELF);
-  Input_file_argument input_argument(filename,
+  Input_file_argument input_argument(name.c_str(),
                                     Input_file_argument::INPUT_FILE_TYPE_FILE,
                                     "", false, posdep);
   Input_file input_file(&input_argument);
@@ -3351,10 +3359,13 @@ script_parse_memory_attr(void* closurev, const char* attrs, size_t attrlen,
 }
 
 extern "C" void
-script_include_directive(void* closurev, const char*, size_t)
+script_include_directive(void* closurev, const char* filename, size_t length)
 {
-  // FIXME: Implement ?
-  yyerror (closurev, _("GOLD does not currently support INCLUDE directives"));
+  Parser_closure* closure = static_cast<Parser_closure*>(closurev);
+  std::string name(filename, length);
+  Command_line* cmdline = closure->command_line();
+  read_script_file(name.c_str(), cmdline, &cmdline->script_options(),
+                   PARSING_LINKER_SCRIPT, Lex::LINKER_SCRIPT);
 }
 
 // Functions for memory regions.