CCFILES = \
archive.cc \
common.cc \
+ compressed_output.cc \
defstd.cc \
dirsearch.cc \
dynobj.cc \
HFILES = \
archive.h \
common.h \
+ compressed_output.h \
defstd.h \
dirsearch.h \
dynobj.h \
ARFLAGS = cru
libgold_a_AR = $(AR) $(ARFLAGS)
libgold_a_LIBADD =
-am__objects_1 = archive.$(OBJEXT) common.$(OBJEXT) defstd.$(OBJEXT) \
+am__objects_1 = archive.$(OBJEXT) common.$(OBJEXT) \
+ compressed_output.$(OBJEXT) defstd.$(OBJEXT) \
dirsearch.$(OBJEXT) dynobj.$(OBJEXT) dwarf_reader.$(OBJEXT) \
ehframe.$(OBJEXT) errors.$(OBJEXT) fileread.$(OBJEXT) \
gold.$(OBJEXT) gold-threads.$(OBJEXT) layout.$(OBJEXT) \
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
CCFILES = \
archive.cc \
common.cc \
+ compressed_output.cc \
defstd.cc \
dirsearch.cc \
dynobj.cc \
HFILES = \
archive.h \
common.h \
+ compressed_output.h \
defstd.h \
dirsearch.h \
dynobj.h \
@AMDEP_TRUE@@am__include@ @am__quote@$(DEPDIR)/pread.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/archive.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/common.Po@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/compressed_output.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/defstd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dirsearch.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf_reader.Po@am__quote@
--- /dev/null
+// compressed_output.cc -- manage compressed output sections for gold
+
+// Copyright 2007 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.
+
+#include "gold.h"
+
+#ifdef HAVE_ZLIB_H
+#include <zlib.h>
+#endif
+
+#include "compressed_output.h"
+#include "parameters.h"
+
+namespace gold
+{
+
+// Compress UNCOMPRESSED_DATA of size UNCOMPRESSED_SIZE. Returns true
+// if it successfully compressed, false if it failed for any reason
+// (including not having zlib support in the library). If it returns
+// true, it allocates memory for the compressed data using new, and
+// sets *COMPRESSED_DATA and *COMPRESSED_SIZE to appropriate values.
+
+static bool
+zlib_compress(const char* uncompressed_data, unsigned long uncompressed_size,
+ char** compressed_data, unsigned long* compressed_size)
+{
+#ifndef HAVE_ZLIB_H
+ return false;
+#else
+ *compressed_size = uncompressed_size + uncompressed_size / 1000 + 128;
+ *compressed_data = new char[*compressed_size];
+
+ int compress_level;
+ if (parameters->optimization_level() >= 1)
+ compress_level = 9;
+ else
+ compress_level = 1;
+
+ int rc = compress2(reinterpret_cast<Bytef*>(*compressed_data),
+ compressed_size,
+ reinterpret_cast<const Bytef*>(uncompressed_data),
+ uncompressed_size,
+ compress_level);
+ if (rc == Z_OK)
+ return true;
+ else
+ {
+ delete[] *compressed_data;
+ *compressed_data = NULL;
+ return false;
+ }
+#endif // #ifdef HAVE_ZLIB_H
+}
+
+// After compressing an output section, we rename it from foo to
+// foo.zlib.nnnn, where nnnn is the uncompressed size of the section.
+
+static std::string
+zlib_compressed_suffix(unsigned long uncompressed_size)
+{
+ char size_string[64];
+ snprintf(size_string, sizeof(size_string), "%lu", uncompressed_size);
+ return std::string(".zlib.") + size_string;
+}
+
+// Class Output_compressed_section_data.
+
+// Add an input section. In this case, we just keep track of the sections.
+
+bool
+Output_compressed_section_data::do_add_input_section(Relobj* obj,
+ unsigned int shndx)
+{
+ this->objects_.push_back(Object_entry(obj, shndx));
+ return true;
+}
+
+// Set the final data size of a compressed section. This is where
+// we actually compress the section data.
+
+void
+Output_compressed_section_data::set_final_data_size()
+{
+ // FIXME: assert that relocations have already been applied.
+
+ off_t uncompressed_size = 0;
+ for (std::vector<Object_entry>::iterator it = this->objects_.begin();
+ it != this->objects_.end();
+ ++it)
+ {
+ it->contents
+ = it->object->section_contents(it->shndx, &it->length, false);
+ uncompressed_size += it->length;
+ }
+
+ // (Try to) compress the data.
+ unsigned long compressed_size;
+ char* uncompressed_data = new char[uncompressed_size];
+ off_t pos = 0;
+ for (std::vector<Object_entry>::const_iterator it = this->objects_.begin();
+ it != this->objects_.end();
+ ++it)
+ {
+ memcpy(uncompressed_data + pos,
+ reinterpret_cast<const char*>(it->contents),
+ it->length);
+ pos += it->length;
+ }
+
+ bool success = false;
+ if (options_.zlib_compress_debug_sections())
+ success = zlib_compress(uncompressed_data, uncompressed_size,
+ &this->data_, &compressed_size);
+ if (success)
+ {
+ delete[] uncompressed_data;
+ this->set_data_size(compressed_size);
+ this->new_section_name_ = zlib_compressed_suffix(uncompressed_size);
+ }
+ else
+ {
+ gold_warning(_("Not compressing section data: zlib error"));
+ gold_assert(this->data_ == NULL);
+ this->data_ = uncompressed_data;
+ this->set_data_size(uncompressed_size);
+ }
+}
+
+// Change the name of the output section to reflect it's compressed.
+// The layout routines call into this right before finalizing the
+// shstrtab.
+
+const char*
+Output_compressed_section_data::do_modified_output_section_name(
+ const char* name)
+{
+ // This mean we never compressed the data.
+ if (this->new_section_name_.empty())
+ return NULL;
+ this->new_section_name_ = std::string(name) + this->new_section_name_;
+ return this->new_section_name_.c_str();
+}
+
+// Write out a compressed section. If we couldn't compress, we just
+// write it out as normal, uncompressed data.
+
+void
+Output_compressed_section_data::do_write(Output_file* of)
+{
+ unsigned char* uview = of->get_output_view(this->offset(),
+ this->data_size());
+ char* view = reinterpret_cast<char*>(uview);
+ memcpy(view, this->data_, this->data_size());
+ of->write_output_view(this->offset(), this->data_size(), uview);
+}
+
+// Class Output_compressed_string.
+
+// Add an input section. We don't do anything special here.
+
+template<typename Char_type>
+bool
+Output_compressed_string<Char_type>::do_add_input_section(Relobj* object,
+ unsigned int shndx)
+{
+ return Output_merge_string<Char_type>::do_add_input_section(object, shndx);
+}
+
+// Set the final data size of a compressed section. This is where
+// we actually compress the section data.
+
+template<typename Char_type>
+void
+Output_compressed_string<Char_type>::set_final_data_size()
+{
+ // First let the superclass finalize all its data, then write it to
+ // a buffer.
+ unsigned long uncompressed_size = this->finalize_merged_data();
+ char* uncompressed_data = new char[uncompressed_size];
+ this->stringpool_to_buffer(uncompressed_data, uncompressed_size);
+
+ // (Try to) compress the data.
+ unsigned long compressed_size;
+ if (options_.zlib_compress_debug_sections()
+ && zlib_compress(uncompressed_data, uncompressed_size,
+ &this->compressed_data_, &compressed_size))
+ {
+ this->set_data_size(compressed_size);
+ // Save some memory.
+ this->clear_stringpool();
+ // We will be renaming the section to name.zlib.uncompressed_size.
+ this->new_section_name_ = zlib_compressed_suffix(uncompressed_size);
+ }
+ else
+ {
+ this->compressed_data_ = NULL;
+ this->set_data_size(uncompressed_size);
+ }
+
+ delete[] uncompressed_data;
+}
+
+// Change the name of the output section to reflect it's compressed.
+// The layout routines call into this right before finalizing the
+// shstrtab.
+
+template<typename Char_type>
+const char*
+Output_compressed_string<Char_type>::do_modified_output_section_name(
+ const char* name)
+{
+ // This mean we never compressed the data
+ if (this->new_section_name_.empty())
+ return NULL;
+ this->new_section_name_ = std::string(name) + this->new_section_name_;
+ return this->new_section_name_.c_str();
+}
+
+// Write out a compressed string section. If we couldn't compress,
+// we just write out the normal string section.
+
+template<typename Char_type>
+void
+Output_compressed_string<Char_type>::do_write(Output_file* of)
+{
+ if (this->compressed_data_ == NULL)
+ Output_merge_string<Char_type>::do_write(of);
+ else
+ {
+ unsigned char* uview = of->get_output_view(this->offset(),
+ this->data_size());
+ char* view = reinterpret_cast<char*>(uview);
+ memcpy(view, this->compressed_data_, this->data_size());
+ of->write_output_view(this->offset(), this->data_size(), uview);
+ }
+}
+
+// Instantiate the templates we need.
+
+template
+class Output_compressed_string<char>;
+
+template
+class Output_compressed_string<uint16_t>;
+
+template
+class Output_compressed_string<uint32_t>;
+
+} // End namespace gold.
--- /dev/null
+// compressed_output.h -- compressed output sections for gold -*- C++ -*-
+
+// Copyright 2007 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.
+
+// We support compressing .debug_* sections on output. (And,
+// potentially one day, other sections.) This is a form of
+// relaxation. This file adds support for merging and emitting the
+// compressed sections.
+
+#ifndef GOLD_COMPRESSED_OUTPUT_H
+#define GOLD_COMPRESSED_OUTPUT_H
+
+#include <string>
+#include <vector>
+
+#include "output.h"
+#include "merge.h"
+
+namespace gold
+{
+
+class General_options;
+
+// This is used for compressing a section before emitting it in the
+// output file. This only works for unloaded sections, since it
+// assumes the final section contents are available at
+// set_final_data_size() time. For loaded sections (those that end up
+// in segments), this is not true; relocations are applied after
+// set_final_data_size() is called. However, for unloaded sections,
+// we can -- and do -- postpone calling finalize_data_size() until
+// after relocations are applies.
+
+class Output_compressed_section_data : public Output_section_data
+{
+ public:
+ Output_compressed_section_data(uint64_t addralign,
+ const General_options& options)
+ : Output_section_data(addralign), options_(options), data_(NULL)
+ { }
+
+ protected:
+ // Add an input section.
+ bool
+ do_add_input_section(Relobj* object, unsigned int shndx);
+
+ // Set the final data size.
+ void
+ set_final_data_size();
+
+ // Change the name of the output section to reflect it's compressed.
+ const char*
+ do_modified_output_section_name(const char* name);
+
+ // Write the data to the file.
+ void
+ do_write(Output_file*);
+
+ private:
+ struct Object_entry
+ {
+ Relobj* object;
+ unsigned int shndx;
+ const unsigned char* contents;
+ off_t length;
+
+ Object_entry(Relobj* o, unsigned int s)
+ : object(o), shndx(s), contents(NULL), length(0)
+ { }
+ };
+
+ const General_options& options_;
+ std::vector<Object_entry> objects_;
+ char* data_;
+ std::string new_section_name_;
+};
+
+// This is a special case for when the output section is a string
+// section and does not have any relocations to apply to it.
+
+template<typename Char_type>
+class Output_compressed_string : public Output_merge_string<Char_type>
+{
+ public:
+ Output_compressed_string(uint64_t addralign,
+ const General_options& options)
+ : Output_merge_string<Char_type>(addralign),
+ options_(options), compressed_data_(NULL)
+ { }
+
+ ~Output_compressed_string()
+ { delete[] compressed_data_; }
+
+ protected:
+ // Add an input section.
+ bool
+ do_add_input_section(Relobj* object, unsigned int shndx);
+
+ // Set the final data size. Also compresses the buffer.
+ void
+ set_final_data_size();
+
+ // Change the name of the output section to reflect it's compressed.
+ const char*
+ do_modified_output_section_name(const char* name);
+
+ // Write the data to the file.
+ void
+ do_write(Output_file*);
+
+ private:
+ const General_options& options_;
+ char* compressed_data_;
+ // This is just a buffer to store the section name in "permanent" storage.
+ std::string new_section_name_;
+};
+
+} // End namespace gold.
+
+#endif // !defined(GOLD_COMPRESSED_OUTPUT_H)
/* Define to 1 if you have the <unistd.h> header file. */
#undef HAVE_UNISTD_H
+/* Define to 1 if you have the <zlib.h> header file. */
+#undef HAVE_ZLIB_H
+
/* Name of package */
#undef PACKAGE
# include <unistd.h>
#endif"
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar THREADS_TRUE THREADS_FALSE TARGETOBJS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE YACC RANLIB ac_ct_RANLIB LN_S USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT MKINSTALLDIRS MSGFMT MSGMERGE NATIVE_LINKER_TRUE NATIVE_LINKER_FALSE GCC_TRUE GCC_FALSE FN_PTRS_IN_SO_WITHOUT_PIC_TRUE FN_PTRS_IN_SO_WITHOUT_PIC_FALSE TLS_TRUE TLS_FALSE STATIC_TLS_TRUE STATIC_TLS_FALSE WARN_CFLAGS NO_WERROR WARN_CXXFLAGS LFS_CXXFLAGS LIBOBJS CXXCPP EGREP MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS build build_cpu build_vendor build_os host host_cpu host_vendor host_os target target_cpu target_vendor target_os INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar THREADS_TRUE THREADS_FALSE TARGETOBJS CC CFLAGS LDFLAGS CPPFLAGS ac_ct_CC EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE CXX CXXFLAGS ac_ct_CXX CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE YACC RANLIB ac_ct_RANLIB LN_S USE_NLS LIBINTL LIBINTL_DEP INCINTL XGETTEXT GMSGFMT POSUB CATALOGS DATADIRNAME INSTOBJEXT GENCAT CATOBJEXT MKINSTALLDIRS MSGFMT MSGMERGE NATIVE_LINKER_TRUE NATIVE_LINKER_FALSE GCC_TRUE GCC_FALSE FN_PTRS_IN_SO_WITHOUT_PIC_TRUE FN_PTRS_IN_SO_WITHOUT_PIC_FALSE TLS_TRUE TLS_FALSE STATIC_TLS_TRUE STATIC_TLS_FALSE WARN_CFLAGS NO_WERROR WARN_CXXFLAGS LFS_CXXFLAGS LIBOBJS CPP EGREP CXXCPP MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT LTLIBOBJS'
ac_subst_files=''
# Initialize some variables set by options.
ac_env_CXXFLAGS_value=$CXXFLAGS
ac_cv_env_CXXFLAGS_set=${CXXFLAGS+set}
ac_cv_env_CXXFLAGS_value=$CXXFLAGS
+ac_env_CPP_set=${CPP+set}
+ac_env_CPP_value=$CPP
+ac_cv_env_CPP_set=${CPP+set}
+ac_cv_env_CPP_value=$CPP
ac_env_CXXCPP_set=${CXXCPP+set}
ac_env_CXXCPP_value=$CXXCPP
ac_cv_env_CXXCPP_set=${CXXCPP+set}
headers in a nonstandard directory <include dir>
CXX C++ compiler command
CXXFLAGS C++ compiler flags
+ CPP C preprocessor
CXXCPP C++ preprocessor
Use these variables to override the choices made by `configure' or to help
+# Link in zlib if we can. This allows us to write compressed sections.
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+echo "$as_me:$LINENO: checking how to run the C preprocessor" >&5
+echo $ECHO_N "checking how to run the C preprocessor... $ECHO_C" >&6
+# On Suns, sometimes $CPP names a directory.
+if test -n "$CPP" && test -d "$CPP"; then
+ CPP=
+fi
+if test -z "$CPP"; then
+ if test "${ac_cv_prog_CPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CPP needs to be expanded
+ for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ break
+fi
+
+ done
+ ac_cv_prog_CPP=$CPP
+
+fi
+ CPP=$ac_cv_prog_CPP
+else
+ ac_cv_prog_CPP=$CPP
+fi
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
+ac_preproc_ok=false
+for ac_c_preproc_warn_flag in '' yes
+do
+ # Use a header file that comes with gcc, so configuring glibc
+ # with a fresh cross-compiler works.
+ # Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ # <limits.h> exists even on freestanding compilers.
+ # On the NeXT, cc -E runs the code through the compiler's parser,
+ # not just through cpp. "Syntax error" is here to catch this case.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+ Syntax error
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ :
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Broken: fails on valid input.
+continue
+fi
+rm -f conftest.err conftest.$ac_ext
+
+ # OK, works on sane cases. Now check whether non-existent headers
+ # can be detected and how.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ac_nonexistent.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ # Broken: success on invalid input.
+continue
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ # Passes both tests.
+ac_preproc_ok=:
+break
+fi
+rm -f conftest.err conftest.$ac_ext
+
+done
+# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
+rm -f conftest.err conftest.$ac_ext
+if $ac_preproc_ok; then
+ :
+else
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+echo "$as_me:$LINENO: checking for egrep" >&5
+echo $ECHO_N "checking for egrep... $ECHO_C" >&6
+if test "${ac_cv_prog_egrep+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ if echo a | (grep -E '(a|b)') >/dev/null 2>&1
+ then ac_cv_prog_egrep='grep -E'
+ else ac_cv_prog_egrep='egrep'
+ fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
+echo "${ECHO_T}$ac_cv_prog_egrep" >&6
+ EGREP=$ac_cv_prog_egrep
+
+
+echo "$as_me:$LINENO: checking for ANSI C header files" >&5
+echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
+if test "${ac_cv_header_stdc+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <float.h>
+
+int
+main ()
+{
+
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_header_stdc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_cv_header_stdc=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+
+if test $ac_cv_header_stdc = yes; then
+ # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <string.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "memchr" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <stdlib.h>
+
+_ACEOF
+if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
+ $EGREP "free" >/dev/null 2>&1; then
+ :
+else
+ ac_cv_header_stdc=no
+fi
+rm -f conftest*
+
+fi
+
+if test $ac_cv_header_stdc = yes; then
+ # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
+ if test "$cross_compiling" = yes; then
+ :
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <ctype.h>
+#if ((' ' & 0x0FF) == 0x020)
+# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
+# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
+#else
+# define ISLOWER(c) \
+ (('a' <= (c) && (c) <= 'i') \
+ || ('j' <= (c) && (c) <= 'r') \
+ || ('s' <= (c) && (c) <= 'z'))
+# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
+#endif
+
+#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
+int
+main ()
+{
+ int i;
+ for (i = 0; i < 256; i++)
+ if (XOR (islower (i), ISLOWER (i))
+ || toupper (i) != TOUPPER (i))
+ exit(2);
+ exit (0);
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ :
+else
+ echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+ac_cv_header_stdc=no
+fi
+rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+fi
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
+echo "${ECHO_T}$ac_cv_header_stdc" >&6
+if test $ac_cv_header_stdc = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define STDC_HEADERS 1
+_ACEOF
+
+fi
+
+# On IRIX 5.3, sys/types and inttypes.h are conflicting.
+
+
+
+
+
+
+
+
+
+for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
+ inttypes.h stdint.h unistd.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ eval "$as_ac_Header=yes"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+eval "$as_ac_Header=no"
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+
+echo "$as_me:$LINENO: checking for library containing zlibVersion" >&5
+echo $ECHO_N "checking for library containing zlibVersion... $ECHO_C" >&6
+if test "${ac_cv_search_zlibVersion+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_func_search_save_LIBS=$LIBS
+ac_cv_search_zlibVersion=no
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char zlibVersion ();
+int
+main ()
+{
+zlibVersion ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_zlibVersion="none required"
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+if test "$ac_cv_search_zlibVersion" = no; then
+ for ac_lib in z; do
+ LIBS="-l$ac_lib $ac_func_search_save_LIBS"
+ cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+
+/* Override any gcc2 internal prototype to avoid an error. */
+#ifdef __cplusplus
+extern "C"
+#endif
+/* We use char because int might match the return type of a gcc2
+ builtin and then its argument prototype would still apply. */
+char zlibVersion ();
+int
+main ()
+{
+zlibVersion ();
+ ;
+ return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
+ (eval $ac_link) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest$ac_exeext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_cv_search_zlibVersion="-l$ac_lib"
+break
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+fi
+rm -f conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+ done
+fi
+LIBS=$ac_func_search_save_LIBS
+fi
+echo "$as_me:$LINENO: result: $ac_cv_search_zlibVersion" >&5
+echo "${ECHO_T}$ac_cv_search_zlibVersion" >&6
+if test "$ac_cv_search_zlibVersion" != no; then
+ test "$ac_cv_search_zlibVersion" = "none required" || LIBS="$ac_cv_search_zlibVersion $LIBS"
+
+for ac_header in zlib.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag"
+ || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <$ac_header>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------- ##
+## Report this to the gold lists. ##
+## ------------------------------- ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
+if eval "test \"\${$as_ac_Header+set}\" = set"; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ eval "$as_ac_Header=\$ac_header_preproc"
+fi
+echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
+echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+ cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+
+done
+
+fi
+
+
ac_ext=cc
ac_cpp='$CXXCPP $CPPFLAGS'
ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-echo "$as_me:$LINENO: checking for egrep" >&5
-echo $ECHO_N "checking for egrep... $ECHO_C" >&6
-if test "${ac_cv_prog_egrep+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- if echo a | (grep -E '(a|b)') >/dev/null 2>&1
- then ac_cv_prog_egrep='grep -E'
- else ac_cv_prog_egrep='egrep'
- fi
-fi
-echo "$as_me:$LINENO: result: $ac_cv_prog_egrep" >&5
-echo "${ECHO_T}$ac_cv_prog_egrep" >&6
- EGREP=$ac_cv_prog_egrep
-
-
-echo "$as_me:$LINENO: checking for ANSI C header files" >&5
-echo $ECHO_N "checking for ANSI C header files... $ECHO_C" >&6
-if test "${ac_cv_header_stdc+set}" = set; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
-#include <stdarg.h>
-#include <string.h>
-#include <float.h>
-
-int
-main ()
-{
-
- ;
- return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_cxx_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- ac_cv_header_stdc=yes
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-ac_cv_header_stdc=no
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-
-if test $ac_cv_header_stdc = yes; then
- # SunOS 4.x string.h does not declare mem*, contrary to ANSI.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <string.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "memchr" >/dev/null 2>&1; then
- :
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI.
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <stdlib.h>
-
-_ACEOF
-if (eval "$ac_cpp conftest.$ac_ext") 2>&5 |
- $EGREP "free" >/dev/null 2>&1; then
- :
-else
- ac_cv_header_stdc=no
-fi
-rm -f conftest*
-
-fi
-
-if test $ac_cv_header_stdc = yes; then
- # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi.
- if test "$cross_compiling" = yes; then
- :
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-#include <ctype.h>
-#if ((' ' & 0x0FF) == 0x020)
-# define ISLOWER(c) ('a' <= (c) && (c) <= 'z')
-# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c))
-#else
-# define ISLOWER(c) \
- (('a' <= (c) && (c) <= 'i') \
- || ('j' <= (c) && (c) <= 'r') \
- || ('s' <= (c) && (c) <= 'z'))
-# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c))
-#endif
-
-#define XOR(e, f) (((e) && !(f)) || (!(e) && (f)))
-int
-main ()
-{
- int i;
- for (i = 0; i < 256; i++)
- if (XOR (islower (i), ISLOWER (i))
- || toupper (i) != TOUPPER (i))
- exit(2);
- exit (0);
-}
-_ACEOF
-rm -f conftest$ac_exeext
-if { (eval echo "$as_me:$LINENO: \"$ac_link\"") >&5
- (eval $ac_link) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- :
-else
- echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-( exit $ac_status )
-ac_cv_header_stdc=no
-fi
-rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-fi
-fi
-echo "$as_me:$LINENO: result: $ac_cv_header_stdc" >&5
-echo "${ECHO_T}$ac_cv_header_stdc" >&6
-if test $ac_cv_header_stdc = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define STDC_HEADERS 1
-_ACEOF
-
-fi
-
-# On IRIX 5.3, sys/types and inttypes.h are conflicting.
-
-
-
-
-
-
-
-
-
-for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \
- inttypes.h stdint.h unistd.h
-do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6
-if eval "test \"\${$as_ac_Header+set}\" = set"; then
- echo $ECHO_N "(cached) $ECHO_C" >&6
-else
- cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h. */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h. */
-$ac_includes_default
-
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
- (eval $ac_compile) 2>conftest.er1
- ac_status=$?
- grep -v '^ *+' conftest.er1 >conftest.err
- rm -f conftest.er1
- cat conftest.err >&5
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); } &&
- { ac_try='test -z "$ac_cxx_werror_flag"
- || test ! -s conftest.err'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; } &&
- { ac_try='test -s conftest.$ac_objext'
- { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
- (eval $ac_try) 2>&5
- ac_status=$?
- echo "$as_me:$LINENO: \$? = $ac_status" >&5
- (exit $ac_status); }; }; then
- eval "$as_ac_Header=yes"
-else
- echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
-
-eval "$as_ac_Header=no"
-fi
-rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
-fi
-echo "$as_me:$LINENO: result: `eval echo '${'$as_ac_Header'}'`" >&5
-echo "${ECHO_T}`eval echo '${'$as_ac_Header'}'`" >&6
-if test `eval echo '${'$as_ac_Header'}'` = yes; then
- cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
-_ACEOF
-
-fi
-
-done
-
-
for ac_header in tr1/unordered_set tr1/unordered_map
s,@WARN_CXXFLAGS@,$WARN_CXXFLAGS,;t t
s,@LFS_CXXFLAGS@,$LFS_CXXFLAGS,;t t
s,@LIBOBJS@,$LIBOBJS,;t t
-s,@CXXCPP@,$CXXCPP,;t t
+s,@CPP@,$CPP,;t t
s,@EGREP@,$EGREP,;t t
+s,@CXXCPP@,$CXXCPP,;t t
s,@MAINTAINER_MODE_TRUE@,$MAINTAINER_MODE_TRUE,;t t
s,@MAINTAINER_MODE_FALSE@,$MAINTAINER_MODE_FALSE,;t t
s,@MAINT@,$MAINT,;t t
AC_REPLACE_FUNCS(pread)
+# Link in zlib if we can. This allows us to write compressed sections.
+AC_SEARCH_LIBS(zlibVersion, z, [AC_CHECK_HEADERS(zlib.h)])
+
AC_LANG_PUSH(C++)
AC_CHECK_HEADERS(tr1/unordered_set tr1/unordered_map)
Layout::make_output_section(const char* name, elfcpp::Elf_Word type,
elfcpp::Elf_Xword flags)
{
- Output_section* os = new Output_section(name, type, flags);
+ Output_section* os = new Output_section(this->options_, name, type, flags);
this->section_list_.push_back(os);
if ((flags & elfcpp::SHF_ALLOC) == 0)
// Set the file offsets of all the non-data sections which don't
// have to wait for the input sections.
- off = this->set_section_offsets(off, false);
+ off = this->set_section_offsets(off, BEFORE_INPUT_SECTIONS_PASS);
// Now that all sections have been created, set the section indexes.
shndx = this->set_section_indexes(shndx);
// segment.
off_t
-Layout::set_section_offsets(off_t off, bool after_input_sections)
+Layout::set_section_offsets(off_t off, Layout::Section_offset_pass pass)
{
for (Section_list::iterator p = this->unattached_section_list_.begin();
p != this->unattached_section_list_.end();
if (*p == this->symtab_section_)
continue;
- if ((*p)->after_input_sections() != after_input_sections)
- continue;
+ if (pass == BEFORE_INPUT_SECTIONS_PASS
+ && (*p)->after_input_sections())
+ continue;
+ else if (pass == AFTER_INPUT_SECTIONS_PASS
+ && (!(*p)->after_input_sections()
+ || (*p)->type() == elfcpp::SHT_STRTAB))
+ continue;
+ else if (pass == STRTAB_AFTER_INPUT_SECTIONS_PASS
+ && (!(*p)->after_input_sections()
+ || (*p)->type() != elfcpp::SHT_STRTAB))
+ continue;
off = align_address(off, (*p)->addralign());
(*p)->set_file_offset(off);
return off;
}
+// Allow any section not associated with a segment to change its
+// output section name at the last minute.
+
+void
+Layout::modify_section_names()
+{
+ for (Section_list::iterator p = this->unattached_section_list_.begin();
+ p != this->unattached_section_list_.end();
+ ++p)
+ if ((*p)->maybe_modify_output_section_name())
+ this->namepool_.add((*p)->name(), true, NULL);
+}
+
// Set the section indexes of all the sections not associated with a
// segment.
Layout::write_sections_after_input_sections(Output_file* of)
{
// Determine the final section offsets, and thus the final output
- // file size.
+ // file size. Note we finalize the .shstrab last, to allow the
+ // after_input_section sections to modify their section-names before
+ // writing.
off_t off = this->output_file_size_;
- off = this->set_section_offsets(off, true);
+ off = this->set_section_offsets(off, AFTER_INPUT_SECTIONS_PASS);
+
+ // Determine the final section names as well (at least, for sections
+ // that we haven't written yet).
+ this->modify_section_names();
+
+ // Now that we've finalized the names, we can finalize the shstrab.
+ off = this->set_section_offsets(off, STRTAB_AFTER_INPUT_SECTIONS_PASS);
+
if (off > this->output_file_size_)
{
of->resize(off);
set_segment_offsets(const Target*, Output_segment*, unsigned int* pshndx);
// Set the final file offsets of all the sections not associated
- // with a segment.
+ // with a segment. We set section offsets in three passes: the
+ // first handles all allocated sections, the second sections that
+ // can be handled after input-sections are processed, and the last
+ // the late-bound STRTAB sections (probably only shstrtab, which is
+ // the one we care about because it holds section names).
+ enum Section_offset_pass
+ {
+ BEFORE_INPUT_SECTIONS_PASS,
+ AFTER_INPUT_SECTIONS_PASS,
+ STRTAB_AFTER_INPUT_SECTIONS_PASS
+ };
off_t
- set_section_offsets(off_t, bool after_input_sections);
+ set_section_offsets(off_t, Section_offset_pass pass);
+
+ // We also allow any section not associated with a segment to change
+ // its output section name at the last minute. Compressed sections
+ // use this to embed compression info in their name.
+ void
+ modify_section_names();
// Set the final section indexes of all the sections not associated
// with a segment. Returns the next unused index.
return true;
}
-// Set the final data size of a merged string section. This is where
-// we finalize the mappings from the input sections to the output
-// section.
+// Finalize the mappings from the input sections to the output
+// section, and return the final data size.
template<typename Char_type>
-void
-Output_merge_string<Char_type>::set_final_data_size()
+off_t
+Output_merge_string<Char_type>::finalize_merged_data()
{
this->stringpool_.set_string_offsets();
this->add_mapping(p->object, p->shndx, p->offset, p->length,
this->stringpool_.get_offset(p->string));
- this->set_data_size(this->stringpool_.get_strtab_size());
-
// Save some memory.
this->merged_strings_.clear();
+
+ return this->stringpool_.get_strtab_size();
+}
+
+template<typename Char_type>
+void
+Output_merge_string<Char_type>::set_final_data_size()
+{
+ const off_t final_data_size = this->finalize_merged_data();
+ this->set_data_size(final_data_size);
}
// Write out a merged string section.
this->stringpool_.set_no_zero_null();
}
+ protected:
// Add an input section.
bool
do_add_input_section(Relobj* object, unsigned int shndx);
+ // Do all the final processing after the input sections are read in.
+ // Returns the final data size.
+ off_t
+ finalize_merged_data();
+
// Set the final data size.
void
set_final_data_size();
void
do_write(Output_file*);
+ // Writes the stringpool to a buffer.
+ void
+ stringpool_to_buffer(char* buffer, size_t buffer_size)
+ { this->stringpool_.write_to_buffer(buffer, buffer_size); }
+
+ // Clears all the data in the stringpool, to save on memory.
+ void
+ clear_stringpool()
+ { stringpool_.clear(); }
+
private:
// As we see input sections, we build a mapping from object, section
// index and offset to strings.
&Position_dependent_options::set_static_search),
GENERAL_NOARG('\0', "Bsymbolic", N_("Bind defined symbols locally"),
NULL, ONE_DASH, &General_options::set_symbolic),
+#ifdef HAVE_ZLIB_H
+# define ZLIB_STR ",zlib"
+#else
+# define ZLIB_STR ""
+#endif
+ GENERAL_ARG('\0', "compress-debug-sections",
+ N_("Compress .debug_* sections in the output file "
+ "(default is none)"),
+ N_("--compress-debug-sections=[none" ZLIB_STR "]"),
+ TWO_DASHES,
+ &General_options::set_compress_debug_symbols),
GENERAL_NOARG('\0', "demangle", N_("Demangle C++ symbols in log messages"),
NULL, TWO_DASHES, &General_options::set_demangle),
GENERAL_NOARG('\0', "no-demangle",
strip_(STRIP_NONE),
allow_shlib_undefined_(false),
symbolic_(false),
+ compress_debug_sections_(NO_COMPRESSION),
detect_odr_violations_(false),
create_eh_frame_hdr_(false),
rpath_(),
strip_debug() const
{ return this->strip_ == STRIP_ALL || this->strip_ == STRIP_DEBUG; }
- // -Sgdb: strip only debugging information that's not used by
- // gdb (at least, for gdb versions <= 6.7).
+ // --strip-debug-gdb: strip only debugging information that's not
+ // used by gdb (at least, for gdb versions <= 6.7).
bool
strip_debug_gdb() const
{ return this->strip_debug() || this->strip_ == STRIP_DEBUG_UNUSED_BY_GDB; }
symbolic() const
{ return this->symbolic_; }
+ // --compress-debug-sections: compress .debug_* sections in the
+ // output file using the given compression method. This is useful
+ // when the tools (such as gdb) support compressed sections.
+ bool
+ compress_debug_sections() const
+ { return this->compress_debug_sections_ != NO_COMPRESSION; }
+
+ bool
+ zlib_compress_debug_sections() const
+ { return this->compress_debug_sections_ == ZLIB_COMPRESSION; }
+
// --demangle: demangle C++ symbols in our log messages.
bool
demangle() const
EXECSTACK_NO
};
+ // What compression method to use
+ enum CompressionMethod
+ {
+ NO_COMPRESSION,
+ ZLIB_COMPRESSION,
+ };
+
void
set_export_dynamic()
{ this->export_dynamic_ = true; }
set_symbolic()
{ this->symbolic_ = true; }
+ void set_compress_debug_symbols(const char* arg)
+ {
+ if (strcmp(arg, "none") == 0)
+ this->compress_debug_sections_ = NO_COMPRESSION;
+#ifdef HAVE_ZLIB_H
+ else if (strcmp(arg, "zlib") == 0)
+ this->compress_debug_sections_ = ZLIB_COMPRESSION;
+#endif
+ else
+ gold_fatal(_("Unsupported argument to --compress-debug-symbols: %s"),
+ arg);
+ }
+
void
set_demangle()
{ this->demangle_ = true; }
Strip strip_;
bool allow_shlib_undefined_;
bool symbolic_;
+ CompressionMethod compress_debug_sections_;
bool demangle_;
bool detect_odr_violations_;
bool create_eh_frame_hdr_;
#include "libiberty.h" // for unlink_if_ordinary()
#include "parameters.h"
+#include "compressed_output.h"
#include "object.h"
#include "symtab.h"
#include "reloc.h"
// Construct an Output_section. NAME will point into a Stringpool.
-Output_section::Output_section(const char* name, elfcpp::Elf_Word type,
+Output_section::Output_section(const General_options& options,
+ const char* name, elfcpp::Elf_Word type,
elfcpp::Elf_Xword flags)
- : name_(name),
+ : options_(options),
+ name_(name),
addralign_(0),
entsize_(0),
link_section_(NULL),
gold_assert(this->entsize_ == v);
}
+// Sometimes we compress sections. This is typically done for
+// sections that are not part of normal program execution (such as
+// .debug_* sections), and where the readers of these sections know
+// how to deal with compressed sections. (To make it easier for them,
+// we will rename the ouput section in such cases from .foo to
+// .foo.zlib.nnnn, where nnnn is the uncompressed size.) This routine
+// doesn't say for certain whether we'll compress -- it depends on
+// commandline options as well -- just whether this section is a
+// candidate for compression.
+
+static bool
+is_compressible_section(const char* secname)
+{
+ return (strncmp(secname, ".debug", sizeof(".debug") - 1) == 0);
+}
+
// Add the input section SHNDX, with header SHDR, named SECNAME, in
// OBJECT, to the Output_section. RELOC_SHNDX is the index of a
// relocation section which applies to this section, or 0 if none, or
&& reloc_shndx == 0)
{
if (this->add_merge_input_section(object, shndx, sh_flags,
- entsize, addralign))
+ entsize, addralign,
+ is_compressible_section(secname)))
{
// Tell the relocation routines that they need to call the
// output_offset method to determine the final address.
bool
Output_section::add_merge_input_section(Relobj* object, unsigned int shndx,
uint64_t flags, uint64_t entsize,
- uint64_t addralign)
+ uint64_t addralign,
+ bool is_compressible_section)
{
bool is_string = (flags & elfcpp::SHF_STRINGS) != 0;
p != this->input_sections_.end();
++p)
if (p->is_merge_section(is_string, entsize, addralign))
- break;
+ {
+ p->add_input_section(object, shndx);
+ return true;
+ }
// We handle the actual constant merging in Output_merge_data or
// Output_merge_string_data.
- if (p != this->input_sections_.end())
- p->add_input_section(object, shndx);
+ Output_section_data* posd;
+ if (!is_string)
+ posd = new Output_merge_data(entsize, addralign);
+ else if (is_compressible_section && options_.compress_debug_sections())
+ {
+ switch (entsize)
+ {
+ case 1:
+ posd = new Output_compressed_string<char>(addralign, this->options_);
+ break;
+ case 2:
+ posd = new Output_compressed_string<uint16_t>(addralign,
+ this->options_);
+ break;
+ case 4:
+ posd = new Output_compressed_string<uint32_t>(addralign,
+ this->options_);
+ break;
+ default:
+ return false;
+ }
+ }
else
{
- Output_section_data* posd;
- if (!is_string)
- posd = new Output_merge_data(entsize, addralign);
- else if (entsize == 1)
- posd = new Output_merge_string<char>(addralign);
- else if (entsize == 2)
- posd = new Output_merge_string<uint16_t>(addralign);
- else if (entsize == 4)
- posd = new Output_merge_string<uint32_t>(addralign);
- else
- return false;
-
- this->add_output_merge_section(posd, is_string, entsize);
- posd->add_input_section(object, shndx);
+ switch (entsize)
+ {
+ case 1:
+ posd = new Output_merge_string<char>(addralign);
+ break;
+ case 2:
+ posd = new Output_merge_string<uint16_t>(addralign);
+ break;
+ case 4:
+ posd = new Output_merge_string<uint32_t>(addralign);
+ break;
+ default:
+ return false;
+ }
}
+ this->add_output_merge_section(posd, is_string, entsize);
+ posd->add_input_section(object, shndx);
+
return true;
}
this->set_data_size(off - startoff);
}
+// Ask each output_section_data member if it wants to change the name
+// of the output section. If any of them says yes, use this to set
+// the new name. This should be called after all processing of this
+// output section is done, but before the name is finally committed to
+// the output-section's header.
+
+bool
+Output_section::maybe_modify_output_section_name()
+{
+ for (Input_section_list::const_iterator it = input_sections_.begin();
+ it != input_sections_.end();
+ ++it)
+ {
+ const char* newname = it->modified_output_section_name(this->name());
+ if (newname != NULL)
+ {
+ this->set_name(newname);
+ return true;
+ }
+ }
+ return false;
+}
+
// Write the section header to *OSHDR.
template<int size, bool big_endian>
add_input_section(Relobj* object, unsigned int shndx)
{ return this->do_add_input_section(object, shndx); }
+ // This class may change the output section name. This is called
+ // right before shstrtab is written, so after all input-section
+ // layout processing is done. The input is the old name, and the
+ // output should be a new name (which will be copied into permanent
+ // storage) to change the name, or NULL to keep the name as-is.
+ virtual const char*
+ do_modified_output_section_name(const char*)
+ { return NULL; }
+
// Given an input OBJECT, an input section index SHNDX within that
// object, and an OFFSET relative to the start of that input
// section, return whether or not the corresponding offset within
{
public:
// Create an output section, giving the name, type, and flags.
- Output_section(const char* name, elfcpp::Elf_Word, elfcpp::Elf_Xword);
+ Output_section(const General_options& options,
+ const char* name, elfcpp::Elf_Word, elfcpp::Elf_Xword);
virtual ~Output_section();
// Add a new input section SHNDX, named NAME, with header SHDR, from
name() const
{ return this->name_; }
+ // Modify the section name. This should be called only after this
+ // section is done being constructed. The input should be a pointer
+ // into layout's namepool_.
+ void
+ set_name(const char* newname)
+ { this->name_ = newname; }
+
// Return the section type.
elfcpp::Elf_Word
type() const
write_header(const Layout*, const Stringpool*,
elfcpp::Shdr_write<size, big_endian>*) const;
+ // This class may change the output section name. This is called
+ // right before shstrtab is written, so after all input-section
+ // layout processing is done. This calls
+ // do_modified_output_section_name() on all its output_section_data
+ // members, and changes the name if any member so suggests. If
+ // several members would suggest, this takes the first, arbitrarily.
+ // Return true if the name was modified, false else.
+ bool
+ maybe_modify_output_section_name();
+
protected:
// Return the section index in the output file.
unsigned int
void
set_address(uint64_t addr, off_t off, off_t secoff);
+ // Call modified_output_section_name on the output-section-data object.
+ const char*
+ modified_output_section_name(const char* name) const
+ {
+ if (this->is_input_section())
+ return NULL;
+ return this->u2_.posd->do_modified_output_section_name(name);
+ }
+
// Add an input section, for SHF_MERGE sections.
bool
add_input_section(Relobj* object, unsigned int shndx)
// handled.
bool
add_merge_input_section(Relobj* object, unsigned int shndx, uint64_t flags,
- uint64_t entsize, uint64_t addralign);
+ uint64_t entsize, uint64_t addralign,
+ bool can_compress_section);
// Add an output SHF_MERGE section POSD to this output section.
// IS_STRING indicates whether it is a SHF_STRINGS section, and
// Most of these fields are only valid after layout.
+ // General options.
+ const General_options& options_;
// The name of the section. This will point into a Stringpool.
- const char* const name_;
+ const char* name_;
// The section address is in the parent class.
// The section alignment.
uint64_t addralign_;
archive.h
common.cc
common.h
+compressed_output.cc
+compressed_output.h
defstd.cc
defstd.h
dirsearch.cc
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2007-11-20 16:37-0800\n"
+"POT-Creation-Date: 2007-11-29 16:33-0800\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
msgid "%s: member at %zu is not an ELF object"
msgstr ""
+#: compressed_output.cc:140
+msgid "Not compressing section data: zlib error"
+msgstr ""
+
#: dirsearch.cc:68
#, c-format
msgid "%s: can not read directory: %s"
msgid "symbol %s has undefined version %s"
msgstr ""
-#: errors.cc:77
+#: errors.cc:88
#, c-format
msgid "%s: warning: "
msgstr ""
-#: errors.cc:112
+#: errors.cc:127
#, c-format
msgid "%s: %s: warning: "
msgstr ""
-#: errors.cc:136
+#: errors.cc:154
#, c-format
msgid "%s: %s: undefined reference to '%s'\n"
msgstr ""
-#: errors.cc:146
+#: errors.cc:164
#, c-format
msgid "%s: "
msgstr ""
msgid "cannot mix -static with dynamic object %s"
msgstr ""
-#: gold-threads.cc:69
+#: gold-threads.cc:102
#, c-format
msgid "pthead_mutextattr_init failed: %s"
msgstr ""
-#: gold-threads.cc:73
+#: gold-threads.cc:106
#, c-format
msgid "pthread_mutextattr_settype failed: %s"
msgstr ""
-#: gold-threads.cc:78
+#: gold-threads.cc:111
#, c-format
msgid "pthread_mutex_init failed: %s"
msgstr ""
-#: gold-threads.cc:82
+#: gold-threads.cc:115
#, c-format
msgid "pthread_mutexattr_destroy failed: %s"
msgstr ""
-#: gold-threads.cc:89
+#: gold-threads.cc:122
#, c-format
msgid "pthread_mutex_destroy failed: %s"
msgstr ""
-#: gold-threads.cc:97
+#: gold-threads.cc:130
#, c-format
msgid "pthread_mutex_lock failed: %s"
msgstr ""
-#: gold-threads.cc:105
+#: gold-threads.cc:138
#, c-format
msgid "pthread_mutex_unlock failed: %s"
msgstr ""
-#: gold-threads.cc:193
+#: gold-threads.cc:219
#, c-format
msgid "pthread_cond_init failed: %s"
msgstr ""
-#: gold-threads.cc:200
+#: gold-threads.cc:226
#, c-format
msgid "pthread_cond_destroy failed: %s"
msgstr ""
-#: gold-threads.cc:208
+#: gold-threads.cc:235
#, c-format
msgid "pthread_cond_wait failed: %s"
msgstr ""
-#: gold-threads.cc:216
+#: gold-threads.cc:243
#, c-format
msgid "pthread_cond_signal failed: %s"
msgstr ""
-#: gold-threads.cc:224
+#: gold-threads.cc:251
#, c-format
msgid "pthread_cond_broadcast failed: %s"
msgstr ""
msgid "both SUN and GNU model TLS relocations"
msgstr ""
-#: merge.cc:283
+#: merge.cc:464
msgid "mergeable string section length not multiple of character size"
msgstr ""
-#: merge.cc:299
+#: merge.cc:480
msgid "entry in mergeable string section not null terminated"
msgstr ""
msgid "section %u in section group %u out of range"
msgstr ""
-#: object.cc:534 reloc.cc:226 reloc.cc:493
+#: object.cc:534 reloc.cc:229 reloc.cc:496
#, c-format
msgid "relocation section %u has bad info %u"
msgstr ""
msgid "Bind defined symbols locally"
msgstr ""
-#: options.cc:379
+#: options.cc:385
+msgid "Compress .debug_* sections in the output file (default is none)"
+msgstr ""
+
+#: options.cc:387
+msgid "--compress-debug-sections=[none"
+msgstr ""
+
+#: options.cc:387
+msgid "]"
+msgstr ""
+
+#: options.cc:390
msgid "Demangle C++ symbols in log messages"
msgstr ""
-#: options.cc:382
+#: options.cc:393
msgid "Do not demangle C++ symbols in log messages"
msgstr ""
-#: options.cc:385
+#: options.cc:396
msgid "Try to detect violations of the One Definition Rule"
msgstr ""
-#: options.cc:387
+#: options.cc:398
msgid "Export all dynamic symbols"
msgstr ""
-#: options.cc:389
+#: options.cc:400
msgid "Create exception frame header"
msgstr ""
-#: options.cc:391
+#: options.cc:402
msgid "Set dynamic linker path"
msgstr ""
-#: options.cc:392
+#: options.cc:403
msgid "-I PROGRAM, --dynamic-linker PROGRAM"
msgstr ""
-#: options.cc:394
+#: options.cc:405
msgid "Search for library LIBNAME"
msgstr ""
-#: options.cc:395
+#: options.cc:406
msgid "-lLIBNAME, --library LIBNAME"
msgstr ""
-#: options.cc:397
+#: options.cc:408
msgid "Add directory to search path"
msgstr ""
-#: options.cc:398
+#: options.cc:409
msgid "-L DIR, --library-path DIR"
msgstr ""
-#: options.cc:400
+#: options.cc:411
msgid "Ignored for compatibility"
msgstr ""
-#: options.cc:402
+#: options.cc:413
msgid "Set output file name"
msgstr ""
-#: options.cc:403
+#: options.cc:414
msgid "-o FILE, --output FILE"
msgstr ""
-#: options.cc:405
+#: options.cc:416
msgid "Optimize output file size"
msgstr ""
-#: options.cc:406
+#: options.cc:417
msgid "-O level"
msgstr ""
-#: options.cc:408
+#: options.cc:419
msgid "Generate relocatable output"
msgstr ""
-#: options.cc:410
+#: options.cc:421
msgid "Add DIR to runtime search path"
msgstr ""
-#: options.cc:411
+#: options.cc:422
msgid "-R DIR, -rpath DIR"
msgstr ""
-#: options.cc:414
+#: options.cc:425
msgid "Add DIR to link time shared library search path"
msgstr ""
-#: options.cc:415
+#: options.cc:426
msgid "--rpath-link DIR"
msgstr ""
-#: options.cc:417
+#: options.cc:428
msgid "Strip all symbols"
msgstr ""
-#: options.cc:420
+#: options.cc:431
msgid "Strip debug symbols that are unused by gdb (at least versions <= 6.7)"
msgstr ""
#. This must come after -Sdebug since it's a prefix of it.
-#: options.cc:424
+#: options.cc:435
msgid "Strip debugging information"
msgstr ""
-#: options.cc:426
+#: options.cc:437
msgid "Generate shared library"
msgstr ""
-#: options.cc:428
+#: options.cc:439
msgid "Do not link against shared libraries"
msgstr ""
-#: options.cc:430
+#: options.cc:441
msgid "Print resource usage statistics"
msgstr ""
-#: options.cc:432
+#: options.cc:443
msgid "Set target system root directory"
msgstr ""
-#: options.cc:433
+#: options.cc:444
msgid "--sysroot DIR"
msgstr ""
-#: options.cc:434
+#: options.cc:445
msgid "Set the address of the .text section"
msgstr ""
-#: options.cc:435
+#: options.cc:446
msgid "-Ttext ADDRESS"
msgstr ""
#. This must come after -Ttext since it's a prefix of it.
-#: options.cc:438
+#: options.cc:449
msgid "Read linker script"
msgstr ""
-#: options.cc:439
+#: options.cc:450
msgid "-T FILE, --script FILE"
msgstr ""
-#: options.cc:441
+#: options.cc:452
msgid "Run the linker multi-threaded"
msgstr ""
-#: options.cc:443
+#: options.cc:454
msgid "Do not run the linker multi-threaded"
msgstr ""
-#: options.cc:445
+#: options.cc:456
msgid "Number of threads to use"
msgstr ""
-#: options.cc:446
+#: options.cc:457
msgid "--thread-count COUNT"
msgstr ""
-#: options.cc:449
+#: options.cc:460
msgid "Number of threads to use in initial pass"
msgstr ""
-#: options.cc:450
+#: options.cc:461
msgid "--thread-count-initial COUNT"
msgstr ""
-#: options.cc:453
+#: options.cc:464
msgid "Number of threads to use in middle pass"
msgstr ""
-#: options.cc:454
+#: options.cc:465
msgid "--thread-count-middle COUNT"
msgstr ""
-#: options.cc:457
+#: options.cc:468
msgid "Number of threads to use in final pass"
msgstr ""
-#: options.cc:458
+#: options.cc:469
msgid "--thread-count-final COUNT"
msgstr ""
-#: options.cc:461
+#: options.cc:472
msgid "Include all archive contents"
msgstr ""
-#: options.cc:465
+#: options.cc:476
msgid "Include only needed archive contents"
msgstr ""
-#: options.cc:470
+#: options.cc:481
msgid ""
"Subcommands as follows:\n"
" -z execstack Mark output as requiring executable stack\n"
" -z noexecstack Mark output as not requiring executable stack"
msgstr ""
-#: options.cc:473
+#: options.cc:484
msgid "-z SUBCOMMAND"
msgstr ""
-#: options.cc:476
+#: options.cc:487
msgid "Start a library search group"
msgstr ""
-#: options.cc:478
+#: options.cc:489
msgid "End a library search group"
msgstr ""
-#: options.cc:480
+#: options.cc:491
msgid "Report usage information"
msgstr ""
-#: options.cc:482
+#: options.cc:493
msgid "Report version information"
msgstr ""
-#: options.cc:484
+#: options.cc:495
msgid "Turn on debugging (all,task)"
msgstr ""
-#: options.cc:485
+#: options.cc:496
msgid "--debug=TYPE"
msgstr ""
-#: options.cc:578
+#: options.cc:590
#, c-format
msgid "%s: unrecognized -z subcommand: %s\n"
msgstr ""
-#: options.cc:601
+#: options.cc:613
#, c-format
msgid "%s: unrecognized --debug subcommand: %s\n"
msgstr ""
-#: options.cc:781
+#: options.cc:793
msgid "unexpected argument"
msgstr ""
-#: options.cc:788 options.cc:840 options.cc:921
+#: options.cc:800 options.cc:852 options.cc:933
msgid "missing argument"
msgstr ""
-#: options.cc:801 options.cc:849
+#: options.cc:813 options.cc:861
msgid "unknown option"
msgstr ""
-#: options.cc:867
+#: options.cc:879
#, c-format
msgid "%s: missing group end\n"
msgstr ""
-#: options.cc:995
+#: options.cc:1007
msgid "may not nest groups"
msgstr ""
-#: options.cc:1005
+#: options.cc:1017
msgid "group end without group start"
msgstr ""
-#: options.cc:1015
+#: options.cc:1027
#, c-format
msgid "%s: use the --help option for usage information\n"
msgstr ""
-#: options.cc:1024
+#: options.cc:1036
#, c-format
msgid "%s: %s: %s\n"
msgstr ""
-#: options.cc:1033
+#: options.cc:1045
#, c-format
msgid "%s: -%c: %s\n"
msgstr ""
-#: options.h:393
+#: options.h:372
+#, c-format
+msgid "Unsupported argument to --compress-debug-symbols: %s"
+msgstr ""
+
+#: options.h:424
#, c-format
msgid "%s: invalid argument to -Ttext: %s\n"
msgstr ""
-#: options.h:406
+#: options.h:437
#, c-format
msgid "%s: invalid thread count: %s\n"
msgstr ""
-#: output.cc:1108
+#: output.cc:1122
#, c-format
msgid "invalid alignment %lu for section \"%s\""
msgstr ""
-#: output.cc:1870
+#: output.cc:1941
#, c-format
msgid "%s: open: %s"
msgstr ""
-#: output.cc:1875
+#: output.cc:1953 output.cc:1986
#, c-format
-msgid "%s: lseek: %s"
+msgid "%s: munmap: %s"
msgstr ""
-#: output.cc:1878
+#: output.cc:1967
#, c-format
-msgid "%s: write: %s"
+msgid "%s: lseek: %s"
msgstr ""
-#: output.cc:1884
+#: output.cc:1970
#, c-format
-msgid "%s: mmap: %s"
+msgid "%s: write: %s"
msgstr ""
-#: output.cc:1894
+#: output.cc:1976
#, c-format
-msgid "%s: munmap: %s"
+msgid "%s: mmap: %s"
msgstr ""
-#: output.cc:1898
+#: output.cc:1990
#, c-format
msgid "%s: close: %s"
msgstr ""
msgid "%s: not an object or archive"
msgstr ""
-#: reloc.cc:245 reloc.cc:511
+#: reloc.cc:248 reloc.cc:514
#, c-format
msgid "relocation section %u uses unexpected symbol table %u"
msgstr ""
-#: reloc.cc:260 reloc.cc:529
+#: reloc.cc:263 reloc.cc:532
#, c-format
msgid "unexpected entsize for reloc section %u: %lu != %u"
msgstr ""
-#: reloc.cc:269 reloc.cc:538
+#: reloc.cc:272 reloc.cc:541
#, c-format
msgid "reloc section %u size %lu uneven"
msgstr ""
-#: reloc.cc:729
+#: reloc.cc:732
#, c-format
msgid "reloc section size %zu is not a multiple of reloc size %d\n"
msgstr ""
"T"
msgstr ""
-#: symtab.cc:576
+#: symtab.cc:597
#, c-format
msgid "bad global symbol name offset %u at %zu"
msgstr ""
-#: symtab.cc:654
+#: symtab.cc:675
msgid "too few symbol versions"
msgstr ""
-#: symtab.cc:683
+#: symtab.cc:704
#, c-format
msgid "bad symbol name offset %u at %zu"
msgstr ""
-#: symtab.cc:737
+#: symtab.cc:758
#, c-format
msgid "versym for symbol %zu out of range: %u"
msgstr ""
-#: symtab.cc:745
+#: symtab.cc:766
#, c-format
msgid "versym for symbol %zu has no name: %u"
msgstr ""
-#: symtab.cc:1463 symtab.cc:1676
+#: symtab.cc:1484 symtab.cc:1697
#, c-format
msgid "%s: unsupported symbol section 0x%x"
msgstr ""
-#: symtab.cc:1800
+#: symtab.cc:1821
#, c-format
msgid "%s: undefined reference to '%s'"
msgstr ""
-#: symtab.cc:1941
+#: symtab.cc:1962
#, c-format
msgid ""
"while linking %s: symbol '%s' defined in multiple places (possible ODR "
"This program has absolutely no warranty.\n"
msgstr ""
-#: workqueue-threads.cc:106
+#: workqueue.cc:484
+#, c-format
+msgid "gold task queue:\n"
+msgstr ""
+
+#: workqueue-threads.cc:107
#, c-format
msgid "%s failed: %s"
msgstr ""
}
template<typename Stringpool_char>
-Stringpool_template<Stringpool_char>::~Stringpool_template()
+void
+Stringpool_template<Stringpool_char>::clear()
{
for (typename std::list<Stringdata*>::iterator p = this->strings_.begin();
p != this->strings_.end();
++p)
delete[] reinterpret_cast<char*>(*p);
+ this->strings_.clear();
+ this->string_set_.clear();
+}
+
+template<typename Stringpool_char>
+Stringpool_template<Stringpool_char>::~Stringpool_template()
+{
+ this->clear();
}
// Return the length of a string of arbitrary character type.
gold_unreachable();
}
-// Write the ELF strtab into the output file at the specified offset.
+// Write the ELF strtab into the buffer.
template<typename Stringpool_char>
void
-Stringpool_template<Stringpool_char>::write(Output_file* of, off_t offset)
+Stringpool_template<Stringpool_char>::write_to_buffer(char* buffer,
+ size_t bufsize)
{
gold_assert(this->strtab_size_ != 0);
- unsigned char* viewu = of->get_output_view(offset, this->strtab_size_);
- char* view = reinterpret_cast<char*>(viewu);
+ if (bufsize < this->strtab_size_) // Quiet the compiler in opt mode.
+ gold_assert(bufsize >= this->strtab_size_);
if (this->zero_null_)
- view[0] = '\0';
+ buffer[0] = '\0';
for (typename String_set_type::const_iterator p = this->string_set_.begin();
p != this->string_set_.end();
++p)
- memcpy(view + p->second.second, p->first,
- (string_length(p->first) + 1) * sizeof(Stringpool_char));
- of->write_output_view(offset, this->strtab_size_, viewu);
+ {
+ const int len = (string_length(p->first) + 1) * sizeof(Stringpool_char);
+ gold_assert(p->second.second + len <= this->strtab_size_);
+ memcpy(buffer + p->second.second, p->first, len);
+ }
+}
+
+// Write the ELF strtab into the output file at the specified offset.
+
+template<typename Stringpool_char>
+void
+Stringpool_template<Stringpool_char>::write(Output_file* of, off_t offset)
+{
+ gold_assert(this->strtab_size_ != 0);
+ unsigned char* view = of->get_output_view(offset, this->strtab_size_);
+ this->write_to_buffer(reinterpret_cast<char*>(view), this->strtab_size_);
+ of->write_output_view(offset, this->strtab_size_, view);
}
// Instantiate the templates we need.
~Stringpool_template();
+ // Clear all the data from the stringpool.
+ void
+ clear();
+
// Indicate that we should not reserve offset 0 to hold the empty
// string when converting the stringpool to a string table. This
// should not be called for a proper ELF SHT_STRTAB section.
void
write(Output_file*, off_t offset);
+ // Write the string table into the specified buffer, of the
+ // specified size. buffer_size should be at least
+ // get_strtab_size().
+ void
+ write_to_buffer(char* buffer, size_t buffer_size);
+
private:
Stringpool_template(const Stringpool_template&);
Stringpool_template& operator=(const Stringpool_template&);
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@