From Craig Silverstein: add support for searching for input files
named in linker scripts.
This commit is contained in:
parent
f5c3f2256f
commit
51dee2fec3
|
@ -27,6 +27,7 @@
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
|
#include "filenames.h"
|
||||||
|
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "dirsearch.h"
|
#include "dirsearch.h"
|
||||||
|
@ -371,21 +372,38 @@ Input_file::Input_file(const char* name, const unsigned char* contents,
|
||||||
: file_()
|
: file_()
|
||||||
{
|
{
|
||||||
this->input_argument_ =
|
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);
|
bool ok = file_.open(name, contents, size);
|
||||||
gold_assert(ok);
|
gold_assert(ok);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Open the file.
|
// 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
|
void
|
||||||
Input_file::open(const General_options& options, const Dirsearch& dirpath)
|
Input_file::open(const General_options& options, const Dirsearch& dirpath)
|
||||||
{
|
{
|
||||||
std::string name;
|
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();
|
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");
|
std::string n1("lib");
|
||||||
n1 += this->input_argument_->name();
|
n1 += this->input_argument_->name();
|
||||||
std::string n2;
|
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))
|
if (!this->file_.open(name))
|
||||||
{
|
{
|
||||||
fprintf(stderr, _("%s: cannot open %s: %s\n"), program_name,
|
fprintf(stderr, _("%s: cannot open %s: %s\n"), program_name,
|
||||||
|
|
|
@ -285,6 +285,8 @@ options::Command_line_options::options[] =
|
||||||
NULL, ONE_DASH, &General_options::set_shared),
|
NULL, ONE_DASH, &General_options::set_shared),
|
||||||
GENERAL_NOARG('\0', "static", N_("Do not link against shared libraries"),
|
GENERAL_NOARG('\0', "static", N_("Do not link against shared libraries"),
|
||||||
NULL, ONE_DASH, &General_options::set_static),
|
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",
|
POSDEP_NOARG('\0', "as-needed",
|
||||||
N_("Only set DT_NEEDED for dynamic libs if used"),
|
N_("Only set DT_NEEDED for dynamic libs if used"),
|
||||||
NULL, TWO_DASHES, &Position_dependent_options::set_as_needed),
|
NULL, TWO_DASHES, &Position_dependent_options::set_as_needed),
|
||||||
|
@ -550,7 +552,7 @@ Command_line::apply_option(const options::One_option& opt,
|
||||||
void
|
void
|
||||||
Command_line::add_file(const char* name, bool is_lib)
|
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);
|
this->inputs_.add_file(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -244,13 +244,23 @@ class Position_dependent_options
|
||||||
class Input_file_argument
|
class Input_file_argument
|
||||||
{
|
{
|
||||||
public:
|
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()
|
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,
|
Input_file_argument(const char* name, bool is_lib,
|
||||||
|
const char* extra_search_path,
|
||||||
const Position_dependent_options& options)
|
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*
|
const char*
|
||||||
|
@ -265,12 +275,27 @@ class Input_file_argument
|
||||||
is_lib() const
|
is_lib() const
|
||||||
{ return this->is_lib_; }
|
{ 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:
|
private:
|
||||||
// We use std::string, not const char*, here for convenience when
|
// We use std::string, not const char*, here for convenience when
|
||||||
// using script files, so that we do not have to preserve the string
|
// using script files, so that we do not have to preserve the string
|
||||||
// in that case.
|
// in that case.
|
||||||
std::string name_;
|
std::string name_;
|
||||||
bool is_lib_;
|
bool is_lib_;
|
||||||
|
std::string extra_search_path_;
|
||||||
Position_dependent_options options_;
|
Position_dependent_options options_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -52,7 +52,7 @@ Task::Is_runnable_type
|
||||||
Read_symbols::is_runnable(Workqueue*)
|
Read_symbols::is_runnable(Workqueue*)
|
||||||
{
|
{
|
||||||
if (this->input_argument_->is_file()
|
if (this->input_argument_->is_file()
|
||||||
&& this->input_argument_->file().is_lib()
|
&& this->input_argument_->file().may_need_search()
|
||||||
&& this->dirpath_.token().is_blocked())
|
&& this->dirpath_.token().is_blocked())
|
||||||
return IS_BLOCKED;
|
return IS_BLOCKED;
|
||||||
|
|
||||||
|
|
|
@ -1166,20 +1166,14 @@ extern "C" void
|
||||||
script_add_file(void* closurev, const char* name)
|
script_add_file(void* closurev, const char* name)
|
||||||
{
|
{
|
||||||
Parser_closure* closure = static_cast<Parser_closure*>(closurev);
|
Parser_closure* closure = static_cast<Parser_closure*>(closurev);
|
||||||
std::string absname;
|
// In addition to checking the normal library search path, we also
|
||||||
if (name[0] == '/')
|
// want to check in the script-directory.
|
||||||
{
|
const char *slash = strrchr(closure->filename(), '/');
|
||||||
absname = name;
|
std::string script_directory(closure->filename(),
|
||||||
}
|
slash ? slash - closure->filename() + 1 : 0);
|
||||||
else
|
Input_file_argument file(name, false,
|
||||||
{
|
slash ? script_directory.c_str() : ".",
|
||||||
// Prepend `dirname closure->filename()` to make the path absolute.
|
closure->position_dependent_options());
|
||||||
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());
|
|
||||||
closure->inputs()->add_file(file);
|
closure->inputs()->add_file(file);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue