Patchwork [build,driver] RFC: Support compressed debug sections

login
register
mail settings
Submitter Rainer Orth
Date April 11, 2013, 11:21 a.m.
Message ID <yddvc7tmhx9.fsf@lokon.CeBiTec.Uni-Bielefeld.DE>
Download mbox | patch
Permalink /patch/235703/
State New
Headers show

Comments

Rainer Orth - April 11, 2013, 11:21 a.m.
There's some interest inside Oracle to support compressed debug sections
inside their toolchain, both on Solaris and Linux.  So far, there's the
GNU style supported by gas, gld, gold, and gdb, which mangles section
names (.debug_* -> .zdebug_*), but consultation with the Solaris linker
engineers resulted in a different style, now (almost) approved for the
ELF gABI.  The final proposal can be found here:

https://groups.google.com/forum/#!msg/generic-abi/dBOS1H47Q64/Fm_Jh9vOlG8J

I've now started to implement this for gcc and probably other parts of
the GNU toolchain.  This patch proposes to add a

	-gz[=none|zlib|zlib-gnu]

option to gcc, enabling (or disabling) compressed debug sections in
either format, and passing the necessary options to assembler and/or
linker.

It probably has rough edges since this is the first time I've been
dealing with the option handling machinery, and may or may not be
appropriate for approval at this time.

I'm asking for both comments on the general approach and specific review
comments.

So far, the patch has been tested on i386-pc-solaris2.11 with gas 2.23.2
and a version of the Solaris linker that supports -z compress-debug-sections.

	Rainer


2013-04-10  Rainer Orth  <ro@CeBiTec.Uni-Bielefeld.DE>

	* configure.ac (gcc_cv_as_compress_debug): Check for assembler
	compressed debug support.
	(gcc_cv_ld_compress_debug): Check for linker compressed debug
	support.
	* configure: Regenerate.
	* config.in: Regenerate.
	* common.opt (gz, gz=): New options.
	* gcc.c (LINK_COMPRESS_DEBUG_SPEC, ASM_COMPRESS_DEBUG_SPEC):
	Define.
	(LINK_COMMAND_SPEC): Invoke LINK_COMPRESS_DEBUG_SPEC.
	(asm_options): Invoke ASM_COMPRESS_DEBUG_SPEC.
	* opts.c (common_handle_option): Handle OPT_gz, OPT_gz_.
	* doc/invoke.texi (Option Summary, Debugging Options): Add
	-gz[=type].
	(Debugging Options): Document -gz[=type].
Andi Kleen - April 11, 2013, 11:44 a.m.
Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:

> There's some interest inside Oracle to support compressed debug sections
> inside their toolchain, both on Solaris and Linux.  So far, there's the
> GNU style supported by gas, gld, gold, and gdb, which mangles section
> names (.debug_* -> .zdebug_*), but consultation with the Solaris linker
> engineers resulted in a different style, now (almost) approved for the
> ELF gABI.  The final proposal can be found here:
>
> https://groups.google.com/forum/#!msg/generic-abi/dBOS1H47Q64/Fm_Jh9vOlG8J

None of the messages explains why the new format is better than the
existing one. For GNU this seems to have zero value.

-Andi
Rainer Orth - April 11, 2013, 12:22 p.m.
Andi Kleen <andi@firstfloor.org> writes:

> Rainer Orth <ro@CeBiTec.Uni-Bielefeld.DE> writes:
>
>> There's some interest inside Oracle to support compressed debug sections
>> inside their toolchain, both on Solaris and Linux.  So far, there's the
>> GNU style supported by gas, gld, gold, and gdb, which mangles section
>> names (.debug_* -> .zdebug_*), but consultation with the Solaris linker
>> engineers resulted in a different style, now (almost) approved for the
>> ELF gABI.  The final proposal can be found here:
>>
>> https://groups.google.com/forum/#!msg/generic-abi/dBOS1H47Q64/Fm_Jh9vOlG8J
>
> None of the messages explains why the new format is better than the
> existing one. For GNU this seems to have zero value.

It's at the beginning of the first message.  Besides, if you look at
binutils sources with several large tables mapping .debug_* to .zdebug_*
sections, there's lots of complexitiy involved in the traditional
format and the name mangling involved.

Anyway, this is now part of the gABI, and the patch at hand also works
with the old GNU style (-gz=zlib-gnu), so it has value even when the
gABI style isn't supported.  Having users invoke gcc
-Wa,--compress-debug-sections -Wl,--compress-debug-sections instead of
-gz doesn't seem to be a good user interface to me.

	Rainer
