This is the mail archive of the
binutils@sourceware.org
mailing list for the binutils project.
[RFC - Gold Patch] Implement INCLUDE directive
- From: Sterling Augustine <saugustine at google dot com>
- To: binutils at sourceware dot org
- Date: Wed, 16 Nov 2011 16:45:19 -0800
- Subject: [RFC - Gold Patch] Implement INCLUDE directive
Hi,
Enclosed please find a first pass at implementing the INCLUDE
directive, bringing Gold to parity with ld.bfd, at least regarding
this feature.
A lot of setup isn't quite done when script_include_directive is
called, so the note in the old FIXME is quite right--using a standard
dirsearch structure in read_script_file is hard for reasons similar to
the need to create a fake Task there.
I wasn't sure about the best place to put the more primitive directory
search logic needed here, so I included it as a static member of
Dirsearch. Is there a better place?
Sterling
011-11-16 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.
Index: dirsearch.cc
===================================================================
RCS file: /cvs/src/src/gold/dirsearch.cc,v
retrieving revision 1.14
diff -u -r1.14 dirsearch.cc
--- dirsearch.cc 3 Jul 2011 04:16:13 -0000 1.14
+++ dirsearch.cc 17 Nov 2011 00:35:08 -0000
@@ -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,27 @@
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 char* extra_search_dir)
+{
+ struct stat buf;
+ std::string extra_name = std::string(extra_search_dir) + "/" + name;
+
+ if (stat(extra_name.c_str(), &buf) == 0)
+ return extra_name;
+ for (unsigned int i = 0; i < directories.size(); ++i)
+ {
+ const Search_directory* p = &directories.at(i);
+ std::string full_name = p->name() + "/" + name;
+ if (stat(full_name.c_str(), &buf) == 0)
+ return full_name;
+ }
+ return name;
+}
+
} // End namespace gold.
Index: dirsearch.h
===================================================================
RCS file: /cvs/src/src/gold/dirsearch.h,v
retrieving revision 1.9
diff -u -r1.9 dirsearch.h
--- dirsearch.h 25 May 2011 06:15:28 -0000 1.9
+++ dirsearch.h 17 Nov 2011 00:35:08 -0000
@@ -67,6 +67,13 @@
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 char* extra_search_dir);
+
private:
// We can not copy this class.
Dirsearch(const Dirsearch&);
Index: script.cc
===================================================================
RCS file: /cvs/src/src/gold/script.cc,v
retrieving revision 1.85
diff -u -r1.85 script.cc
--- script.cc 31 Oct 2011 22:51:03 -0000 1.85
+++ script.cc 17 Nov 2011 00:35:08 -0000
@@ -1535,18 +1535,26 @@
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 = std::string(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 @@
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 @@
}
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.