mirror of
https://sourceware.org/git/binutils-gdb.git
synced 2024-11-27 03:54:41 +08:00
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 <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,
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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_;
|
||||
};
|
||||
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user