aboutsummaryrefslogtreecommitdiff
path: root/gold
diff options
context:
space:
mode:
authorIan Lance Taylor <iant@google.com>2007-11-30 00:35:27 +0000
committerIan Lance Taylor <iant@google.com>2007-11-30 00:35:27 +0000
commit9a0910c33e1a6962d475ee0a994fd1f5e446a888 (patch)
treef30e7b369cc05383699fbe4780ee0839b8dbcdde /gold
parent71195202dfb59bb7b61b35dc4cc5d202fab12020 (diff)
downloadgdb-9a0910c33e1a6962d475ee0a994fd1f5e446a888.zip
gdb-9a0910c33e1a6962d475ee0a994fd1f5e446a888.tar.gz
gdb-9a0910c33e1a6962d475ee0a994fd1f5e446a888.tar.bz2
From Craig Silverstein: Add support for compressing .debug_str section.
Diffstat (limited to 'gold')
-rw-r--r--gold/Makefile.am2
-rw-r--r--gold/Makefile.in7
-rw-r--r--gold/compressed_output.cc267
-rw-r--r--gold/compressed_output.h137
-rw-r--r--gold/config.in3
-rwxr-xr-xgold/configure608
-rw-r--r--gold/configure.ac3
-rw-r--r--gold/layout.cc46
-rw-r--r--gold/layout.h20
-rw-r--r--gold/merge.cc21
-rw-r--r--gold/merge.h16
-rw-r--r--gold/options.cc12
-rw-r--r--gold/options.h36
-rw-r--r--gold/output.cc112
-rw-r--r--gold/output.h45
-rw-r--r--gold/po/POTFILES.in2
-rw-r--r--gold/po/gold.pot246
-rw-r--r--gold/stringpool.cc42
-rw-r--r--gold/stringpool.h10
-rw-r--r--gold/testsuite/Makefile.in1
20 files changed, 1429 insertions, 207 deletions
diff --git a/gold/Makefile.am b/gold/Makefile.am
index de9be20..84c39b9 100644
--- a/gold/Makefile.am
+++ b/gold/Makefile.am
@@ -30,6 +30,7 @@ noinst_LIBRARIES = libgold.a
CCFILES = \
archive.cc \
common.cc \
+ compressed_output.cc \
defstd.cc \
dirsearch.cc \
dynobj.cc \
@@ -59,6 +60,7 @@ CCFILES = \
HFILES = \
archive.h \
common.h \
+ compressed_output.h \
defstd.h \
dirsearch.h \
dynobj.h \
diff --git a/gold/Makefile.in b/gold/Makefile.in
index fd981d6..cae5524 100644
--- a/gold/Makefile.in
+++ b/gold/Makefile.in
@@ -70,7 +70,8 @@ AR = ar
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) \
@@ -152,6 +153,7 @@ CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@
@@ -285,6 +287,7 @@ noinst_LIBRARIES = libgold.a
CCFILES = \
archive.cc \
common.cc \
+ compressed_output.cc \
defstd.cc \
dirsearch.cc \
dynobj.cc \
@@ -314,6 +317,7 @@ CCFILES = \
HFILES = \
archive.h \
common.h \
+ compressed_output.h \
defstd.h \
dirsearch.h \
dynobj.h \
@@ -465,6 +469,7 @@ distclean-compile:
@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@
diff --git a/gold/compressed_output.cc b/gold/compressed_output.cc
new file mode 100644
index 0000000..1006ac8
--- /dev/null
+++ b/gold/compressed_output.cc
@@ -0,0 +1,267 @@
+// 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.
diff --git a/gold/compressed_output.h b/gold/compressed_output.h
new file mode 100644
index 0000000..589dacc
--- /dev/null
+++ b/gold/compressed_output.h
@@ -0,0 +1,137 @@
+// 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)
diff --git a/gold/config.in b/gold/config.in
index 7550224..9c0db95 100644
--- a/gold/config.in
+++ b/gold/config.in
@@ -67,6 +67,9 @@
/* 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
diff --git a/gold/configure b/gold/configure
index 7648c2c..66e6167 100755
--- a/gold/configure
+++ b/gold/configure
@@ -309,7 +309,7 @@ ac_includes_default="\
# 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.
@@ -774,6 +774,10 @@ ac_env_CXXFLAGS_set=${CXXFLAGS+set}
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}
@@ -884,6 +888,7 @@ Some influential environment variables:
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
@@ -4755,30 +4760,27 @@ done
-ac_ext=cc
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
-
-
-
-ac_ext=cc
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_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
-if test -z "$CXXCPP"; then
- if test "${ac_cv_prog_CXXCPP+set}" = set; then
+# 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 CXXCPP needs to be expanded
- for CXXCPP in "$CXX -E" "/lib/cpp"
+ # 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_cxx_preproc_warn_flag in '' yes
+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.
@@ -4808,8 +4810,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
- ac_cpp_err=$ac_cxx_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -4846,8 +4848,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
- ac_cpp_err=$ac_cxx_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -4875,17 +4877,17 @@ if $ac_preproc_ok; then
fi
done
- ac_cv_prog_CXXCPP=$CXXCPP
+ ac_cv_prog_CPP=$CPP
fi
- CXXCPP=$ac_cv_prog_CXXCPP
+ CPP=$ac_cv_prog_CPP
else
- ac_cv_prog_CXXCPP=$CXXCPP
+ ac_cv_prog_CPP=$CPP
fi
-echo "$as_me:$LINENO: result: $CXXCPP" >&5
-echo "${ECHO_T}$CXXCPP" >&6
+echo "$as_me:$LINENO: result: $CPP" >&5
+echo "${ECHO_T}$CPP" >&6
ac_preproc_ok=false
-for ac_cxx_preproc_warn_flag in '' yes
+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.
@@ -4915,8 +4917,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
- ac_cpp_err=$ac_cxx_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -4953,8 +4955,8 @@ if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } >/dev/null; then
if test -s conftest.err; then
- ac_cpp_err=$ac_cxx_preproc_warn_flag
- ac_cpp_err=$ac_cpp_err$ac_cxx_werror_flag
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
else
ac_cpp_err=
fi
@@ -4980,18 +4982,18 @@ rm -f conftest.err conftest.$ac_ext
if $ac_preproc_ok; then
:
else
- { { echo "$as_me:$LINENO: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+ { { echo "$as_me:$LINENO: error: C preprocessor \"$CPP\" fails sanity check
See \`config.log' for more details." >&5
-echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+echo "$as_me: error: C preprocessor \"$CPP\" fails sanity check
See \`config.log' for more details." >&2;}
{ (exit 1); exit 1; }; }
fi
-ac_ext=cc
-ac_cpp='$CXXCPP $CPPFLAGS'
-ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+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
@@ -5042,7 +5044,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_cxx_werror_flag"
+ { 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
@@ -5213,7 +5215,7 @@ if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
cat conftest.err >&5
echo "$as_me:$LINENO: \$? = $ac_status" >&5
(exit $ac_status); } &&
- { ac_try='test -z "$ac_cxx_werror_flag"
+ { 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
@@ -5247,6 +5249,521 @@ 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_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_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
+if test -z "$CXXCPP"; then
+ if test "${ac_cv_prog_CXXCPP+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ # Double quotes because CXXCPP needs to be expanded
+ for CXXCPP in "$CXX -E" "/lib/cpp"
+ do
+ ac_preproc_ok=false
+for ac_cxx_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_cxx_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_cxx_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_cxx_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_cxx_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_CXXCPP=$CXXCPP
+
+fi
+ CXXCPP=$ac_cv_prog_CXXCPP
+else
+ ac_cv_prog_CXXCPP=$CXXCPP
+fi
+echo "$as_me:$LINENO: result: $CXXCPP" >&5
+echo "${ECHO_T}$CXXCPP" >&6
+ac_preproc_ok=false
+for ac_cxx_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_cxx_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_cxx_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_cxx_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_cxx_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 \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&5
+echo "$as_me: error: C++ preprocessor \"$CXXCPP\" fails sanity check
+See \`config.log' for more details." >&2;}
+ { (exit 1); exit 1; }; }
+fi
+
+ac_ext=cc
+ac_cpp='$CXXCPP $CPPFLAGS'
+ac_compile='$CXX -c $CXXFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CXX -o conftest$ac_exeext $CXXFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
+
+
for ac_header in tr1/unordered_set tr1/unordered_map
@@ -6534,8 +7051,9 @@ s,@NO_WERROR@,$NO_WERROR,;t t
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
diff --git a/gold/configure.ac b/gold/configure.ac
index e230b5f..ea4fd67 100644
--- a/gold/configure.ac
+++ b/gold/configure.ac
@@ -202,6 +202,9 @@ AC_SUBST(LFS_CXXFLAGS)
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)
diff --git a/gold/layout.cc b/gold/layout.cc
index d95aea4..f7c1e40 100644
--- a/gold/layout.cc
+++ b/gold/layout.cc
@@ -393,7 +393,7 @@ Output_section*
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)
@@ -710,7 +710,7 @@ Layout::finalize(const Input_objects* input_objects, Symbol_table* symtab)
// 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);
@@ -1059,7 +1059,7 @@ Layout::set_segment_offsets(const Target* target, Output_segment* load_seg,
// 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();
@@ -1069,8 +1069,17 @@ Layout::set_section_offsets(off_t off, bool after_input_sections)
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);
@@ -1080,6 +1089,19 @@ Layout::set_section_offsets(off_t off, bool after_input_sections)
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.
@@ -1883,9 +1905,19 @@ void
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);
diff --git a/gold/layout.h b/gold/layout.h
index 0659d1b..cff29ed 100644
--- a/gold/layout.h
+++ b/gold/layout.h
@@ -342,9 +342,25 @@ class Layout
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.
diff --git a/gold/merge.cc b/gold/merge.cc
index 726a972..215bc34 100644
--- a/gold/merge.cc
+++ b/gold/merge.cc
@@ -496,13 +496,12 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
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();
@@ -513,10 +512,18 @@ Output_merge_string<Char_type>::set_final_data_size()
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.
diff --git a/gold/merge.h b/gold/merge.h
index 70fe6b7..a28ff42 100644
--- a/gold/merge.h
+++ b/gold/merge.h
@@ -209,10 +209,16 @@ class Output_merge_string : public Output_merge_base
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();
@@ -221,6 +227,16 @@ class Output_merge_string : public Output_merge_base
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.
diff --git a/gold/options.cc b/gold/options.cc
index fb79901..f5fc8da 100644
--- a/gold/options.cc
+++ b/gold/options.cc
@@ -376,6 +376,17 @@ options::Command_line_options::options[] =
&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",
@@ -525,6 +536,7 @@ General_options::General_options()
strip_(STRIP_NONE),
allow_shlib_undefined_(false),
symbolic_(false),
+ compress_debug_sections_(NO_COMPRESSION),
detect_odr_violations_(false),
create_eh_frame_hdr_(false),
rpath_(),
diff --git a/gold/options.h b/gold/options.h
index c7b08e8..b327aa9 100644
--- a/gold/options.h
+++ b/gold/options.h
@@ -150,8 +150,8 @@ class General_options
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; }
@@ -167,6 +167,17 @@ class General_options
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
@@ -288,6 +299,13 @@ class General_options
EXECSTACK_NO
};
+ // What compression method to use
+ enum CompressionMethod
+ {
+ NO_COMPRESSION,
+ ZLIB_COMPRESSION,
+ };
+
void
set_export_dynamic()
{ this->export_dynamic_ = true; }
@@ -342,6 +360,19 @@ class General_options
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; }
@@ -476,6 +507,7 @@ class General_options
Strip strip_;
bool allow_shlib_undefined_;
bool symbolic_;
+ CompressionMethod compress_debug_sections_;
bool demangle_;
bool detect_odr_violations_;
bool create_eh_frame_hdr_;
diff --git a/gold/output.cc b/gold/output.cc
index d89c72a..351c21d 100644
--- a/gold/output.cc
+++ b/gold/output.cc
@@ -32,6 +32,7 @@
#include "libiberty.h" // for unlink_if_ordinary()
#include "parameters.h"
+#include "compressed_output.h"
#include "object.h"
#include "symtab.h"
#include "reloc.h"
@@ -1033,9 +1034,11 @@ Output_section::Input_section::write(Output_file* of)
// 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),
@@ -1079,6 +1082,22 @@ Output_section::set_entsize(uint64_t v)
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
@@ -1126,7 +1145,8 @@ Output_section::add_input_section(Sized_relobj<size, big_endian>* object,
&& 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.
@@ -1213,7 +1233,8 @@ Output_section::add_output_merge_section(Output_section_data* posd,
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;
@@ -1227,30 +1248,56 @@ Output_section::add_merge_input_section(Relobj* object, unsigned int shndx,
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;
}
@@ -1367,6 +1414,29 @@ Output_section::set_final_data_size()
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>
diff --git a/gold/output.h b/gold/output.h
index 05ed1f8..95d95f6 100644
--- a/gold/output.h
+++ b/gold/output.h
@@ -432,6 +432,15 @@ class Output_section_data : public Output_data
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
@@ -1308,7 +1317,8 @@ class Output_section : public Output_data
{
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
@@ -1331,6 +1341,13 @@ class Output_section : public Output_data
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
@@ -1518,6 +1535,16 @@ class Output_section : public Output_data
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
@@ -1663,6 +1690,15 @@ class Output_section : public Output_data
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)
@@ -1777,7 +1813,8 @@ class Output_section : public Output_data
// 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
@@ -1789,8 +1826,10 @@ class Output_section : public Output_data
// 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_;
diff --git a/gold/po/POTFILES.in b/gold/po/POTFILES.in
index 3797b1a..e8a5ba7 100644
--- a/gold/po/POTFILES.in
+++ b/gold/po/POTFILES.in
@@ -2,6 +2,8 @@ archive.cc
archive.h
common.cc
common.h
+compressed_output.cc
+compressed_output.h
defstd.cc
defstd.h
dirsearch.cc
diff --git a/gold/po/gold.pot b/gold/po/gold.pot
index 73f1f01..8d97ea1 100644
--- a/gold/po/gold.pot
+++ b/gold/po/gold.pot
@@ -8,7 +8,7 @@ msgid ""
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"
@@ -61,6 +61,10 @@ msgstr ""
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"
@@ -179,22 +183,22 @@ msgstr ""
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 ""
@@ -271,62 +275,62 @@ 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 ""
@@ -371,11 +375,11 @@ 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 ""
@@ -419,7 +423,7 @@ 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 ""
@@ -549,314 +553,331 @@ 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 ""
@@ -877,22 +898,22 @@ 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 ""
@@ -934,41 +955,41 @@ msgid ""
"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 "
@@ -1003,7 +1024,12 @@ msgid ""
"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 ""
diff --git a/gold/stringpool.cc b/gold/stringpool.cc
index db04b0c..42a2fda 100644
--- a/gold/stringpool.cc
+++ b/gold/stringpool.cc
@@ -41,12 +41,21 @@ Stringpool_template<Stringpool_char>::Stringpool_template()
}
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.
@@ -413,23 +422,38 @@ Stringpool_template<Stringpool_char>::get_offset(const Stringpool_char* s)
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.
diff --git a/gold/stringpool.h b/gold/stringpool.h
index 80e53be..57725a5 100644
--- a/gold/stringpool.h
+++ b/gold/stringpool.h
@@ -84,6 +84,10 @@ class Stringpool_template
~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.
@@ -139,6 +143,12 @@ class Stringpool_template
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&);
diff --git a/gold/testsuite/Makefile.in b/gold/testsuite/Makefile.in
index f908dc3..a3d6aa5 100644
--- a/gold/testsuite/Makefile.in
+++ b/gold/testsuite/Makefile.in
@@ -445,6 +445,7 @@ CATOBJEXT = @CATOBJEXT@
CC = @CC@
CCDEPMODE = @CCDEPMODE@
CFLAGS = @CFLAGS@
+CPP = @CPP@
CPPFLAGS = @CPPFLAGS@
CXX = @CXX@
CXXCPP = @CXXCPP@