aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--gold/fileread.cc49
-rw-r--r--gold/options.cc4
-rw-r--r--gold/options.h29
-rw-r--r--gold/readsyms.cc2
-rw-r--r--gold/script.cc22
5 files changed, 85 insertions, 21 deletions
diff --git a/gold/fileread.cc b/gold/fileread.cc
index d87f773..9e6cd90 100644
--- a/gold/fileread.cc
+++ b/gold/fileread.cc
@@ -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,
diff --git a/gold/options.cc b/gold/options.cc
index 577c604..4df21b0 100644
--- a/gold/options.cc
+++ b/gold/options.cc
@@ -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);
}
diff --git a/gold/options.h b/gold/options.h
index 85a7aee..3b7c051 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -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_;
};
diff --git a/gold/readsyms.cc b/gold/readsyms.cc
index bbeb425..87e4fa4 100644
--- a/gold/readsyms.cc
+++ b/gold/readsyms.cc
@@ -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;
diff --git a/gold/script.cc b/gold/script.cc
index 950fa15..b003add 100644
--- a/gold/script.cc
+++ b/gold/script.cc
@@ -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);
}