Support creating empty output when there are no input objects.

This commit is contained in:
Ian Lance Taylor 2008-02-06 20:32:10 +00:00
parent 755ab8af10
commit fbfba50887
10 changed files with 198 additions and 55 deletions

View File

@ -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

76
gold/configure vendored
View File

@ -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'

View File

@ -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

55
gold/configure.tgt Normal file
View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -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;
}

View File

@ -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.

View File

@ -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

View File

@ -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.