From Craig Silverstein: add support for searching for input files

named in linker scripts.
This commit is contained in:
Ian Lance Taylor 2007-10-02 21:24:41 +00:00
parent f5c3f2256f
commit 51dee2fec3
5 changed files with 85 additions and 21 deletions

View 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,

View 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);
}

View 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_;
};

View 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;

View 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);
}