Support creating empty output when there are no input objects.
This commit is contained in:
parent
755ab8af10
commit
fbfba50887
@ -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
76
gold/configure
vendored
@ -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'
|
||||
|
@ -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
55
gold/configure.tgt
Normal 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
|
20
gold/gold.cc
20
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();
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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.
|
||||
|
Loading…
Reference in New Issue
Block a user