From 42218b9f16a40780716d3ec5b817d3d44fbf4d2e Mon Sep 17 00:00:00 2001 From: =?utf8?q?Rafael=20=C3=81vila=20de=20Esp=C3=ADndola?= Date: Mon, 21 Jun 2010 21:21:25 +0000 Subject: [PATCH] 2010-06-21 Rafael Espindola * fileread.cc (Input_file::find_fie): New (Input_file::open): Use Input_file::find_fie. * fileread.h (Input_file::find_fie): New * plugin.cc (set_extra_library_path): New. (Plugin::load): Add set_extra_library_path to the transfer vector. (Plugin_manager::set_extra_library_path): New. (Plugin_manager::add_input_file): Use the extra search path if set. (set_extra_library_path(): New. * plugin.h (Plugin_manager): Add set_extra_library_path and extra_search_path_. 2010-06-21 Rafael Espindola * plugin-api.h (ld_plugin_set_extra_library_path): New. (ld_plugin_tag): Add LDPT_SET_EXTRA_LIBRARY_PATH. (ld_plugin_tv): Add tv_set_extra_library_path. --- gold/ChangeLog | 13 +++++ gold/fileread.cc | 131 ++++++++++++++++++++++++++++--------------- gold/plugin.cc | 34 ++++++++++- gold/plugin.h | 10 +++- include/ChangeLog | 6 ++ include/plugin-api.h | 10 +++- 6 files changed, 155 insertions(+), 49 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 46cbdc7d7a..304a4ae7c7 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,16 @@ +2010-06-21 Rafael Espindola + + * fileread.cc (Input_file::find_fie): New + (Input_file::open): Use Input_file::find_fie. + * fileread.h (Input_file::find_fie): New + * plugin.cc (set_extra_library_path): New. + (Plugin::load): Add set_extra_library_path to the transfer vector. + (Plugin_manager::set_extra_library_path): New. + (Plugin_manager::add_input_file): Use the extra search path if set. + (set_extra_library_path(): New. + * plugin.h (Plugin_manager): Add set_extra_library_path and + extra_search_path_. + 2010-06-19 Cary Coutant * layout.cc (gdb_sections): Add .debug_types. diff --git a/gold/fileread.cc b/gold/fileread.cc index 10e1dec223..bfab1a47f8 100644 --- a/gold/fileread.cc +++ b/gold/fileread.cc @@ -841,8 +841,30 @@ File_read::get_mtime() #endif } -// Open the file. +// Try to find a file in the extra search dirs. Returns true on success. + +static bool +try_extra_search_path(int* pindex, const Input_file_argument* input_argument, + std::string filename, std::string* found_name, + std::string* namep) { + if (input_argument->extra_search_path() == NULL) + return false; + + std::string name = input_argument->extra_search_path(); + if (!IS_DIR_SEPARATOR (name[name.length() - 1])) + name += '/'; + name += filename; + + struct stat dummy_stat; + if (*pindex > 0 || ::stat(name.c_str(), &dummy_stat) < 0) + return false; + *found_name = filename; + *namep = name; + return true; +} + +// Find the actual file. // If the filename is not absolute, we assume it is in the current // directory *except* when: // A) input_argument_->is_lib() is true; @@ -851,35 +873,37 @@ File_read::get_mtime() // In each, we look in extra_search_path + library_path to find // the file location, rather than the current directory. -bool -Input_file::open(const Dirsearch& dirpath, const Task* task, int *pindex) +static bool +find_file(const Dirsearch& dirpath, int* pindex, + const Input_file_argument* input_argument, bool* is_in_sysroot, + std::string* found_name, std::string* namep) { std::string name; // Case 1: name is an absolute file, just try to open it // Case 2: name is relative but is_lib is false, is_searched_file is false, // and extra_search_path is empty - if (IS_ABSOLUTE_PATH(this->input_argument_->name()) - || (!this->input_argument_->is_lib() - && !this->input_argument_->is_searched_file() - && this->input_argument_->extra_search_path() == NULL)) + if (IS_ABSOLUTE_PATH(input_argument->name()) + || (!input_argument->is_lib() + && !input_argument->is_searched_file() + && input_argument->extra_search_path() == NULL)) { - name = this->input_argument_->name(); - this->found_name_ = name; + name = input_argument->name(); + *found_name = name; + *namep = name; + return true; } // Case 3: is_lib is true or is_searched_file is true - else if (this->input_argument_->is_lib() - || this->input_argument_->is_searched_file()) + else if (input_argument->is_lib() + || input_argument->is_searched_file()) { - // We don't yet support extra_search_path with -l. - gold_assert(this->input_argument_->extra_search_path() == NULL); std::string n1, n2; - if (this->input_argument_->is_lib()) + if (input_argument->is_lib()) { n1 = "lib"; - n1 += this->input_argument_->name(); + n1 += input_argument->name(); if (parameters->options().is_static() - || !this->input_argument_->options().Bdynamic()) + || !input_argument->options().Bdynamic()) n1 += ".a"; else { @@ -888,49 +912,66 @@ Input_file::open(const Dirsearch& dirpath, const Task* task, int *pindex) } } else - n1 = this->input_argument_->name(); - name = dirpath.find(n1, n2, &this->is_in_sysroot_, pindex); + n1 = input_argument->name(); + + if (try_extra_search_path(pindex, input_argument, n1, found_name, namep)) + return true; + + if (!n2.empty() && try_extra_search_path(pindex, input_argument, n2, + found_name, namep)) + return true; + + // It is not in the extra_search_path. + name = dirpath.find(n1, n2, is_in_sysroot, pindex); if (name.empty()) { gold_error(_("cannot find %s%s"), - this->input_argument_->is_lib() ? "-l" : "", - this->input_argument_->name()); + input_argument->is_lib() ? "-l" : "", + input_argument->name()); return false; } if (n2.empty() || name[name.length() - 1] == 'o') - this->found_name_ = n1; + *found_name = n1; else - this->found_name_ = n2; + *found_name = n2; + *namep = name; + return true; } // 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 (*pindex > 0 || ::stat(name.c_str(), &dummy_stat) < 0) + gold_assert(input_argument->extra_search_path() != NULL); + + if (try_extra_search_path(pindex, input_argument, input_argument->name(), + found_name, namep)) + return true; + + // extra_search_path failed, so check the normal search-path. + int index = *pindex; + if (index > 0) + --index; + name = dirpath.find(input_argument->name(), "", + is_in_sysroot, &index); + if (name.empty()) { - // extra_search_path failed, so check the normal search-path. - int index = *pindex; - if (index > 0) - --index; - name = dirpath.find(this->input_argument_->name(), "", - &this->is_in_sysroot_, &index); - if (name.empty()) - { - gold_error(_("cannot find %s"), - this->input_argument_->name()); - return false; - } - *pindex = index + 1; + gold_error(_("cannot find %s"), + input_argument->name()); + return false; } - this->found_name_ = this->input_argument_->name(); + *pindex = index + 1; + return true; } +} + +// Open the file. + +bool +Input_file::open(const Dirsearch& dirpath, const Task* task, int *pindex) +{ + std::string name; + if (!find_file(dirpath, pindex, this->input_argument_, &this->is_in_sysroot_, + &this->found_name_, &name)) + return false; // Now that we've figured out where the file lives, try to open it. diff --git a/gold/plugin.cc b/gold/plugin.cc index 1c33b125ee..c9e55effcb 100644 --- a/gold/plugin.cc +++ b/gold/plugin.cc @@ -80,6 +80,9 @@ add_input_file(const char *pathname); static enum ld_plugin_status add_input_library(const char *pathname); +static enum ld_plugin_status +set_extra_library_path(const char *path); + static enum ld_plugin_status message(int level, const char *format, ...); @@ -127,7 +130,7 @@ Plugin::load() sscanf(ver, "%d.%d", &major, &minor); // Allocate and populate a transfer vector. - const int tv_fixed_size = 15; + const int tv_fixed_size = 16; int tv_size = this->args_.size() + tv_fixed_size; ld_plugin_tv *tv = new ld_plugin_tv[tv_size]; @@ -201,6 +204,10 @@ Plugin::load() tv[i].tv_tag = LDPT_ADD_INPUT_LIBRARY; tv[i].tv_u.tv_add_input_library = add_input_library; + ++i; + tv[i].tv_tag = LDPT_SET_EXTRA_LIBRARY_PATH; + tv[i].tv_u.tv_set_extra_library_path = set_extra_library_path; + ++i; tv[i].tv_tag = LDPT_NULL; tv[i].tv_u.tv_val = 0; @@ -418,6 +425,15 @@ Plugin_manager::release_input_file(unsigned int handle) return LDPS_OK; } +// Add a new library path. + +ld_plugin_status +Plugin_manager::set_extra_library_path(const char *path) +{ + this->extra_search_path_ = std::string(path); + return LDPS_OK; +} + // Add a new input file. ld_plugin_status @@ -427,7 +443,11 @@ Plugin_manager::add_input_file(const char *pathname, bool is_lib) (is_lib ? Input_file_argument::INPUT_FILE_TYPE_LIBRARY : Input_file_argument::INPUT_FILE_TYPE_FILE), - "", false, this->options_); + (is_lib + ? this->extra_search_path_.c_str() + : ""), + false, + this->options_); Input_argument* input_argument = new Input_argument(file); Task_token* next_blocker = new Task_token(true); next_blocker->add_blocker(); @@ -1038,6 +1058,16 @@ add_input_library(const char *pathname) return parameters->options().plugins()->add_input_file(pathname, true); } +// Set the extra library path to be used by libraries added via +// add_input_library + +static enum ld_plugin_status +set_extra_library_path(const char *path) +{ + gold_assert(parameters->options().has_plugins()); + return parameters->options().plugins()->set_extra_library_path(path); +} + // Issue a diagnostic message from a plugin. static enum ld_plugin_status diff --git a/gold/plugin.h b/gold/plugin.h index 99e6d957f4..81c3be6508 100644 --- a/gold/plugin.h +++ b/gold/plugin.h @@ -127,7 +127,7 @@ class Plugin_manager plugin_input_file_(), in_replacement_phase_(false), options_(options), workqueue_(NULL), task_(NULL), input_objects_(NULL), symtab_(NULL), layout_(NULL), dirpath_(NULL), mapfile_(NULL), - this_blocker_(NULL) + this_blocker_(NULL), extra_search_path_() { this->current_ = plugins_.end(); } ~Plugin_manager(); @@ -232,6 +232,10 @@ class Plugin_manager ld_plugin_status add_input_file(const char *pathname, bool is_lib); + // Set the extra library path. + ld_plugin_status + set_extra_library_path(const char *path); + // Return TRUE if we are in the replacement phase. bool in_replacement_phase() const @@ -275,6 +279,10 @@ class Plugin_manager Dirsearch* dirpath_; Mapfile* mapfile_; Task_token* this_blocker_; + + // An extra directory to seach for the libraries passed by + // add_input_library. + std::string extra_search_path_; }; diff --git a/include/ChangeLog b/include/ChangeLog index decb57ad0a..f4191af5fe 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,9 @@ +2010-06-21 Rafael Espindola + + * plugin-api.h (ld_plugin_set_extra_library_path): New. + (ld_plugin_tag): Add LDPT_SET_EXTRA_LIBRARY_PATH. + (ld_plugin_tv): Add tv_set_extra_library_path. + 2010-06-21 Jakub Jelinek * dwarf2.h (enum dwarf_type): Add DW_ATE_UTF. diff --git a/include/plugin-api.h b/include/plugin-api.h index 55cfe25789..a0cf5f4583 100644 --- a/include/plugin-api.h +++ b/include/plugin-api.h @@ -228,6 +228,12 @@ typedef enum ld_plugin_status (*ld_plugin_add_input_library) (const char *libname); +/* The linker's interface for adding a library path that should be searched. */ + +typedef +enum ld_plugin_status +(*ld_plugin_set_extra_library_path) (const char *path); + /* The linker's interface for issuing a warning or error message. */ typedef @@ -261,7 +267,8 @@ enum ld_plugin_tag LDPT_GET_INPUT_FILE, LDPT_RELEASE_INPUT_FILE, LDPT_ADD_INPUT_LIBRARY, - LDPT_OUTPUT_NAME + LDPT_OUTPUT_NAME, + LDPT_SET_EXTRA_LIBRARY_PATH }; /* The plugin transfer vector. */ @@ -283,6 +290,7 @@ struct ld_plugin_tv ld_plugin_get_input_file tv_get_input_file; ld_plugin_release_input_file tv_release_input_file; ld_plugin_add_input_library tv_add_input_library; + ld_plugin_set_extra_library_path tv_set_extra_library_path; } tv_u; }; -- 2.34.1