diff options
author | Ian Lance Taylor <iant@google.com> | 2008-02-06 20:32:10 +0000 |
---|---|---|
committer | Ian Lance Taylor <iant@google.com> | 2008-02-06 20:32:10 +0000 |
commit | fbfba5088712eb014b9051baa71f9636359d159e (patch) | |
tree | 6836ec1f682dc1c4954429d9be124c268d530526 | |
parent | 755ab8af10558c40e5090e92c46bbbd89815c292 (diff) | |
download | fsf-binutils-gdb-fbfba5088712eb014b9051baa71f9636359d159e.zip fsf-binutils-gdb-fbfba5088712eb014b9051baa71f9636359d159e.tar.gz fsf-binutils-gdb-fbfba5088712eb014b9051baa71f9636359d159e.tar.bz2 |
Support creating empty output when there are no input objects.
-rw-r--r-- | gold/config.in | 9 | ||||
-rwxr-xr-x | gold/configure | 76 | ||||
-rw-r--r-- | gold/configure.ac | 61 | ||||
-rw-r--r-- | gold/configure.tgt | 55 | ||||
-rw-r--r-- | gold/gold.cc | 20 | ||||
-rw-r--r-- | gold/layout.cc | 2 | ||||
-rw-r--r-- | gold/object.cc | 11 | ||||
-rw-r--r-- | gold/object.h | 10 | ||||
-rw-r--r-- | gold/parameters.h | 5 | ||||
-rw-r--r-- | gold/symtab.cc | 4 |
10 files changed, 198 insertions, 55 deletions
diff --git a/gold/config.in b/gold/config.in index 9c0db95..4dc6141 100644 --- a/gold/config.in +++ b/gold/config.in @@ -7,6 +7,15 @@ /* Define to do multi-threaded linking */ #undef ENABLE_THREADS +/* Default big endian (true or false) */ +#undef GOLD_DEFAULT_BIG_ENDIAN + +/* Default machine code */ +#undef GOLD_DEFAULT_MACHINE + +/* Default size (32 or 64) */ +#undef GOLD_DEFAULT_SIZE + /* Define to 1 if you have the <ext/hash_map> header file. */ #undef HAVE_EXT_HASH_MAP diff --git a/gold/configure b/gold/configure index ef56ef5..d2006a3 100755 --- a/gold/configure +++ b/gold/configure @@ -1970,11 +1970,14 @@ fi # See which specific instantiations we need. targetobjs= all_targets= +default_machine= +default_size= +default_big_endian= +targ_32_little= +targ_32_big= +targ_64_little= +targ_64_big= for targ in $target $canon_targets; do - targ_32_little= - targ_32_big= - targ_64_little= - targ_64_big= if test "$targ" = "all"; then targ_32_little=yes targ_32_big=yes @@ -1982,21 +1985,46 @@ for targ in $target $canon_targets; do targ_64_big=yes all_targets=yes else - case "$targ" in - i?86-*) - targ_32_little=yes - targetobjs="$targetobjs i386.\$(OBJEXT)" - ;; - x86_64-*) - targ_64_little=yes - targetobjs="$targetobjs x86_64.\$(OBJEXT)" - ;; - *) + . ${srcdir}/configure.tgt + + if test "$targ_obj" = "UNKNOWN"; then { { echo "$as_me:$LINENO: error: \"unsupported target $targ\"" >&5 echo "$as_me: error: \"unsupported target $targ\"" >&2;} { (exit 1); exit 1; }; } - ;; - esac + else + targetobjs="$targetobjs ${targ_obj}.\$(OBJEXT)" + if test "$targ_size" = "32"; then + if test "$targ_big_endian" = "false"; then + targ_32_little=yes + elif test "$targ_big_endian" = "true"; then + targ_32_big=yes + else + { { echo "$as_me:$LINENO: error: \"bad configure.tgt endian $targ_big_endian\"" >&5 +echo "$as_me: error: \"bad configure.tgt endian $targ_big_endian\"" >&2;} + { (exit 1); exit 1; }; } + fi + elif test "$targ_size" = "64"; then + if test "$targ_big_endian" = "false"; then + targ_64_little=yes + elif test "$targ_big_endian" = "true"; then + targ_64_big=yes + else + { { echo "$as_me:$LINENO: error: \"bad configure.tgt endian $targ_big_endian\"" >&5 +echo "$as_me: error: \"bad configure.tgt endian $targ_big_endian\"" >&2;} + { (exit 1); exit 1; }; } + fi + else + { { echo "$as_me:$LINENO: error: \"bad configure.tgt size $targ_size\"" >&5 +echo "$as_me: error: \"bad configure.tgt size $targ_size\"" >&2;} + { (exit 1); exit 1; }; } + fi + + if test "$target" = "$targ"; then + default_machine=$targ_machine + default_size=$targ_size + default_big_endian=$targ_big_endian + fi + fi fi done @@ -2036,6 +2064,22 @@ else fi + +cat >>confdefs.h <<_ACEOF +#define GOLD_DEFAULT_MACHINE $default_machine +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define GOLD_DEFAULT_SIZE $default_size +_ACEOF + + +cat >>confdefs.h <<_ACEOF +#define GOLD_DEFAULT_BIG_ENDIAN $default_big_endian +_ACEOF + + ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' diff --git a/gold/configure.ac b/gold/configure.ac index 62fdaab..c719e78 100644 --- a/gold/configure.ac +++ b/gold/configure.ac @@ -86,11 +86,14 @@ fi # See which specific instantiations we need. targetobjs= all_targets= +default_machine= +default_size= +default_big_endian= +targ_32_little= +targ_32_big= +targ_64_little= +targ_64_big= for targ in $target $canon_targets; do - targ_32_little= - targ_32_big= - targ_64_little= - targ_64_big= if test "$targ" = "all"; then targ_32_little=yes targ_32_big=yes @@ -98,19 +101,38 @@ for targ in $target $canon_targets; do targ_64_big=yes all_targets=yes else - case "$targ" in - i?86-*) - targ_32_little=yes - targetobjs="$targetobjs i386.\$(OBJEXT)" - ;; - x86_64-*) - targ_64_little=yes - targetobjs="$targetobjs x86_64.\$(OBJEXT)" - ;; - *) + . ${srcdir}/configure.tgt + + if test "$targ_obj" = "UNKNOWN"; then AC_MSG_ERROR("unsupported target $targ") - ;; - esac + else + targetobjs="$targetobjs ${targ_obj}.\$(OBJEXT)" + if test "$targ_size" = "32"; then + if test "$targ_big_endian" = "false"; then + targ_32_little=yes + elif test "$targ_big_endian" = "true"; then + targ_32_big=yes + else + AC_MSG_ERROR("bad configure.tgt endian $targ_big_endian") + fi + elif test "$targ_size" = "64"; then + if test "$targ_big_endian" = "false"; then + targ_64_little=yes + elif test "$targ_big_endian" = "true"; then + targ_64_big=yes + else + AC_MSG_ERROR("bad configure.tgt endian $targ_big_endian") + fi + else + AC_MSG_ERROR("bad configure.tgt size $targ_size") + fi + + if test "$target" = "$targ"; then + default_machine=$targ_machine + default_size=$targ_size + default_big_endian=$targ_big_endian + fi + fi fi done @@ -138,6 +160,13 @@ else fi AC_SUBST(TARGETOBJS) +AC_DEFINE_UNQUOTED(GOLD_DEFAULT_MACHINE, $default_machine, + [Default machine code]) +AC_DEFINE_UNQUOTED(GOLD_DEFAULT_SIZE, $default_size, + [Default size (32 or 64)]) +AC_DEFINE_UNQUOTED(GOLD_DEFAULT_BIG_ENDIAN, $default_big_endian, + [Default big endian (true or false)]) + AC_PROG_CC AC_PROG_CXX AC_PROG_YACC diff --git a/gold/configure.tgt b/gold/configure.tgt new file mode 100644 index 0000000..93615aa --- /dev/null +++ b/gold/configure.tgt @@ -0,0 +1,55 @@ +# configure.tgt -- target configuration for gold -*- sh -*- + +# Copyright 2006, 2007, 2008 Free Software Foundation, Inc. +# Written by Ian Lance Taylor <iant@google.com>. + +# This file is part of gold. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. + +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, +# MA 02110-1301, USA. + +# This script handles target configuration for gold. This is shell +# code invoked by the autoconf generated configure script. Putting +# this in a separate file lets us skip running autoconf when modifying +# target specific information. + +# This file switches on the shell variable ${targ}, which is a +# canonicalized GNU configuration triplet. It sets the following +# shell variables: + +# targ_obj object file to include in the link, with no extension +# targ_machine ELF machine code for this target +# targ_size size of this target--32 or 64 +# targ_big_endian whether the target is big-endian--true or false + +# If the target is not recognized targ_obj is set to "UNKNOWN". + +case "$targ" in +i?86-*) + targ_obj=i386 + targ_machine=EM_386 + targ_size=32 + targ_big_endian=false + ;; +x86_64*) + targ_obj=x86_64 + targ_machine=EM_X86_64 + targ_size=64 + targ_big_endian=false + ;; +*) + targ_obj=UNKNOWN + ;; +esac diff --git a/gold/gold.cc b/gold/gold.cc index 71dac86..4b52b57 100644 --- a/gold/gold.cc +++ b/gold/gold.cc @@ -26,10 +26,12 @@ #include <cstdio> #include <cstring> #include <unistd.h> +#include <algorithm> #include "libiberty.h" #include "options.h" #include "debug.h" +#include "target-select.h" #include "workqueue.h" #include "dirsearch.h" #include "readsyms.h" @@ -160,16 +162,24 @@ queue_middle_tasks(const General_options& options, Layout* layout, Workqueue* workqueue) { + // We have to support the case of not seeing any input objects, and + // generate an empty file. Existing builds depend on being able to + // pass an empty archive to the linker and get an empty object file + // out. In order to do this we need to use a default target. if (input_objects->number_of_input_objects() == 0) { - // We had some input files, but we weren't able to open any of - // them. - gold_fatal(_("no input files")); + // The GOLD_xx macros are defined by the configure script. + Target* target = select_target(elfcpp::GOLD_DEFAULT_MACHINE, + GOLD_DEFAULT_SIZE, + GOLD_DEFAULT_BIG_ENDIAN, + 0, 0); + gold_assert(target != NULL); + set_parameters_target(target); } int thread_count = options.thread_count_middle(); if (thread_count == 0) - thread_count = input_objects->number_of_input_objects(); + thread_count = std::max(2, input_objects->number_of_input_objects()); workqueue->set_thread_count(thread_count); // Now we have seen all the input files. @@ -278,7 +288,7 @@ queue_final_tasks(const General_options& options, { int thread_count = options.thread_count_final(); if (thread_count == 0) - thread_count = input_objects->number_of_input_objects(); + thread_count = std::max(2, input_objects->number_of_input_objects()); workqueue->set_thread_count(thread_count); bool any_postprocessing_sections = layout->any_postprocessing_sections(); diff --git a/gold/layout.cc b/gold/layout.cc index 8b17f83..faae577 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -891,7 +891,7 @@ off_t Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab, const Task* task) { - Target* const target = input_objects->target(); + Target* const target = parameters->target(); target->finalize_sections(this); diff --git a/gold/object.cc b/gold/object.cc index 433fbc8..f82827c 100644 --- a/gold/object.cc +++ b/gold/object.cc @@ -1248,12 +1248,13 @@ Sized_relobj<size, big_endian>::get_symbol_location_info( bool Input_objects::add_object(Object* obj) { + // Set the global target from the first object file we recognize. Target* target = obj->target(); - if (this->target_ == NULL) - this->target_ = target; - else if (this->target_ != target) + if (!parameters->is_target_valid()) + set_parameters_target(target); + else if (target != parameters->target()) { - gold_error(_("%s: incompatible target"), obj->name().c_str()); + obj->error(_("incompatible target")); return false; } @@ -1289,8 +1290,6 @@ Input_objects::add_object(Object* obj) } } - set_parameters_target(target); - return true; } diff --git a/gold/object.h b/gold/object.h index dbe0ca1..b83d420 100644 --- a/gold/object.h +++ b/gold/object.h @@ -1367,8 +1367,7 @@ class Input_objects { public: Input_objects() - : relobj_list_(), dynobj_list_(), target_(NULL), sonames_(), - system_library_directory_() + : relobj_list_(), dynobj_list_(), sonames_(), system_library_directory_() { } // The type of the list of input relocateable objects. @@ -1384,11 +1383,6 @@ class Input_objects bool add_object(Object*); - // Get the target we should use for the output file. - Target* - target() const - { return this->target_; } - // For each dynamic object, check whether we've seen all of its // explicit dependencies. void @@ -1437,8 +1431,6 @@ class Input_objects Relobj_list relobj_list_; // The list of dynamic objects included in the link. Dynobj_list dynobj_list_; - // The target. - Target* target_; // SONAMEs that we have seen. Unordered_set<std::string> sonames_; // The directory in which we find the libc.so. diff --git a/gold/parameters.h b/gold/parameters.h index 2467295..67ce1e6 100644 --- a/gold/parameters.h +++ b/gold/parameters.h @@ -200,6 +200,11 @@ class Parameters return this->doing_static_link_; } + // Return whether the target field has been set. + bool + is_target_valid() const + { return this->is_target_valid_; } + // The target of the output file we are generating. Target* target() const diff --git a/gold/symtab.cc b/gold/symtab.cc index 288b966..c7f6816 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -1791,7 +1791,7 @@ Symbol_table::sized_write_globals(const Input_objects* input_objects, const Stringpool* dynpool, Output_file* of) const { - const Target* const target = input_objects->target(); + const Target* const target = parameters->target(); const int sym_size = elfcpp::Elf_sizes<size>::sym_size; @@ -1966,7 +1966,7 @@ Symbol_table::warn_about_undefined_dynobj_symbol( && sym->shndx() == elfcpp::SHN_UNDEF && sym->binding() != elfcpp::STB_WEAK && !parameters->allow_shlib_undefined() - && !input_objects->target()->is_defined_by_abi(sym) + && !parameters->target()->is_defined_by_abi(sym) && !input_objects->found_in_system_library_directory(sym->object())) { // A very ugly cast. |