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

login
register
mail settings
Submitter Rainer Orth
Date April 30, 2013, 1:59 p.m.
Message ID <yddd2tcazm5.fsf@lokon.CeBiTec.Uni-Bielefeld.DE>
Download mbox | patch
Permalink /patch/240623/
State New
Headers show

Comments

Rainer Orth - April 30, 2013, 1:59 p.m.
"Joseph S. Myers" <joseph@codesourcery.com> writes:

> 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 

I already wondered how to do this with specs, but your suggestion worked
seamlessly, thanks.

> empty argument isn't meaningful, use Joined rather than JoinedOrMissing.)

Done.  This was a leftover from a failed attempt to handle -gz[=format]
in a single clause.

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

Right, so I've just used numeric constants.

>> +@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".

Fixed.

The patch now underwent additonal testing on i386-pc-solaris2.11.  The
following tools were handled correctly:

* Solaris as: not yet capable of generating compressed debug sections.
  Planned, but command line options not yet known.

* GNU as 2.23.1 built without zlib: just warns about
  --compressed-debug-sections, but exits successfully.

* GNU as 2.23.2 with zlib.

* Solaris 11.2 ld: no compressed debug support yet.

* Test version of Solaris 12/11.2 ld: almost final now, command line
  option changed to -z compress-sections since the ELF gABI spec allows
  compresion of any non-allocable section.  I may follow this lead for
  gas/gld/gold, so the default for --compress-debug-sections (zlib-gnu)
  can remain unchanged, but the --compress-sections default would be
  zlib, following the gABI.

* GNU ld 2.23.2: I hadn't realized that gld can decompress on input, but
  always produces uncompressed output.

* GNU gold 2.23.2: can read and write compressed sections.

Ok for mainline now?

Thanks.

	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 (compressed_debug_sections): New enum.
	(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].
Joseph S. Myers - May 3, 2013, 8:01 p.m.
On Tue, 30 Apr 2013, Rainer Orth wrote:

> 	* 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.

Note that there are separate copies of LINK_COMMAND_SPEC in darwin.h and 
i386/djgpp.h, which maybe should include the new spec.

It's not clear to me from the documentation added by this patch whether 
users are meant to specify their -gz options when compiling, when linking, 
or both - and whether there might be cases when such an option is accepted 
for one of compiling and linking but not the other (which would be 
especially confusing).

Patch

# HG changeset patch
# Parent a871a025093e293206f64a1d3b34ac7db53ee187
Enable --compress-debug-sections

diff --git a/gcc/common.opt b/gcc/common.opt
--- a/gcc/common.opt
+++ b/gcc/common.opt
@@ -2407,6 +2407,28 @@  gxcoff+
 Common JoinedOrMissing Negative(gcoff)
 Generate debug information in extended XCOFF format
 
+Enum
+Name(compressed_debug_sections) Type(int)
+
+; Since -gz= is completely handled in specs, the values aren't used and we
+; assign arbitrary constants.
+EnumValue
+Enum(compressed_debug_sections) String(none) Value(0)
+
+EnumValue
+Enum(compressed_debug_sections) String(zlib) Value(1)
+
+EnumValue
+Enum(compressed_debug_sections) String(zlib-gnu) Value(2)
+
+gz
+Common Driver
+Generate compressed debug sections
+
+gz=
+Common Driver Joined Enum(compressed_debug_sections)
+-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,30 @@  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,,,,
+  [# gas compiled without zlib cannot compress debug sections and warns
+   # about it, but still exits successfully.  So check for this, too.
+   if $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
+   elif $gcc_cv_as --compress-debug-sections -o conftest.o conftest.s > /dev/null 2>&1
+   then
+     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"
+   else
+     gcc_cv_as_compress_debug=0
+   # 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 +4555,60 @@  if test x$gcc_cv_ld_eh_gc_sections_bug =
 fi
 AC_MSG_RESULT($gcc_cv_ld_eh_gc_sections_bug)
 
+AC_MSG_CHECKING(linker for compressed debug sections)
+# 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-sections' > /dev/null; then
+        gcc_cv_ld_compress_debug=3
+        gcc_cv_ld_compress_debug_option="-z compress-sections"
+      else
+        gcc_cv_ld_compress_debug=0
+      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.])
+AC_MSG_RESULT($gcc_cv_ld_compress_debug)
+
 # --------
 # UNSORTED
 # --------
diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi
--- a/gcc/doc/invoke.texi
+++ b/gcc/doc/invoke.texi
@@ -338,7 +338,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
@@ -5072,6 +5072,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 traditional 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,32 @@  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 on input, GNU ld options.  */
+#define LINK_COMPRESS_DEBUG_SPEC \
+	" %{gz:%e-gz is not supported in this configuration}" \
+	" %{gz=none:}" \
+	" %{gz=zlib:%e-gz=zlib is not supported in this configuration}" \
+	" %{gz=zlib-gnu:%e-gz=zlib-gnu 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 +646,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 +782,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 +910,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
@@ -1750,6 +1750,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,