Support creating empty output when there are no input objects.
authorIan Lance Taylor <iant@google.com>
Wed, 6 Feb 2008 20:32:10 +0000 (20:32 +0000)
committerIan Lance Taylor <iant@google.com>
Wed, 6 Feb 2008 20:32:10 +0000 (20:32 +0000)
gold/config.in
gold/configure
gold/configure.ac
gold/configure.tgt [new file with mode: 0644]
gold/gold.cc
gold/layout.cc
gold/object.cc
gold/object.h
gold/parameters.h
gold/symtab.cc

index 9c0db951f17ea34e0c6ab3e80ef3e536f82ac0d3..4dc6141415542389770c13363147de735094baf7 100644 (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
 
index ef56ef5e3b3634a6d4e152ede9f9f282ebeed06c..d2006a3d5322cb5efad9f2c340df12829a5a407e 100755 (executable)
@@ -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'
index 62fdaab4de9e8b02173eff5dc795a2ca3a37064e..c719e7853414dbf5aa8c06e444fd886627b7056d 100644 (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
diff --git a/gold/configure.tgt b/gold/configure.tgt
new file mode 100644 (file)
index 0000000..93615aa
--- /dev/null
@@ -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
index 71dac861798453b3be3d3eacd32cd8d999ee7bc9..4b52b570abca32b9889d41f966f95012ad271931 100644 (file)
 #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();
index 8b17f83ab4fe01b8aa911506a8e6913a8dbbd758..faae577336cb0da7b8aa23aeec232081b57d8bd0 100644 (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);
 
index 433fbc842c5ff912c3901f71379cb9e53b1e21b4..f82827c3b2f36299ec26810c5bef8cbde4f1da3a 100644 (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;
 }
 
index dbe0ca1390ebaf4056ae2008736765cd5595fd29..b83d420f65c454495528cafb1be97832d06ee754 100644 (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.
index 2467295c857f634dcc4f0f2bf0f067095f7eda6a..67ce1e6eff95fdcc5ba337f768b2733d0a127b06 100644 (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
index 288b96696614a54bbdf6df5a3d80bf25024f2e8c..c7f68166a46b177aafb175eb466cf7b88d126b56 100644 (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.
This page took 0.038809 seconds and 4 git commands to generate.