Joseph S. Myers - April 26, 2013, 3:55 p.m.
On Thu, 11 Apr 2013, Rainer Orth wrote:

> +gz=
> +Common Driver JoinedOrMissing
> +-gz=<format>	Generate compressed debug sections in format <format>

Although handled entirely in specs, I think it's best to use the Enum .opt 
facility to list the valid arguments to this option, so the option 
handling machinery can properly detect invalid arguments.  (And, since an 
empty argument isn't meaningful, use Joined rather than JoinedOrMissing.)

The integer values assigned to each valid argument string are of course 
arbitrary since nothing will use them.

> +@item -gz@r{[}=@var{type}@r{]}
> +@opindex gz
> +Produce compressed debug sections in DWARF format (if that is
> +supported).  If @var{type} is not given, the default type depends on the
> +capabilities of the assembler and linker used.  @var{type} may be one of
> +@option{none} (don't compress debug sections), @option{zlib} (use zlib
> +compression in ELF gABI format), or @option{zlib-gnu} (use zlib
> +compression in tradition GNU format).

"traditional".

Patch

# HG changeset patch
# Parent 6d495f6205ff6ab3888d907d7891cce8f7593878
Enable --compress-debug-sections

diff --git a/gcc/common.opt b/gcc/common.opt
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2375,6 +2375,14 @@  gxcoff+
 Common JoinedOrMissing Negative(gcoff)
 Generate debug information in extended XCOFF format
 
+gz
+Common Driver
+Generate compressed debug sections
+
+gz=
+Common Driver JoinedOrMissing
+-gz=<format>	Generate compressed debug sections in format <format>
+
 h
 Driver Joined Separate
 
diff --git a/gcc/configure.ac b/gcc/configure.ac
--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -4261,6 +4261,27 @@  if test x"$insn" != x; then
 [Define if your assembler supports the --debug-prefix-map option.])])
 fi
 
