From ad2d6943a49fa11ba1e23749973c75feb12dcf6b Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Thu, 4 Oct 2007 05:49:04 +0000 Subject: [PATCH] Full support for --sysroot. --- gold/Makefile.am | 7 ++- gold/Makefile.in | 13 +++-- gold/config.in | 6 +++ gold/configure | 43 +++++++++++++++ gold/configure.ac | 27 ++++++++++ gold/dirsearch.cc | 46 ++++++++-------- gold/dirsearch.h | 19 ++++--- gold/fileread.cc | 7 +-- gold/fileread.h | 11 +++- gold/layout.cc | 6 +-- gold/main.cc | 2 +- gold/options.cc | 132 ++++++++++++++++++++++++++++++++++++++++++--- gold/options.h | 72 +++++++++++++++++++++++-- gold/parameters.cc | 3 +- gold/parameters.h | 9 ++++ gold/script.cc | 56 +++++++++++++++---- gold/testsuite/Makefile.am | 4 +- gold/testsuite/Makefile.in | 41 +++++++++----- 18 files changed, 420 insertions(+), 84 deletions(-) diff --git a/gold/Makefile.am b/gold/Makefile.am index bb5d3f6..f61dac3 100644 --- a/gold/Makefile.am +++ b/gold/Makefile.am @@ -13,8 +13,11 @@ AM_CXXFLAGS = $(WARN_CXXFLAGS) $(LFS_CXXFLAGS) INCLUDES = -D_GNU_SOURCE \ -I$(srcdir) -I$(srcdir)/../include -I$(srcdir)/../elfcpp \ -DLOCALEDIR="\"$(datadir)/locale\"" \ + -DBINDIR="\"$(bindir)\"" -DTOOLBINDIR="\"$(tooldir)/bin\"" \ @INCINTL@ +LIBIBERTY = ../libiberty/libiberty.a + AM_YFLAGS = -d noinst_PROGRAMS = ld-new @@ -87,8 +90,8 @@ ALL_TARGETOBJS = \ libgold_a_SOURCES = $(CCFILES) $(HFILES) $(YFILES) sources_var = main.cc -deps_var = $(TARGETOBJS) libgold.a $(LIBINTL_DEP) -ldadd_var = $(TARGETOBJS) libgold.a $(LIBINTL) +deps_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL_DEP) +ldadd_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL) ld_new_SOURCES = $(sources_var) ld_new_DEPENDENCIES = $(deps_var) $(LIBOBJS) diff --git a/gold/Makefile.in b/gold/Makefile.in index 168849e..a2e4100 100644 --- a/gold/Makefile.in +++ b/gold/Makefile.in @@ -88,9 +88,10 @@ am__objects_4 = main.$(OBJEXT) am_ld_new_OBJECTS = $(am__objects_4) ld_new_OBJECTS = $(am_ld_new_OBJECTS) am__DEPENDENCIES_1 = -am__DEPENDENCIES_2 = $(am__DEPENDENCIES_1) libgold.a \ - $(am__DEPENDENCIES_1) -am__DEPENDENCIES_3 = @LIBOBJS@ +am__DEPENDENCIES_2 = ../libiberty/libiberty.a +am__DEPENDENCIES_3 = $(am__DEPENDENCIES_1) libgold.a \ + $(am__DEPENDENCIES_2) $(am__DEPENDENCIES_1) +am__DEPENDENCIES_4 = @LIBOBJS@ am__ld1_SOURCES_DIST = main.cc @GCC_TRUE@@NATIVE_LINKER_TRUE@am_ld1_OBJECTS = $(am__objects_4) ld1_OBJECTS = $(am_ld1_OBJECTS) @@ -265,8 +266,10 @@ AM_CXXFLAGS = $(WARN_CXXFLAGS) $(LFS_CXXFLAGS) INCLUDES = -D_GNU_SOURCE \ -I$(srcdir) -I$(srcdir)/../include -I$(srcdir)/../elfcpp \ -DLOCALEDIR="\"$(datadir)/locale\"" \ + -DBINDIR="\"$(bindir)\"" -DTOOLBINDIR="\"$(tooldir)/bin\"" \ @INCINTL@ +LIBIBERTY = ../libiberty/libiberty.a AM_YFLAGS = -d noinst_LIBRARIES = libgold.a CCFILES = \ @@ -334,8 +337,8 @@ ALL_TARGETOBJS = \ libgold_a_SOURCES = $(CCFILES) $(HFILES) $(YFILES) sources_var = main.cc -deps_var = $(TARGETOBJS) libgold.a $(LIBINTL_DEP) -ldadd_var = $(TARGETOBJS) libgold.a $(LIBINTL) +deps_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL_DEP) +ldadd_var = $(TARGETOBJS) libgold.a $(LIBIBERTY) $(LIBINTL) ld_new_SOURCES = $(sources_var) ld_new_DEPENDENCIES = $(deps_var) $(LIBOBJS) ld_new_LDADD = $(ldadd_var) $(LIBOBJS) diff --git a/gold/config.in b/gold/config.in index bbdf051..46d67e5 100644 --- a/gold/config.in +++ b/gold/config.in @@ -82,6 +82,12 @@ /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS +/* System root for target files */ +#undef TARGET_SYSTEM_ROOT + +/* Whether the system root can be relocated */ +#undef TARGET_SYSTEM_ROOT_RELOCATABLE + /* Version number of package */ #undef VERSION diff --git a/gold/configure b/gold/configure index 7bf0364..f7192cd 100755 --- a/gold/configure +++ b/gold/configure @@ -867,6 +867,11 @@ Optional Features: --enable-maintainer-mode enable make rules and dependencies not useful (and sometimes confusing) to the casual installer +Optional Packages: + --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] + --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) + --with-sysroot=DIR search for usr/lib et al within DIR + Some influential environment variables: CC C compiler command CFLAGS C compiler flags @@ -1842,6 +1847,44 @@ am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -' ac_config_headers="$ac_config_headers config.h:config.in" + +# Check whether --with-sysroot or --without-sysroot was given. +if test "${with_sysroot+set}" = set; then + withval="$with_sysroot" + sysroot=$withval +else + sysroot=no +fi; + +if test "$sysroot" = "yes"; then + sysroot='${exec_prefix}/${target_alias}/sys-root' +elif test "$sysroot" = "no"; then + sysroot= +fi + +sysroot_relocatable=0 +if test -n "$sysroot"; then + case "sysroot" in + "${prefix}" | "${prefix}/"* | \ + "${exec_prefix}" | "${exec_prefix}/"* | \ + '${prefix}' | '${prefix}/'*| \ + '${exec_prefix}' | '${exec_prefix}/'*) + sysroot_relocatable=1 + ;; + esac +fi + + +cat >>confdefs.h <<_ACEOF +#define TARGET_SYSTEM_ROOT "$sysroot" +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define TARGET_SYSTEM_ROOT_RELOCATABLE $sysroot_relocatable +_ACEOF + + # Check whether --enable-targets or --disable-targets was given. if test "${enable_targets+set}" = set; then enableval="$enable_targets" diff --git a/gold/configure.ac b/gold/configure.ac index 4efe83d..d01ab91 100644 --- a/gold/configure.ac +++ b/gold/configure.ac @@ -10,6 +10,33 @@ AM_INIT_AUTOMAKE(gold, 0.1) AM_CONFIG_HEADER(config.h:config.in) +AC_ARG_WITH(sysroot, +[ --with-sysroot[=DIR] search for usr/lib et al within DIR], +[sysroot=$withval], [sysroot=no]) + +if test "$sysroot" = "yes"; then + sysroot='${exec_prefix}/${target_alias}/sys-root' +elif test "$sysroot" = "no"; then + sysroot= +fi + +sysroot_relocatable=0 +if test -n "$sysroot"; then + case "sysroot" in + "${prefix}" | "${prefix}/"* | \ + "${exec_prefix}" | "${exec_prefix}/"* | \ + '${prefix}' | '${prefix}/'*| \ + '${exec_prefix}' | '${exec_prefix}/'*) + sysroot_relocatable=1 + ;; + esac +fi + +AC_DEFINE_UNQUOTED(TARGET_SYSTEM_ROOT, "$sysroot", + [System root for target files]) +AC_DEFINE_UNQUOTED(TARGET_SYSTEM_ROOT_RELOCATABLE, $sysroot_relocatable, + [Whether the system root can be relocated]) + AC_ARG_ENABLE([targets], [ --enable-targets alternative target configurations], [case "${enableval}" in diff --git a/gold/dirsearch.cc b/gold/dirsearch.cc index 8965903..6dea53d 100644 --- a/gold/dirsearch.cc +++ b/gold/dirsearch.cc @@ -211,43 +211,43 @@ Dir_cache_task::run(gold::Workqueue*) namespace gold { -Dirsearch::Dirsearch() - : directories_(), token_() -{ -} - void -Dirsearch::add(Workqueue* workqueue, const char* d) +Dirsearch::initialize(Workqueue* workqueue, + const General_options::Dir_list* directories) { - this->directories_.push_back(d); - this->token_.add_blocker(); - workqueue->queue(new Dir_cache_task(d, this->token_)); -} - -void -Dirsearch::add(Workqueue* workqueue, const General_options::Dir_list& list) -{ - for (General_options::Dir_list::const_iterator p = list.begin(); - p != list.end(); + this->directories_ = directories; + for (General_options::Dir_list::const_iterator p = directories->begin(); + p != directories->end(); ++p) - this->add(workqueue, *p); + { + this->token_.add_blocker(); + workqueue->queue(new Dir_cache_task(p->name().c_str(), this->token_)); + } } std::string -Dirsearch::find(const std::string& n1, const std::string& n2) const +Dirsearch::find(const std::string& n1, const std::string& n2, + bool *is_in_sysroot) const { gold_assert(!this->token_.is_blocked()); - for (std::list::const_iterator p = this->directories_.begin(); - p != this->directories_.end(); + for (General_options::Dir_list::const_iterator p = + this->directories_->begin(); + p != this->directories_->end(); ++p) { - Dir_cache* pdc = caches.lookup(*p); + Dir_cache* pdc = caches.lookup(p->name().c_str()); gold_assert(pdc != NULL); if (pdc->find(n1)) - return std::string(*p) + '/' + n1; + { + *is_in_sysroot = p->is_in_sysroot(); + return p->name() + '/' + n1; + } if (!n2.empty() && pdc->find(n2)) - return std::string(*p) + '/' + n2; + { + *is_in_sysroot = p->is_in_sysroot(); + return p->name() + '/' + n2; + } } return std::string(); diff --git a/gold/dirsearch.h b/gold/dirsearch.h index 8b5a91e..c1af843 100644 --- a/gold/dirsearch.h +++ b/gold/dirsearch.h @@ -39,22 +39,21 @@ class General_options; class Dirsearch { public: - Dirsearch(); + Dirsearch() + : directories_(NULL), token_() + { } - // Add a directory to the search path. + // Set the list of directories to search. void - add(Workqueue*, const char*); - - // Add a list of directories to the search path. - void - add(Workqueue*, const General_options::Dir_list&); + initialize(Workqueue*, const General_options::Dir_list*); // Search for a file, giving one or two names to search for (the // second one may be empty). Return a full path name for the file, // or the empty string if it could not be found. This may only be - // called if the token is not blocked. + // called if the token is not blocked. Set *IS_IN_SYSROOT if the + // file was found in a directory which is in the sysroot. std::string - find(const std::string&, const std::string& n2 = std::string()) const; + find(const std::string&, const std::string& n2, bool *is_in_sysroot) const; // Return a reference to the blocker token which controls access. const Task_token& @@ -67,7 +66,7 @@ class Dirsearch Dirsearch& operator=(const Dirsearch&); // Directories to search. - std::list directories_; + const General_options::Dir_list* directories_; // Blocker token to control access from tasks. Task_token token_; }; diff --git a/gold/fileread.cc b/gold/fileread.cc index 9e6cd90..1bbd841 100644 --- a/gold/fileread.cc +++ b/gold/fileread.cc @@ -414,10 +414,10 @@ Input_file::open(const General_options& options, const Dirsearch& dirpath) n2 = n1 + ".a"; n1 += ".so"; } - name = dirpath.find(n1, n2); + name = dirpath.find(n1, n2, &this->is_in_sysroot_); if (name.empty()) { - fprintf(stderr, _("%s: cannot find %s\n"), program_name, + fprintf(stderr, _("%s: cannot find -l%s\n"), program_name, this->input_argument_->name()); gold_exit(false); } @@ -437,7 +437,8 @@ Input_file::open(const General_options& options, const Dirsearch& dirpath) 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(), ""); + name = dirpath.find(this->input_argument_->name(), "", + &this->is_in_sysroot_); if (name.empty()) { fprintf(stderr, _("%s: cannot find %s\n"), program_name, diff --git a/gold/fileread.h b/gold/fileread.h index cda5d9c..abeb28e 100644 --- a/gold/fileread.h +++ b/gold/fileread.h @@ -260,7 +260,7 @@ class Input_file { public: Input_file(const Input_file_argument* input_argument) - : input_argument_(input_argument), file_() + : input_argument_(input_argument), file_(), is_in_sysroot_(false) { } // Create an input file with the contents already provided. This is @@ -292,12 +292,21 @@ class Input_file file() { return this->file_; } + // Whether we found the file in a directory in the system root. + bool + is_in_sysroot() const + { return this->is_in_sysroot_; } + private: Input_file(const Input_file&); Input_file& operator=(const Input_file&); + // The argument from the command line. const Input_file_argument* input_argument_; + // The file after we open it. File_read file_; + // Whether we found the file in a directory in the system root. + bool is_in_sysroot_; }; } // end namespace gold diff --git a/gold/layout.cc b/gold/layout.cc index 9dad4b0..e878456 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -1309,18 +1309,18 @@ Layout::finish_dynamic_section(const Input_objects* input_objects, ++p) { if (rpath_val.empty()) - rpath_val = *p; + rpath_val = p->name(); else { // Eliminate duplicates. General_options::Dir_list::const_iterator q; for (q = rpath.begin(); q != p; ++q) - if (strcmp(*q, *p) == 0) + if (q->name() == p->name()) break; if (q == p) { rpath_val += ':'; - rpath_val += *p; + rpath_val += p->name(); } } } diff --git a/gold/main.cc b/gold/main.cc index e1135e9..ccd958d 100644 --- a/gold/main.cc +++ b/gold/main.cc @@ -65,7 +65,7 @@ main(int argc, char** argv) // Get the search path from the -L options. Dirsearch search_path; - search_path.add(&workqueue, command_line.options().search_path()); + search_path.initialize(&workqueue, &command_line.options().search_path()); // Queue up the first set of tasks. queue_initial_tasks(command_line.options(), search_path, diff --git a/gold/options.cc b/gold/options.cc index 4df21b0..f49b9f5 100644 --- a/gold/options.cc +++ b/gold/options.cc @@ -20,9 +20,13 @@ // Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, // MA 02110-1301, USA. +#include "gold.h" + #include +#include +#include "filenames.h" +#include "libiberty.h" -#include "gold.h" #include "options.h" namespace gold @@ -216,6 +220,51 @@ help(int, char**, char*, gold::Command_line*) return 0; } +// If the default sysroot is relocatable, try relocating it based on +// the prefix FROM. + +char* +get_relative_sysroot(const char* from) +{ + char* path = make_relative_prefix(gold::program_name, from, + TARGET_SYSTEM_ROOT); + if (path != NULL) + { + struct stat s; + if (::stat(path, &s) == 0 && S_ISDIR(s.st_mode)) + return path; + free(path); + } + + return NULL; +} + +// Return the default sysroot. This is set by the --with-sysroot +// option to configure. + +std::string +get_default_sysroot() +{ + const char* sysroot = TARGET_SYSTEM_ROOT; + if (*sysroot == '\0') + return ""; + + if (TARGET_SYSTEM_ROOT_RELOCATABLE) + { + char* path = get_relative_sysroot (BINDIR); + if (path == NULL) + path = get_relative_sysroot (TOOLBINDIR); + if (path != NULL) + { + std::string ret = path; + free(path); + return ret; + } + } + + return sysroot; +} + } // End anonymous namespace. namespace gold @@ -285,8 +334,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), + GENERAL_ARG('\0', "sysroot", N_("Set target system root directory"), + N_("--sysroot DIR"), TWO_DASHES, &General_options::set_sysroot), POSDEP_NOARG('\0', "as-needed", N_("Only set DT_NEEDED for dynamic libs if used"), NULL, TWO_DASHES, &Position_dependent_options::set_as_needed), @@ -321,7 +370,8 @@ General_options::General_options() rpath_(), rpath_link_(), is_shared_(false), - is_static_(false) + is_static_(false), + sysroot_() { } @@ -334,6 +384,66 @@ Position_dependent_options::Position_dependent_options() { } +// Add the sysroot, if any, to the search paths. + +void +General_options::add_sysroot() +{ + if (this->sysroot_.empty()) + { + this->sysroot_ = get_default_sysroot(); + if (this->sysroot_.empty()) + return; + } + + const char* sysroot = this->sysroot_.c_str(); + char* canonical_sysroot = lrealpath(sysroot); + + for (Dir_list::iterator p = this->search_path_.begin(); + p != this->search_path_.end(); + ++p) + p->add_sysroot(sysroot, canonical_sysroot); + + free(canonical_sysroot); +} + +// Search_directory methods. + +// This is called if we have a sysroot. Apply the sysroot if +// appropriate. Record whether the directory is in the sysroot. + +void +Search_directory::add_sysroot(const char* sysroot, + const char* canonical_sysroot) +{ + gold_assert(*sysroot != '\0'); + if (this->put_in_sysroot_) + { + if (!IS_DIR_SEPARATOR(this->name_[0]) + && !IS_DIR_SEPARATOR(sysroot[strlen(sysroot) - 1])) + this->name_ = '/' + this->name_; + this->name_ = sysroot + this->name_; + this->is_in_sysroot_ = true; + } + else + { + // Check whether this entry is in the sysroot. To do this + // correctly, we need to use canonical names. Otherwise we will + // get confused by the ../../.. paths that gcc tends to use. + char* canonical_name = lrealpath(this->name_.c_str()); + int canonical_name_len = strlen(canonical_name); + int canonical_sysroot_len = strlen(canonical_sysroot); + if (canonical_name_len > canonical_sysroot_len + && IS_DIR_SEPARATOR(canonical_name[canonical_sysroot_len])) + { + canonical_name[canonical_sysroot_len] = '\0'; + if (FILENAME_CMP(canonical_name, canonical_sysroot) == 0) + this->is_in_sysroot_ = true; + } + free(canonical_name); + } +} + // Input_arguments methods. // Add a file to the list. @@ -414,8 +524,12 @@ Command_line::process(int argc, char** argv) char first = opt[0]; int skiparg = 0; char* arg = strchr(opt, '='); + bool argument_with_equals = arg != NULL; if (arg != NULL) - *arg = '\0'; + { + *arg = '\0'; + ++arg; + } else if (i + 1 < argc) { arg = argv[i + 1]; @@ -438,6 +552,8 @@ Command_line::process(int argc, char** argv) { if (!options[j].takes_argument()) { + if (argument_with_equals) + this->usage(_("unexpected argument"), argv[i]); arg = NULL; skiparg = 0; } @@ -517,8 +633,10 @@ Command_line::process(int argc, char** argv) } // FIXME: We should only do this when configured in native mode. - this->options_.add_to_search_path("/lib"); - this->options_.add_to_search_path("/usr/lib"); + this->options_.add_to_search_path_with_sysroot("/lib"); + this->options_.add_to_search_path_with_sysroot("/usr/lib"); + + this->options_.add_sysroot(); } // Apply a command line option. diff --git a/gold/options.h b/gold/options.h index 3b7c051..159e7b2 100644 --- a/gold/options.h +++ b/gold/options.h @@ -50,6 +50,50 @@ struct One_option; } // End namespace gold::options. +// A directory to search. For each directory we record whether it is +// in the sysroot. We need to know this so that, if a linker script +// is found within the sysroot, we will apply the sysroot to any files +// named by that script. + +class Search_directory +{ + public: + // We need a default constructor because we put this in a + // std::vector. + Search_directory() + : name_(NULL), put_in_sysroot_(false), is_in_sysroot_(false) + { } + + // This is the usual constructor. + Search_directory(const char* name, bool put_in_sysroot) + : name_(name), put_in_sysroot_(put_in_sysroot), is_in_sysroot_(false) + { gold_assert(!this->name_.empty()); } + + // This is called if we have a sysroot. The sysroot is prefixed to + // any entries for which put_in_sysroot_ is true. is_in_sysroot_ is + // set to true for any enries which are in the sysroot (this will + // naturally include any entries for which put_in_sysroot_ is true). + // SYSROOT is the sysroot, CANONICAL_SYSROOT is the result of + // passing SYSROOT to lrealpath. + void + add_sysroot(const char* sysroot, const char* canonical_sysroot); + + // Get the directory name. + const std::string& + name() const + { return this->name_; } + + // Return whether this directory is in the sysroot. + bool + is_in_sysroot() const + { return this->is_in_sysroot_; } + + private: + std::string name_; + bool put_in_sysroot_; + bool is_in_sysroot_; +}; + // The position independent options which apply to the whole link. // There are a lot of them. @@ -69,7 +113,7 @@ class General_options { return this->dynamic_linker_; } // -L: Library search path. - typedef std::vector Dir_list; + typedef std::vector Dir_list; const Dir_list& search_path() const @@ -115,6 +159,11 @@ class General_options is_static() const { return this->is_static_; } + // --sysroot: The system root of a cross-linker. + const std::string& + sysroot() const + { return this->sysroot_; } + private: // Don't copy this structure. General_options(const General_options&); @@ -133,7 +182,11 @@ class General_options void add_to_search_path(const char* arg) - { this->search_path_.push_back(arg); } + { this->search_path_.push_back(Search_directory(arg, false)); } + + void + add_to_search_path_with_sysroot(const char* arg) + { this->search_path_.push_back(Search_directory(arg, true)); } void set_optimization_level(const char* arg) @@ -153,11 +206,11 @@ class General_options void add_to_rpath(const char* arg) - { this->rpath_.push_back(arg); } + { this->rpath_.push_back(Search_directory(arg, false)); } void add_to_rpath_link(const char* arg) - { this->rpath_link_.push_back(arg); } + { this->rpath_link_.push_back(Search_directory(arg, false)); } void set_shared() @@ -168,9 +221,17 @@ class General_options { this->is_static_ = true; } void + set_sysroot(const char* arg) + { this->sysroot_ = arg; } + + void ignore(const char*) { } + // Apply any sysroot to the directory lists. + void + add_sysroot(); + bool export_dynamic_; const char* dynamic_linker_; Dir_list search_path_; @@ -182,6 +243,7 @@ class General_options Dir_list rpath_link_; bool is_shared_; bool is_static_; + std::string sysroot_; }; // The current state of the position dependent options. @@ -251,7 +313,7 @@ class Input_file_argument // 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. + // command line, such as --whole-archive. Input_file_argument() : name_(), is_lib_(false), extra_search_path_(""), options_() { } diff --git a/gold/parameters.cc b/gold/parameters.cc index 0c38ef7..3c7cf28 100644 --- a/gold/parameters.cc +++ b/gold/parameters.cc @@ -31,7 +31,8 @@ namespace gold // Initialize the parameters from the options. Parameters::Parameters(const General_options* options) - : is_doing_static_link_valid_(false), doing_static_link_(false), + : sysroot_(options->sysroot()), + is_doing_static_link_valid_(false), doing_static_link_(false), is_size_and_endian_valid_(false), size_(0), is_big_endian_(false), optimization_level_(options->optimization_level()) { diff --git a/gold/parameters.h b/gold/parameters.h index 2a21607..a150981 100644 --- a/gold/parameters.h +++ b/gold/parameters.h @@ -56,6 +56,12 @@ class Parameters output_is_object() const { return this->output_file_type_ == OUTPUT_OBJECT; } + // The target system root directory. This is NULL if there isn't + // one. + const std::string& + sysroot() const + { return this->sysroot_; } + // Whether we are doing a static link--a link in which none of the // input files are shared libraries. This is only known after we // have seen all the input files. @@ -110,6 +116,9 @@ class Parameters // The type of the output file. Output_file_type output_file_type_; + // The target system root directory. + std::string sysroot_; + // Whether the doing_static_link_ field is valid. bool is_doing_static_link_valid_; // Whether we are doing a static link. diff --git a/gold/script.cc b/gold/script.cc index b003add..365cedf 100644 --- a/gold/script.cc +++ b/gold/script.cc @@ -26,11 +26,13 @@ #include #include #include +#include "filenames.h" #include "options.h" #include "fileread.h" #include "workqueue.h" #include "readsyms.h" +#include "parameters.h" #include "yyscript.h" #include "script.h" #include "script-c.h" @@ -827,10 +829,10 @@ class Parser_closure public: Parser_closure(const char* filename, const Position_dependent_options& posdep_options, - bool in_group, + bool in_group, bool is_in_sysroot, const Lex::Token_sequence* tokens) : filename_(filename), posdep_options_(posdep_options), - in_group_(in_group), tokens_(tokens), + in_group_(in_group), is_in_sysroot_(is_in_sysroot), tokens_(tokens), next_token_index_(0), inputs_(NULL) { } @@ -850,6 +852,12 @@ class Parser_closure in_group() const { return this->in_group_; } + // Return whether this script was found using a directory in the + // sysroot. + bool + is_in_sysroot() const + { return this->is_in_sysroot_; } + // Whether we are at the end of the token list. bool at_eof() const @@ -886,6 +894,8 @@ class Parser_closure Position_dependent_options posdep_options_; // Whether we are currently in a --start-group/--end-group. bool in_group_; + // Whether the script was found in a sysrooted directory. + bool is_in_sysroot_; // The tokens to be returned by the lexer. const Lex::Token_sequence* tokens_; @@ -915,6 +925,7 @@ read_input_script(Workqueue* workqueue, const General_options& options, Parser_closure closure(input_file->filename().c_str(), input_argument->file().options(), input_group != NULL, + input_file->is_in_sysroot(), &lex.tokens()); if (yyparse(&closure) != 0) @@ -1166,14 +1177,39 @@ extern "C" void script_add_file(void* closurev, const char* name) { Parser_closure* closure = static_cast(closurev); - // 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()); + + // If this is an absolute path, and we found the script in the + // sysroot, then we want to prepend the sysroot to the file name. + // For example, this is how we handle a cross link to the x86_64 + // libc.so, which refers to /lib/libc.so.6. + std::string name_string; + const char* extra_search_path = "."; + std::string script_directory; + if (IS_ABSOLUTE_PATH (name)) + { + if (closure->is_in_sysroot()) + { + const std::string& sysroot(parameters->sysroot()); + gold_assert(!sysroot.empty()); + name_string = sysroot + name; + name = name_string.c_str(); + } + } + else + { + // In addition to checking the normal library search path, we + // also want to check in the script-directory. + const char *slash = strrchr(closure->filename(), '/'); + if (slash != NULL) + { + script_directory.assign(closure->filename(), + slash - closure->filename() + 1); + extra_search_path = script_directory.c_str(); + } + } + + Input_file_argument file(name, false, extra_search_path, + closure->position_dependent_options()); closure->inputs()->add_file(file); } diff --git a/gold/testsuite/Makefile.am b/gold/testsuite/Makefile.am index 6054d66..b2f56dc 100644 --- a/gold/testsuite/Makefile.am +++ b/gold/testsuite/Makefile.am @@ -60,7 +60,9 @@ TESTS = object_unittest $(NATIVE_TESTING) check_LIBRARIES = libgoldtest.a libgoldtest_a_SOURCES = test.cc testmain.cc testfile.cc -LDADD = libgoldtest.a ../libgold.a +DEPENDENCIES = \ + libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL_DEP) +LDADD = libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL) check_PROGRAMS = object_unittest $(NATIVE_PROGS) diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in index 5de0c50..6cf79cc 100644 --- a/gold/testsuite/Makefile.in +++ b/gold/testsuite/Makefile.in @@ -50,23 +50,35 @@ target_triplet = @target@ @FN_PTRS_IN_SO_WITHOUT_PIC_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@ two_file_separate_shared_21_nonpic_test check_PROGRAMS = object_unittest$(EXEEXT) $(am__EXEEXT_2) -@GCC_FALSE@constructor_test_DEPENDENCIES = libgoldtest.a ../libgold.a +@GCC_FALSE@constructor_test_DEPENDENCIES = libgoldtest.a ../libgold.a \ +@GCC_FALSE@ ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) @NATIVE_LINKER_FALSE@constructor_test_DEPENDENCIES = libgoldtest.a \ -@NATIVE_LINKER_FALSE@ ../libgold.a +@NATIVE_LINKER_FALSE@ ../libgold.a ../../libiberty/libiberty.a \ +@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) @GCC_FALSE@constructor_static_test_DEPENDENCIES = libgoldtest.a \ -@GCC_FALSE@ ../libgold.a +@GCC_FALSE@ ../libgold.a ../../libiberty/libiberty.a \ +@GCC_FALSE@ $(am__DEPENDENCIES_1) @NATIVE_LINKER_FALSE@constructor_static_test_DEPENDENCIES = \ -@NATIVE_LINKER_FALSE@ libgoldtest.a ../libgold.a -@GCC_FALSE@two_file_test_DEPENDENCIES = libgoldtest.a ../libgold.a +@NATIVE_LINKER_FALSE@ libgoldtest.a ../libgold.a \ +@NATIVE_LINKER_FALSE@ ../../libiberty/libiberty.a \ +@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) +@GCC_FALSE@two_file_test_DEPENDENCIES = libgoldtest.a ../libgold.a \ +@GCC_FALSE@ ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) @NATIVE_LINKER_FALSE@two_file_test_DEPENDENCIES = libgoldtest.a \ -@NATIVE_LINKER_FALSE@ ../libgold.a -@GCC_FALSE@exception_test_DEPENDENCIES = libgoldtest.a ../libgold.a +@NATIVE_LINKER_FALSE@ ../libgold.a ../../libiberty/libiberty.a \ +@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) +@GCC_FALSE@exception_test_DEPENDENCIES = libgoldtest.a ../libgold.a \ +@GCC_FALSE@ ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) @NATIVE_LINKER_FALSE@exception_test_DEPENDENCIES = libgoldtest.a \ -@NATIVE_LINKER_FALSE@ ../libgold.a +@NATIVE_LINKER_FALSE@ ../libgold.a ../../libiberty/libiberty.a \ +@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) @GCC_FALSE@exception_static_test_DEPENDENCIES = libgoldtest.a \ -@GCC_FALSE@ ../libgold.a +@GCC_FALSE@ ../libgold.a ../../libiberty/libiberty.a \ +@GCC_FALSE@ $(am__DEPENDENCIES_1) @NATIVE_LINKER_FALSE@exception_static_test_DEPENDENCIES = \ -@NATIVE_LINKER_FALSE@ libgoldtest.a ../libgold.a +@NATIVE_LINKER_FALSE@ libgoldtest.a ../libgold.a \ +@NATIVE_LINKER_FALSE@ ../../libiberty/libiberty.a \ +@NATIVE_LINKER_FALSE@ $(am__DEPENDENCIES_1) subdir = testsuite DIST_COMMON = $(srcdir)/Makefile.am $(srcdir)/Makefile.in ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 @@ -116,6 +128,7 @@ am__constructor_static_test_SOURCES_DIST = constructor_test.cc constructor_static_test_OBJECTS = \ $(am_constructor_static_test_OBJECTS) constructor_static_test_LDADD = $(LDADD) +am__DEPENDENCIES_1 = am__constructor_test_SOURCES_DIST = constructor_test.cc @GCC_TRUE@@NATIVE_LINKER_TRUE@am_constructor_test_OBJECTS = \ @GCC_TRUE@@NATIVE_LINKER_TRUE@ constructor_test.$(OBJEXT) @@ -171,7 +184,8 @@ exception_test_LDADD = $(LDADD) am_object_unittest_OBJECTS = object_unittest.$(OBJEXT) object_unittest_OBJECTS = $(am_object_unittest_OBJECTS) object_unittest_LDADD = $(LDADD) -object_unittest_DEPENDENCIES = libgoldtest.a ../libgold.a +object_unittest_DEPENDENCIES = libgoldtest.a ../libgold.a \ + ../../libiberty/libiberty.a $(am__DEPENDENCIES_1) am__two_file_same_shared_nonpic_test_SOURCES_DIST = \ two_file_test_main.cc @FN_PTRS_IN_SO_WITHOUT_PIC_TRUE@@GCC_TRUE@@NATIVE_LINKER_TRUE@am_two_file_same_shared_nonpic_test_OBJECTS = two_file_test_main.$(OBJEXT) @@ -447,7 +461,10 @@ INCLUDES = -D_GNU_SOURCE \ TESTS = object_unittest $(NATIVE_TESTING) check_LIBRARIES = libgoldtest.a libgoldtest_a_SOURCES = test.cc testmain.cc testfile.cc -LDADD = libgoldtest.a ../libgold.a +DEPENDENCIES = \ + libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL_DEP) + +LDADD = libgoldtest.a ../libgold.a ../../libiberty/libiberty.a $(LIBINTL) object_unittest_SOURCES = object_unittest.cc @GCC_TRUE@@NATIVE_LINKER_TRUE@constructor_test_SOURCES = constructor_test.cc @GCC_TRUE@@NATIVE_LINKER_TRUE@constructor_test_DEPENDENCIES = gcctestdir/ld -- 2.7.4