+gcc_GAS_CHECK_FEATURE([compressed debug sections],
+  gcc_cv_as_compress_debug,, [--compress-debug-sections],,
+  [# gas compiled without zlib cannot compress debug sections and warns
+   # about it, but still exits successfully.  So check for this.
+   if AC_TRY_COMMAND([$gcc_cv_as --compress-debug-sections -o conftest.o conftest.s 2>&1 | grep -i warning > /dev/null])
+   then
+     gcc_cv_as_compress_debug=0
+   else
+     gcc_cv_as_compress_debug=1
+     gcc_cv_as_compress_debug_option="--compress-debug-sections"
+     gcc_cv_as_no_compress_debug_option="--nocompress-debug-sections"
+   # FIXME: Future gas versions will support ELF gABI style via
+   # --compress-debug-sections[=type].
+   fi])
+AC_DEFINE_UNQUOTED(HAVE_AS_COMPRESS_DEBUG, $gcc_cv_as_compress_debug,
+[Define to the level of your assembler's compressed debug section support.])
+AC_DEFINE_UNQUOTED(AS_COMPRESS_DEBUG_OPTION, "$gcc_cv_as_compress_debug_option",
+[Define to the assembler option to enable compressed debug sections.])
+AC_DEFINE_UNQUOTED(AS_NO_COMPRESS_DEBUG_OPTION, "$gcc_cv_as_no_compress_debug_option",
+[Define to the assembler option to disable compressed debug sections.])
+
 gcc_GAS_CHECK_FEATURE([.lcomm with alignment], gcc_cv_as_lcomm_with_alignment,
  ,,
 [.lcomm bar,4,16],,
@@ -4531,6 +4552,56 @@  if test x$gcc_cv_ld_eh_gc_sections_bug =
 fi
 AC_MSG_RESULT($gcc_cv_ld_eh_gc_sections_bug)
 
+# gold/gld support compressed debug sections since binutils 2.19/2.21
+if test $in_tree_ld = yes ; then
+  gcc_cv_ld_compress_debug=0
+  if test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 19 -o "$gcc_cv_gld_major_version" -gt 2 \
+     && test $in_tree_ld_is_elf = yes && test $ld_is_gold = yes; then
+    gcc_cv_ld_compress_debug=2
+    gcc_cv_ld_compress_debug_option="--compress-debug-sections"
+  elif test "$gcc_cv_gld_major_version" -eq 2 -a "$gcc_cv_gld_minor_version" -ge 21 -o "$gcc_cv_gld_major_version" -gt 2 \
+     && test $in_tree_ld_is_elf = yes; then
+    gcc_cv_ld_compress_debug=1
+  fi
+elif echo "$ld_ver" | grep GNU > /dev/null; then
+  gcc_cv_ld_compress_debug=1
+  if test 0"$ld_date" -lt 20050308; then
+    if test -n "$ld_date"; then
+      # If there was date string, but was earlier than 2005-03-08, fail
+      gcc_cv_ld_compress_debug=0
+    elif test "$ld_vers_major" -lt 2; then
+      gcc_cv_ld_compress_debug=0
+    elif test "$ld_vers_major" -eq 2 -a "$ld_vers_minor" -lt 21; then
+      gcc_cv_ld_compress_debug=0
+    fi
+  fi
+  if test $ld_is_gold = yes; then
+    gcc_cv_ld_compress_debug=2
+    gcc_cv_ld_compress_debug_option="--compress-debug-sections"
+  fi
+else
+changequote(,)dnl
+  case "${target}" in
+    *-*-solaris2*)
+      # Introduced in Solaris 11.2.
+      if $gcc_cv_ld --help 2>&1 | grep -- '-z compress-debug-sections' > /dev/null; then
+        gcc_cv_ld_compress_debug=3
+        gcc_cv_ld_compress_debug_option="-z compress-debug-sections"
+      fi
+      ;;
+    *)
+      # Assume linkers other than GNU ld don't support compessed debug
+      # sections.
+      gcc_cv_ld_compress_debug=0
+      ;;
+  esac
+changequote([,])dnl
+fi
+AC_DEFINE_UNQUOTED(HAVE_LD_COMPRESS_DEBUG, $gcc_cv_ld_compress_debug,
+[Define to the level of your linker's compressed debug section support.])
+AC_DEFINE_UNQUOTED(LD_COMPRESS_DEBUG_OPTION, "$gcc_cv_ld_compress_debug_option",
+[Define to the linker option to enable compressed debug sections.])
+
 # --------
 # UNSORTED
 # --------
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -337,7 +337,7 @@  Objective-C and Objective-C++ Dialects}.
 -g  -g@var{level}  -gtoggle  -gcoff  -gdwarf-@var{version} @gol
 -ggdb  -grecord-gcc-switches  -gno-record-gcc-switches @gol
 -gstabs  -gstabs+  -gstrict-dwarf  -gno-strict-dwarf @gol
--gvms  -gxcoff  -gxcoff+ @gol
+-gvms  -gxcoff  -gxcoff+ -gz@r{[}=@var{type}@r{]} @gol
 -fno-merge-debug-strings -fno-dwarf2-cfi-asm @gol
 -fdebug-prefix-map=@var{old}=@var{new} @gol
 -femit-struct-debug-baseonly -femit-struct-debug-reduced @gol
@@ -4999,6 +4999,15 @@  DWARF extensions from later standard ver
 Allow using extensions of later DWARF standard version than selected with
 @option{-gdwarf-@var{version}}.
 
+@item -gz@r{[}=@var{type}@r{]}
+@opindex gz
+Produce compressed debug sections in DWARF format (if that is
+supported).  If @var{type} is not given, the default type depends on the
+capabilities of the assembler and linker used.  @var{type} may be one of
+@option{none} (don't compress debug sections), @option{zlib} (use zlib
+compression in ELF gABI format), or @option{zlib-gnu} (use zlib
+compression in tradition GNU format).
+
 @item -gvms
 @opindex gvms
 Produce debugging information in Alpha/VMS debug format (if that is
diff --git a/gcc/gcc.c b/gcc/gcc.c
--- a/gcc/gcc.c
+++ b/gcc/gcc.c
@@ -586,6 +586,31 @@  proper position among the other output f
 #define LIBTSAN_EARLY_SPEC ""
 #endif
 
+/* Linker options for compressed debug sections.  */
+#if HAVE_LD_COMPRESS_DEBUG == 0
+/* No linker support.  */
+#define LINK_COMPRESS_DEBUG_SPEC \
+	" %{gz*:%e-gz is not supported in this configuration}"
+#elif HAVE_LD_COMPRESS_DEBUG == 1
+/* GNU style, GNU ld options.  */
+#define LINK_COMPRESS_DEBUG_SPEC \
+	" %{gz|gz=zlib-gnu:}" \
+	" %{gz=none:%e-gz=none is not supported in this configuration}" \
+	" %{gz=zlib:%e-gz=zlib is not supported in this configuration}"
+#elif HAVE_LD_COMPRESS_DEBUG == 2
+/* GNU style, GNU gold options.  */
+#define LINK_COMPRESS_DEBUG_SPEC \
+	" %{gz|gz=zlib-gnu:" LD_COMPRESS_DEBUG_OPTION "=zlib}" \
+	" %{gz=none:"        LD_COMPRESS_DEBUG_OPTION "=none}" \
+	" %{gz=zlib:%e-gz=zlib is not supported in this configuration}"
+#else
+/* ELF gABI style.  */
+#define LINK_COMPRESS_DEBUG_SPEC \
+	" %{gz|gz=zlib:"  LD_COMPRESS_DEBUG_OPTION "=zlib}" \
+	" %{gz=none:"	  LD_COMPRESS_DEBUG_OPTION "=none}" \
+	" %{gz=zlib-gnu:" LD_COMPRESS_DEBUG_OPTION "=zlib-gnu}"
+#endif
+
 /* config.h can define LIBGCC_SPEC to override how and when libgcc.a is
    included.  */
 #ifndef LIBGCC_SPEC
@@ -620,6 +645,25 @@  proper position among the other output f
 #define ASM_MAP ""
 #endif
 
+/* Assembler options for compressed debug sections.  */
+#if HAVE_AS_COMPRESS_DEBUG == 0
+/* No assembler support.  */
+#define ASM_COMPRESS_DEBUG_SPEC \
+	" %{gz*:%e-gz is not supported in this configuration}"
+#elif HAVE_AS_COMPRESS_DEBUG == 1
+/* GNU style, GNU as options.  */
+#define ASM_COMPRESS_DEBUG_SPEC \
+	" %{gz|gz=zlib-gnu:" AS_COMPRESS_DEBUG_OPTION "}" \
+	" %{gz=none:"        AS_NO_COMPRESS_DEBUG_OPTION "}" \
+	" %{gz=zlib:%e-gz=zlib is not supported in this configuration}"
+#else
+/* ELF gABI style.  */
+#define ASM_COMPRESS_DEBUG_SPEC \
+	" %{gz|gz=zlib:"  AS_COMPRESS_DEBUG_OPTION "=zlib}" \
+	" %{gz=none:"	  AS_COMPRESS_DEBUG_OPTION "=none}" \
+	" %{gz=zlib-gnu:" AS_COMPRESS_DEBUG_OPTION "=zlib-gnu}"
+#endif
+
 /* Define ASM_DEBUG_SPEC to be a spec suitable for translating '-g'
    to the assembler.  */
 #ifndef ASM_DEBUG_SPEC
@@ -737,8 +781,8 @@  proper position among the other output f
     LINK_PLUGIN_SPEC \
    "%{flto|flto=*:%<fcompare-debug*} \
     %{flto} %{flto=*} %l " LINK_PIE_SPEC \
-   "%{fuse-ld=*:-fuse-ld=%*}\
-    %X %{o*} %{e*} %{N} %{n} %{r}\
+   "%{fuse-ld=*:-fuse-ld=%*} " LINK_COMPRESS_DEBUG_SPEC \
+   "%X %{o*} %{e*} %{N} %{n} %{r}\
     %{s} %{t} %{u*} %{z} %{Z} %{!nostdlib:%{!nostartfiles:%S}}\
     %{static:} %{L*} %(mfwrap) %(link_libgcc) " SANITIZER_EARLY_SPEC " %o\
     %{fopenmp|ftree-parallelize-loops=*:%:include(libgomp.spec)%(link_gomp)}\
@@ -865,6 +909,7 @@  static const char *asm_options =
    to the assembler equivalents.  */
 "%{v} %{w:-W} %{I*} "
 #endif
+ASM_COMPRESS_DEBUG_SPEC
 "%a %Y %{c:%W{o*}%{!o*:-o %w%b%O}}%{!c:-o %d%w%u%O}";
 
 static const char *invoke_as =
diff --git a/gcc/opts.c b/gcc/opts.c
--- a/gcc/opts.c
+++ b/gcc/opts.c
@@ -1732,6 +1732,11 @@  common_handle_option (struct gcc_options
 		       loc);
       break;
 
+    case OPT_gz:
+    case OPT_gz_:
+      /* Handled completely via specs.  */
+      break;
+
     case OPT_pedantic_errors:
       dc->pedantic_errors = 1;
       control_warning_option (OPT_Wpedantic, DK_ERROR, value,