public inbox for binutils@sourceware.org
 help / color / mirror / Atom feed
* PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
@ 2015-04-13 12:38 H.J. Lu
  2015-04-15  0:55 ` Alan Modra
  0 siblings, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2015-04-13 12:38 UTC (permalink / raw)
  To: Binutils

[-- Attachment #1: Type: text/plain, Size: 1968 bytes --]

On Sun, Apr 12, 2015 at 6:13 PM, Alan Modra <amodra@gmail.com> wrote:
> On Thu, Apr 09, 2015 at 03:07:20PM -0700, H.J. Lu wrote:
>> +  if (arg->link_info
>> +      && (arg->link_info->compress_debug & COMPRESS_DEBUG)
>> +      && arg->link_info->compress_debug != COMPRESS_DEBUG_GABI_ZLIB
>> +      && (asect->flags & SEC_DEBUGGING)
>> +      && name[1] == 'd'
>> +      && name[6] == '_')
>
> Here and in a couple of other places you omit checking the full prefix
> of the name.  Are you certain you won't see something like a ".de"
> section here?  It you might, then name[6] is a buffer overflow and a
> potential segfault.

elf.c has

  if ((flags & SEC_ALLOC) == 0)
    {
      /* The debugging sections appear to be recognized only by name,
         not any sort of flag.  Their SEC_ALLOC bits are cleared.  */
      if (name [0] == '.')
        {
          const char *p;
          int n;
          if (name[1] == 'd')
            p = ".debug", n = 6;
          else if (name[1] == 'g' && name[2] == 'n')
            p = ".gnu.linkonce.wi.", n = 17;
          else if (name[1] == 'g' && name[2] == 'd')
            p = ".gdb_index", n = 11; /* yes we really do mean 11.  */
          else if (name[1] == 'l')
            p = ".line", n = 5;
          else if (name[1] == 's')
            p = ".stab", n = 5;
          else if (name[1] == 'z')
            p = ".zdebug", n = 7;
          else
            p = NULL, n = 0;
          if (p != NULL && strncmp (name, p, n) == 0)
            flags |= SEC_DEBUGGING;
        }
    }

and

 /* Compress/decompress DWARF debug sections with names: .debug_* and
     .zdebug_*, after the section flags is set.  */
  if ((flags & SEC_DEBUGGING)
      && ((name[1] == 'd' && name[6] == '_')
          || (name[1] == 'z' && name[7] == '_')))
    {

When name[1] == 'd'.  It is pretty safe to check name[1] == 'd' &&
name[6] == '_'
when SEC_DEBUGGING is set.

Here is the completed patch.  OK for master?

Thanks.

-- 
H.J.

[-- Attachment #2: 0001-Add-compress-debug-sections-none-zlib-zlib-gnu-zlib-.patch --]
[-- Type: text/x-patch, Size: 33704 bytes --]

From f6134092f395177cedbca1a2cb519e9f1b3c6ffb Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 13 Apr 2015 05:30:52 -0700
Subject: [PATCH] Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi]

This patch adds --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi]
to ld for ELF targets to support generating compressed DWARF debug
sections.  We always generate .zdebug_* section since section names have
been finalized and they can't be changed easily when compression is
being performed.

bfd/

	* bfd-in.h (compressed_debug_section_type): New.
	* compress.c (bfd_compress_section_contents): Add an argument
	for linker write compression and always generate .zdebug_*
	section when linking.
	(bfd_init_section_compress_status): Pass FALSE to
	bfd_compress_section_contents.
	(bfd_compress_section): New function.
	* elf.c (elf_fake_sections): For linking, set SEC_ELF_COMPRESS
	on DWARF debug sections if COMPRESS_DEBUG is set and rename
	section if COMPRESS_DEBUG_GABI_ZLIB isn't set.
	(assign_file_positions_for_non_load_sections): Set sh_offset
	to -1 if SEC_ELF_COMPRESS is set.
	(assign_file_positions_except_relocs): Likwise.
	(_bfd_elf_assign_file_positions_for_relocs): Renamed to ...
	(_bfd_elf_assign_file_positions_for_non_load): This.  Change
	return time to bfd_boolean.  Compress the section if
	SEC_ELF_COMPRESS is set.
	(_bfd_elf_write_object_contents): Updated.
	(_bfd_elf_set_section_contents): Allocate the buffer for contents
	if SEC_ELF_COMPRESS is set.
	* merge.c: Include "elf-bfd.h".
	(sec_merge_emit): Add an argument for offset.  For ELF, write
	to contents if sh_offset is -1.
	(_bfd_write_merged_section): Allocate the buffer for contents
	if SEC_ELF_COMPRESS is set.  Pass output_offset to
	sec_merge_emit.
	* section.c (SEC_ELF_COMPRESS): New.
	* bfd-in2.h: Regenerated.

gas/

	* as.h (compressed_debug_section_type): Removed.

include/

	* bfdlink.h (bfd_link_info): Add compress_debug.

ld/

	* ld.texinfo: Document --compress-debug-sections=.
	* ldmain.c (main): Set BFD_COMPRESS on output_bfd if
	COMPRESS_DEBUG is set.  Set BFD_COMPRESS_GABI on output_bfd
	for COMPRESS_DEBUG_GABI_ZLIB.
	* lexsup.c (elf_static_list_options): Add
	--compress-debug-sections=.
	* emultempl/elf32.em (OPTION_COMPRESS_DEBUG): New.
	(xtra_long): Add "compress-debug-sections".
	(gld${EMULATION_NAME}_handle_option): Handle
	OPTION_COMPRESS_DEBUG.

ld/testsuite/

	* ld-elf/compress.exp (build_tests): Add tests for
	--compress-debug-sections=.
	(run_tests): Likewise.
	Add additonal tests for --compress-debug-sections=.
	* ld-elf/gabiend.rt: New file.
	* ld-elf/gabinormal.rt: Likewise.
	* ld-elf/gnubegin.rS: Likewise.
	* ld-elf/gnunormal.rS: Likewise.
	* ld-elf/zlibbegin.rS: Likewise.
	* ld-elf/zlibnormal.rS: Likewise.
---
 bfd/bfd-in.h                      |  11 +++
 bfd/bfd-in2.h                     |  18 ++++
 bfd/compress.c                    |  51 +++++++++++-
 bfd/elf.c                         |  97 ++++++++++++++++++++--
 bfd/merge.c                       |  76 ++++++++++++++---
 bfd/section.c                     |   4 +
 gas/as.h                          |  10 ---
 include/bfdlink.h                 |   3 +
 ld/emultempl/elf32.em             |  15 ++++
 ld/ld.texinfo                     |  16 ++++
 ld/ldmain.c                       |   7 ++
 ld/lexsup.c                       |   3 +
 ld/testsuite/ld-elf/compress.exp  | 167 +++++++++++++++++++++++++++++++++++++-
 ld/testsuite/ld-elf/gabiend.rt    |   4 +
 ld/testsuite/ld-elf/gabinormal.rt |   4 +
 ld/testsuite/ld-elf/gnubegin.rS   |   3 +
 ld/testsuite/ld-elf/gnunormal.rS  |   3 +
 ld/testsuite/ld-elf/zlibbegin.rS  |   3 +
 ld/testsuite/ld-elf/zlibnormal.rS |   3 +
 19 files changed, 466 insertions(+), 32 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/gabiend.rt
 create mode 100644 ld/testsuite/ld-elf/gabinormal.rt
 create mode 100644 ld/testsuite/ld-elf/gnubegin.rS
 create mode 100644 ld/testsuite/ld-elf/gnunormal.rS
 create mode 100644 ld/testsuite/ld-elf/zlibbegin.rS
 create mode 100644 ld/testsuite/ld-elf/zlibnormal.rS

diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index 1f8a72c..2e324cd 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -437,6 +437,17 @@ extern void bfd_hash_traverse
    this size.  */
 extern unsigned long bfd_hash_set_default_size (unsigned long);
 
+/* Types of compressed DWARF debug sections.  We currently support
+   zlib.  */
+enum compressed_debug_section_type
+{
+  COMPRESS_DEBUG_NONE = 0,
+  COMPRESS_DEBUG = 1 << 0,
+  COMPRESS_DEBUG_ZLIB = COMPRESS_DEBUG | 1 << 1,
+  COMPRESS_DEBUG_GNU_ZLIB = COMPRESS_DEBUG | 1 << 2,
+  COMPRESS_DEBUG_GABI_ZLIB = COMPRESS_DEBUG | 1 << 3
+};
+
 /* This structure is used to keep track of stabs in sections
    information while linking.  */
 
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 679595e..122caa0 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -444,6 +444,17 @@ extern void bfd_hash_traverse
    this size.  */
 extern unsigned long bfd_hash_set_default_size (unsigned long);
 
+/* Types of compressed DWARF debug sections.  We currently support
+   zlib.  */
+enum compressed_debug_section_type
+{
+  COMPRESS_DEBUG_NONE = 0,
+  COMPRESS_DEBUG = 1 << 0,
+  COMPRESS_DEBUG_ZLIB = COMPRESS_DEBUG | 1 << 1,
+  COMPRESS_DEBUG_GNU_ZLIB = COMPRESS_DEBUG | 1 << 2,
+  COMPRESS_DEBUG_GABI_ZLIB = COMPRESS_DEBUG | 1 << 3
+};
+
 /* This structure is used to keep track of stabs in sections
    information while linking.  */
 
@@ -1378,6 +1389,10 @@ typedef struct bfd_section
      executables or shared objects. This is for COFF only.  */
 #define SEC_COFF_SHARED 0x8000000
 
+  /* This section should be compressed.  This is for ELF linker
+     internal use only.  */
+#define SEC_ELF_COMPRESS 0x8000000
+
   /* When a section with this flag is being linked, then if the size of
      the input section is less than a page, it should not cross a page
      boundary.  If the size of the input section is one page or more,
@@ -7316,6 +7331,9 @@ bfd_boolean bfd_init_section_decompress_status
 bfd_boolean bfd_init_section_compress_status
    (bfd *abfd, asection *section);
 
+bfd_boolean bfd_compress_section
+   (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/bfd/compress.c b/bfd/compress.c
index 770ea57..dfde50e 100644
--- a/bfd/compress.c
+++ b/bfd/compress.c
@@ -72,7 +72,8 @@ decompress_contents (bfd_byte *compressed_buffer,
 static bfd_size_type
 bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
 			       bfd_byte *uncompressed_buffer,
-			       bfd_size_type uncompressed_size)
+			       bfd_size_type uncompressed_size,
+			       bfd_boolean write_compress)
 {
   uLong compressed_size;
   bfd_byte *buffer;
@@ -176,8 +177,11 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
 
       compressed_size += header_size;
       /* PR binutils/18087: If compression didn't make the section smaller,
-	 just keep it uncompressed.  */
-      if (compressed_size < uncompressed_size)
+	 just keep it uncompressed.  We always generate .zdebug_* section
+	 when linking since section names have been finalized and they
+	 can't be changed easily.  */
+      if ((write_compress && compression_header_size == 0)
+	   || compressed_size < uncompressed_size)
 	{
 	  bfd_update_compression_header (abfd, buffer, sec);
 
@@ -543,9 +547,48 @@ bfd_init_section_compress_status (bfd *abfd, sec_ptr sec)
     {
       uncompressed_size = bfd_compress_section_contents (abfd, sec,
 							 uncompressed_buffer,
-							 uncompressed_size);
+							 uncompressed_size,
+							 FALSE);
       ret = uncompressed_size != 0;
     }
 
   return ret;
 }
+
+/*
+FUNCTION
+	bfd_compress_section
+
+SYNOPSIS
+	bfd_boolean bfd_compress_section
+	  (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer);
+
+DESCRIPTION
+	If open for write, compress section, update section size with
+	compressed size and set compress_status to COMPRESS_SECTION_DONE.
+
+	Return @code{FALSE} if compression fail.  Otherwise, return
+	@code{TRUE}.
+*/
+
+bfd_boolean
+bfd_compress_section (bfd *abfd, sec_ptr sec, bfd_byte *uncompressed_buffer)
+{
+  bfd_size_type uncompressed_size = sec->size;
+
+  /* Error if not opened for write.  */
+  if (abfd->direction != write_direction
+      || uncompressed_size == 0
+      || uncompressed_buffer == NULL
+      || sec->contents != NULL
+      || sec->compressed_size != 0
+      || sec->compress_status != COMPRESS_SECTION_NONE)
+    {
+      bfd_set_error (bfd_error_invalid_operation);
+      return FALSE;
+    }
+
+  /* Compress it.  */
+  return bfd_compress_section_contents (abfd, sec, uncompressed_buffer,
+					uncompressed_size, TRUE) != 0;
+}
diff --git a/bfd/elf.c b/bfd/elf.c
index a031b9e..dcd24c1 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -2752,6 +2752,7 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
   struct bfd_elf_section_data *esd = elf_section_data (asect);
   Elf_Internal_Shdr *this_hdr;
   unsigned int sh_type;
+  const char *name = asect->name;
 
   if (arg->failed)
     {
@@ -2762,8 +2763,38 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
 
   this_hdr = &esd->this_hdr;
 
+  /* For linking, compress DWARF debug sections with names: .debug_*.  */
+  if (arg->link_info
+      && (arg->link_info->compress_debug & COMPRESS_DEBUG)
+      && (asect->flags & SEC_DEBUGGING)
+      && name[1] == 'd'
+      && name[6] == '_')
+    {
+      /* Set SEC_ELF_COMPRESS to indicate this section should be
+	 compressed.  */
+      asect->flags |= SEC_ELF_COMPRESS;
+
+      if (arg->link_info->compress_debug != COMPRESS_DEBUG_GABI_ZLIB)
+	{
+	  /* If SHF_COMPRESSED isn't used, rename compressed DWARF
+	     debug section to .zdebug_*.  */
+	  unsigned int len = strlen (name);
+	  char *new_name = bfd_alloc (abfd, len + 2);
+	  if (new_name == NULL)
+	    {
+	      arg->failed = TRUE;
+	      return;
+	    }
+	  new_name[0] = '.';
+	  new_name[1] = 'z';
+	  memcpy (new_name + 2, name + 1, len);
+	  bfd_rename_section (abfd, asect, new_name);
+	  name = asect->name;
+	}
+    }
+
   this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
-							  asect->name, FALSE);
+							  name, FALSE);
   if (this_hdr->sh_name == (unsigned int) -1)
     {
       arg->failed = TRUE;
@@ -5116,6 +5147,9 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
 	}
       else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
 		&& hdr->bfd_section == NULL)
+	       || (hdr->bfd_section != NULL
+		   && (hdr->bfd_section->flags & SEC_ELF_COMPRESS))
+		   /* Compress DWARF debug sections.  */
 	       || hdr == i_shdrpp[elf_onesymtab (abfd)]
 	       || hdr == i_shdrpp[elf_symtab_shndx (abfd)]
 	       || hdr == i_shdrpp[elf_strtab_sec (abfd)])
@@ -5365,6 +5399,9 @@ assign_file_positions_except_relocs (bfd *abfd,
 	  hdr = *hdrpp;
 	  if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
 	       && hdr->bfd_section == NULL)
+	      || (hdr->bfd_section != NULL
+		  && (hdr->bfd_section->flags & SEC_ELF_COMPRESS))
+		  /* Compress DWARF debug sections.  */
 	      || i == elf_onesymtab (abfd)
 	      || i == elf_symtab_shndx (abfd)
 	      || i == elf_strtab_sec (abfd))
@@ -5518,8 +5555,8 @@ prep_headers (bfd *abfd)
 /* Assign file positions for all the reloc sections which are not part
    of the loadable file image, and the file position of section headers.  */
 
-static void
-_bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
+static bfd_boolean
+_bfd_elf_assign_file_positions_for_non_load (bfd *abfd)
 {
   file_ptr off;
   unsigned int i, num_sec;
@@ -5535,9 +5572,30 @@ _bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
       Elf_Internal_Shdr *shdrp;
 
       shdrp = *shdrpp;
-      if ((shdrp->sh_type == SHT_REL || shdrp->sh_type == SHT_RELA)
-	  && shdrp->sh_offset == -1)
-	off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE);
+      if (shdrp->sh_offset == -1)
+	{
+	  bfd_boolean is_rel = (shdrp->sh_type == SHT_REL
+				|| shdrp->sh_type == SHT_RELA);
+	  if (is_rel
+	      || (shdrp->bfd_section != NULL
+		  && (shdrp->bfd_section->flags & SEC_ELF_COMPRESS)))
+	    {
+	      if (!is_rel)
+		{
+		  /* Compress DWARF debug sections.  */
+		  if (!bfd_compress_section (abfd, shdrp->bfd_section,
+					     shdrp->contents))
+		    return FALSE;
+		  /* Update section size and contents.  */
+		  shdrp->sh_size = shdrp->bfd_section->size;
+		  shdrp->contents = shdrp->bfd_section->contents;
+		  shdrp->bfd_section->contents = NULL;
+		}
+	      off = _bfd_elf_assign_file_position_for_section (shdrp,
+							       off,
+							       TRUE);
+	    }
+	}
     }
 
 /* Place the section headers.  */
@@ -5547,6 +5605,8 @@ _bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
   i_ehdrp->e_shoff = off;
   off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
   elf_next_file_pos (abfd) = off;
+
+  return TRUE;
 }
 
 bfd_boolean
@@ -5569,7 +5629,8 @@ _bfd_elf_write_object_contents (bfd *abfd)
   if (failed)
     return FALSE;
 
-  _bfd_elf_assign_file_positions_for_relocs (abfd);
+  if (!_bfd_elf_assign_file_positions_for_non_load (abfd))
+    return FALSE;
 
   /* After writing the headers, we need to write the sections too...  */
   num_sec = elf_numsections (abfd);
@@ -7922,7 +7983,29 @@ _bfd_elf_set_section_contents (bfd *abfd,
       && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
     return FALSE;
 
+  if (!count)
+    return TRUE;
+
   hdr = &elf_section_data (section)->this_hdr;
+  if (hdr->sh_offset == (file_ptr) -1)
+    {
+      /* We must compress this section.  Write output to a buffer.  */
+      unsigned char *contents = hdr->contents;
+      if ((offset + count) > hdr->sh_size
+	  || (section->flags & SEC_ELF_COMPRESS) == 0)
+	abort ();
+      if (contents == NULL)
+	{
+	  /* Use bfd_malloc since it will be freed by
+	     bfd_compress_section_contents.  */
+	  contents = (unsigned char *) bfd_malloc (hdr->sh_size);
+	  if (contents == NULL)
+	    return FALSE;
+	  hdr->contents = contents;
+	}
+      memcpy (contents + offset, location, count);
+      return TRUE;
+    }
   pos = hdr->sh_offset + offset;
   if (bfd_seek (abfd, pos, SEEK_SET) != 0
       || bfd_bwrite (location, count, abfd) != count)
diff --git a/bfd/merge.c b/bfd/merge.c
index 5f45ba6..b77a346 100644
--- a/bfd/merge.c
+++ b/bfd/merge.c
@@ -25,6 +25,7 @@
 
 #include "sysdep.h"
 #include "bfd.h"
+#include "elf-bfd.h"
 #include "libbfd.h"
 #include "hashtab.h"
 #include "libiberty.h"
@@ -283,13 +284,15 @@ sec_merge_add (struct sec_merge_hash *tab, const char *str,
 }
 
 static bfd_boolean
-sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
+sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry,
+		file_ptr offset)
 {
   struct sec_merge_sec_info *secinfo = entry->secinfo;
   asection *sec = secinfo->sec;
   char *pad = NULL;
   bfd_size_type off = 0;
   int alignment_power = sec->output_section->alignment_power;
+  unsigned char *contents = NULL;
 
   if (alignment_power)
     {
@@ -298,6 +301,14 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
 	return FALSE;
     }
 
+  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+    {
+      Elf_Internal_Shdr *hdr
+	= &elf_section_data (sec->output_section)->this_hdr;
+      if (hdr->sh_offset == (file_ptr) -1)
+	contents = hdr->contents;
+    }
+
   for (; entry != NULL && entry->secinfo == secinfo; entry = entry->next)
     {
       const char *str;
@@ -306,7 +317,12 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
       len = -off & (entry->alignment - 1);
       if (len != 0)
 	{
-	  if (bfd_bwrite (pad, len, abfd) != len)
+	  if (contents)
+	    {
+	      memcpy (contents + offset, pad, len);
+	      offset += len;
+	    }
+	  else if (bfd_bwrite (pad, len, abfd) != len)
 	    goto err;
 	  off += len;
 	}
@@ -314,7 +330,12 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
       str = entry->root.string;
       len = entry->len;
 
-      if (bfd_bwrite (str, len, abfd) != len)
+      if (contents)
+	{
+	  memcpy (contents + offset, str, len);
+	  offset += len;
+	}
+      else if (bfd_bwrite (str, len, abfd) != len)
 	goto err;
 
       off += len;
@@ -322,9 +343,13 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
 
   /* Trailing alignment needed?  */
   off = sec->size - off;
-  if (off != 0
-      && bfd_bwrite (pad, off, abfd) != off)
-    goto err;
+  if (off != 0)
+    {
+      if (contents)
+	memcpy (contents + offset, pad, off);
+      else if (bfd_bwrite (pad, off, abfd) != off)
+	goto err;
+    }
 
   if (pad != NULL)
     free (pad);
@@ -785,6 +810,7 @@ _bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
 {
   struct sec_merge_sec_info *secinfo;
   file_ptr pos;
+  unsigned char *contents;
 
   secinfo = (struct sec_merge_sec_info *) psecinfo;
 
@@ -794,12 +820,42 @@ _bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
   if (secinfo->first_str == NULL)
     return TRUE;
 
+  contents = NULL;
+
   /* FIXME: octets_per_byte.  */
-  pos = sec->output_section->filepos + sec->output_offset;
-  if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
-    return FALSE;
+  if (bfd_get_flavour (output_bfd) == bfd_target_elf_flavour)
+    {
+      Elf_Internal_Shdr *hdr
+	= &elf_section_data (sec->output_section)->this_hdr;
+      if (hdr->sh_offset == (file_ptr) -1)
+	{
+	  if ((sec->output_section->flags & SEC_ELF_COMPRESS) == 0)
+	    abort ();
+
+	  /* Cache the section contents so that they can be compressed
+	     later.  */
+	  contents = hdr->contents;
+	  if (contents == NULL)
+	    {
+	      /* Use bfd_malloc since it will be freed by
+		 bfd_compress_section_contents.  */
+	      contents = (unsigned char *) bfd_malloc (hdr->sh_size);
+	      if (contents == NULL)
+		return FALSE;
+	      hdr->contents = contents;
+	    }
+	}
+    }
+
+  if (contents == NULL)
+    {
+      pos = sec->output_section->filepos + sec->output_offset;
+      if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
+	return FALSE;
+    }
 
-  if (! sec_merge_emit (output_bfd, secinfo->first_str))
+  if (! sec_merge_emit (output_bfd, secinfo->first_str,
+			sec->output_offset))
     return FALSE;
 
   return TRUE;
diff --git a/bfd/section.c b/bfd/section.c
index 4a6f2e4..d59a0e3 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -334,6 +334,10 @@ CODE_FRAGMENT
 .     executables or shared objects. This is for COFF only.  *}
 .#define SEC_COFF_SHARED 0x8000000
 .
+.  {* This section should be compressed.  This is for ELF linker
+.     internal use only.  *}
+.#define SEC_ELF_COMPRESS 0x8000000
+.
 .  {* When a section with this flag is being linked, then if the size of
 .     the input section is less than a page, it should not cross a page
 .     boundary.  If the size of the input section is one page or more,
diff --git a/gas/as.h b/gas/as.h
index e04cc0f..6de319e 100644
--- a/gas/as.h
+++ b/gas/as.h
@@ -370,16 +370,6 @@ COMMON int flag_strip_local_absolute;
 /* True if we should generate a traditional format object file.  */
 COMMON int flag_traditional_format;
 
-/* Types of compressed debug sections.  We currently support zlib.  */
-enum compressed_debug_section_type
-{
-  COMPRESS_DEBUG_NONE = 0,
-  COMPRESS_DEBUG,
-  COMPRESS_DEBUG_ZLIB,
-  COMPRESS_DEBUG_GNU_ZLIB,
-  COMPRESS_DEBUG_GABI_ZLIB
-};
-
 /* Type of compressed debug sections we should generate.   */
 COMMON enum compressed_debug_section_type flag_compress_debug;
 
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 6a02a3c..012569b 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -431,6 +431,9 @@ struct bfd_link_info
   /* Separator between archive and filename in linker script filespecs.  */
   char path_separator;
 
+  /* Compress DWARF debug sections.  */
+  enum compressed_debug_section_type compress_debug;
+
   /* Default stack size.  Zero means default (often zero itself), -1
      means explicitly zero-sized.  */
   bfd_signed_vma stacksize;
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 5db5a93..0802d76 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -2110,6 +2110,7 @@ fragment <<EOF
 #define OPTION_HASH_STYLE		(OPTION_EXCLUDE_LIBS + 1)
 #define OPTION_BUILD_ID			(OPTION_HASH_STYLE + 1)
 #define OPTION_AUDIT			(OPTION_BUILD_ID + 1)
+#define OPTION_COMPRESS_DEBUG		(OPTION_AUDIT + 1)
 
 static void
 gld${EMULATION_NAME}_add_options
@@ -2137,6 +2138,7 @@ EOF
 fi
 fragment <<EOF
     {"build-id", optional_argument, NULL, OPTION_BUILD_ID},
+    {"compress-debug-sections", required_argument, NULL, OPTION_COMPRESS_DEBUG},
 EOF
 if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
 fragment <<EOF
@@ -2186,6 +2188,19 @@ gld${EMULATION_NAME}_handle_option (int optc)
 	emit_note_gnu_build_id = xstrdup (optarg);
       break;
 
+    case OPTION_COMPRESS_DEBUG:
+      if (strcasecmp (optarg, "none") == 0)
+	link_info.compress_debug = COMPRESS_DEBUG_NONE;
+      else if (strcasecmp (optarg, "zlib") == 0)
+	link_info.compress_debug = COMPRESS_DEBUG_ZLIB;
+      else if (strcasecmp (optarg, "zlib-gnu") == 0)
+	link_info.compress_debug = COMPRESS_DEBUG_GNU_ZLIB;
+      else if (strcasecmp (optarg, "zlib-gabi") == 0)
+	link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
+      else
+	einfo (_("%P%F: invalid --compress-debug-sections option: \`%s'\n"),
+	       optarg);
+      break;
 EOF
 
 if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 5384c98..462ec34 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -2193,6 +2193,22 @@ new style GNU @code{.gnu.hash} section or @code{both} for both
 the classic ELF @code{.hash} and new style GNU @code{.gnu.hash}
 hash tables.  The default is @code{sysv}.
 
+@kindex --compress-debug-sections=none
+@kindex --compress-debug-sections=zlib
+@kindex --compress-debug-sections=zlib-gnu
+@kindex --compress-debug-sections=zlib-gabi
+@item --compress-debug-sections=none
+@itemx --compress-debug-sections=zlib
+@itemx --compress-debug-sections=zlib-gnu
+@itemx --compress-debug-sections=zlib-gabi
+On ELF platforms , these options control how DWARF debug sections are
+compressed using zlib.  @option{--compress-debug-sections=none} doesn't
+compress DWARF debug sections.  @option{--compress-debug-sections=zlib}
+and @option{--compress-debug-sections=zlib-gnu} compress DWARF debug
+sections and rename debug section names to begin with @samp{.zdebug}
+instead of @samp{.debug}.  @option{--compress-debug-sections=zlib-gabi}
+compresses DWARF debug sections with SHF_COMPRESSED from the ELF ABI.
+
 @kindex --reduce-memory-overheads
 @item --reduce-memory-overheads
 This option reduces memory requirements at ld runtime, at the expense of
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 6674a80..224ba53 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -424,6 +424,13 @@ main (int argc, char **argv)
   else
     link_info.output_bfd->flags |= EXEC_P;
 
+  if ((link_info.compress_debug & COMPRESS_DEBUG))
+    {
+      link_info.output_bfd->flags |= BFD_COMPRESS;
+      if (link_info.compress_debug == COMPRESS_DEBUG_GABI_ZLIB)
+	link_info.output_bfd->flags |= BFD_COMPRESS_GABI;
+    }
+
   ldwrite ();
 
   if (config.map_file != NULL)
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 4a71ba4..b618241 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -1722,6 +1722,9 @@ elf_static_list_options (FILE *file)
   fprintf (file, _("\
   --build-id[=STYLE]          Generate build ID note\n"));
   fprintf (file, _("\
+  --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi]\n\
+                              Compress DWARF debug sections using zlib\n"));
+  fprintf (file, _("\
   -z common-page-size=SIZE    Set common page size to SIZE\n"));
   fprintf (file, _("\
   -z max-page-size=SIZE       Set maximum page size to SIZE\n"));
diff --git a/ld/testsuite/ld-elf/compress.exp b/ld/testsuite/ld-elf/compress.exp
index adb7fc2..e2448b9 100644
--- a/ld/testsuite/ld-elf/compress.exp
+++ b/ld/testsuite/ld-elf/compress.exp
@@ -49,7 +49,8 @@ set build_tests {
    "-shared" "-fPIC -g -Wa,--compress-debug-sections"
    {foo.c} {} "libfoo.so"}
   {"Build libbar.so with compressed debug sections"
-   "-shared" "-fPIC -g -Wa,--compress-debug-sections"
+   "-shared -Wl,--compress-debug-sections=none"
+   "-fPIC -g -Wa,--compress-debug-sections"
    {begin.c end.c} {} "libbar.so"}
   {"Build libfoozlib.so with compressed debug sections with zlib-gabi"
    "-shared" "-fPIC -g -Wa,--compress-debug-sections=zlib-gabi"
@@ -57,6 +58,30 @@ set build_tests {
   {"Build libbarzlib.so with compressed debug sections with zlib-gabi"
    "-shared" "-fPIC -g -Wa,--compress-debug-sections=zlib-gabi"
    {begin.c end.c} {} "libbarzlib.so"}
+  {"Build libzlibfoo.so with zlib compressed debug sections"
+   "-shared -Wl,--compress-debug-sections=zlib"
+   "-fPIC -g -Wa,--compress-debug-sections=zlib"
+   {foo.c} {} "libzlibfoo.so"}
+  {"Build libgnufoo.so with zlib-gnu compressed debug sections"
+   "-shared -Wl,--compress-debug-sections=zlib-gnu"
+   "-fPIC -g -Wa,--compress-debug-sections=zlib-gnu"
+   {foo.c} {} "libgnufoo.so"}
+  {"Build libgabifoo.so with zlib-gabi compressed debug sections"
+   "-shared -Wl,--compress-debug-sections=zlib-gabi"
+   "-fPIC -g -Wa,--compress-debug-sections=zlib-gabi"
+   {foo.c} {} "libgabifoo.so"}
+  {"Build zlibbegin.o with zlib compressed debug sections"
+   "-r -nostdlib -Wl,--compress-debug-sections=zlib"
+   "-g -Wa,--compress-debug-sections=zlib"
+   {begin.c} {} "zlibbegin.o"}
+  {"Build gnubegin.o with zlib-gnu compressed debug sections"
+   "-r -nostdlib -Wl,--compress-debug-sections=zlib-gnu"
+   "-g -Wa,--compress-debug-sections=zlib-gnu"
+   {begin.c} {} "gnubegin.o"}
+  {"Build gabiend.o with zlib-gabi compressed debug sections"
+   "-r -nostdlib -Wl,--compress-debug-sections=zlib-gabi"
+   "-g -Wa,--compress-debug-sections=zlib-gnu"
+   {end.c} {} "gabiend.o"}
 }
 
 set run_tests {
@@ -66,6 +91,15 @@ set run_tests {
     {"Run normal with libfoo.so with compressed debug sections with zlib-gabi"
      "tmpdir/begin.o tmpdir/libfoozlib.so tmpdir/end.o" ""
      {main.c} "normal" "normal.out" "-Wa,--compress-debug-sections=zlib-gabi"}
+    {"Run zlibnormal with libzlibfoo.so with zlib compressed debug sections"
+     "tmpdir/begin.o tmpdir/libzlibfoo.so tmpdir/end.o --compress-debug-sections=zlib" ""
+     {main.c} "zlibnormal" "normal.out" "-Wa,--compress-debug-sections=zlib"}
+    {"Run gnunormal with libgnufoo.so with zlib-gnu compressed debug sections"
+     "tmpdir/gnubegin.o tmpdir/libgnufoo.so tmpdir/end.o --compress-debug-sections=zlib-gnu" ""
+     {main.c} "gnunormal" "normal.out" "-Wa,--compress-debug-sections=zlib-gnu"}
+    {"Run gabinormal with libgabifoo.so with zlib-gabi compressed debug sections"
+     "tmpdir/zlibbegin.o tmpdir/libgabifoo.so tmpdir/gabiend.o --compress-debug-sections=zlib-gabi" ""
+     {main.c} "gabinormal" "normal.out" "-Wa,--compress-debug-sections=zlib-gabi"}
 }
 
 run_cc_link_tests $build_tests
@@ -79,3 +113,134 @@ if { [catch {exec cmp tmpdir/libfoo.so tmpdir/libfoozlib.so}] } then {
 } else {
     pass "$test_name"
 }
+
+global READELF
+
+set test_name "Link -r with zlib compressed debug output"
+set test zlibbegin
+send_log "$READELF -S -W tmpdir/$test.o > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -S -W tmpdir/$test.o" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rS] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+
+set test_name "Link -r with zlib-gnu compressed debug output"
+set test gnubegin
+send_log "$READELF -S -W tmpdir/$test.o > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -S -W tmpdir/$test.o" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rS] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+
+set test_name "Link -r with zlib-gabi compressed debug output"
+set test gabiend
+send_log "$READELF -t -W tmpdir/$test.o > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -t -W tmpdir/$test.o" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rt] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+
+set test_name "Link with zlib compressed debug output"
+set test normal
+send_log "$READELF -w tmpdir/$test > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -w tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+
+set test_name "Link with zlib compressed debug output"
+set test zlibnormal
+send_log "$READELF -w tmpdir/$test | sed -e \"s/.zdebug_/.debug_/\" > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -w tmpdir/$test | sed -e \"s/.zdebug_/.debug_/\"" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [catch {exec cmp tmpdir/normal.out tmpdir/$test.out}] } then {
+    send_log "tmpdir/normal.out tmpdir/$test.out differ.\n"
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+send_log "$READELF -S -W tmpdir/$test' > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -S -W tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rS] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+
+set test_name "Link with zlib-gnu compressed debug output"
+set test gnunormal
+send_log "$READELF -w tmpdir/$test | sed -e \"s/.zdebug_/.debug_/\" > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -w tmpdir/$test | sed -e \"s/.zdebug_/.debug_/\"" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [catch {exec cmp tmpdir/normal.out tmpdir/$test.out}] } then {
+    send_log "tmpdir/normal.out tmpdir/$test.out differ.\n"
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+send_log "$READELF -S -W tmpdir/$test' > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -S -W tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rS] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+
+set test gabinormal
+set test_name "Link with zlib-gabi compressed debug output"
+send_log "$READELF -w tmpdir/$test > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -w tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [catch {exec cmp tmpdir/normal.out tmpdir/$test.out}] } then {
+    send_log "tmpdir/normal.out tmpdir/$test.out differ.\n"
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+send_log "$READELF -t -W tmpdir/$test > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -t -W tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rt] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
diff --git a/ld/testsuite/ld-elf/gabiend.rt b/ld/testsuite/ld-elf/gabiend.rt
new file mode 100644
index 0000000..23bc36c
--- /dev/null
+++ b/ld/testsuite/ld-elf/gabiend.rt
@@ -0,0 +1,4 @@
+#...
+ +\[[0-9a-f]+\]: .*COMPRESSED
+ +ZLIB, [0-9a-f]+, 1
+#pass
diff --git a/ld/testsuite/ld-elf/gabinormal.rt b/ld/testsuite/ld-elf/gabinormal.rt
new file mode 100644
index 0000000..23bc36c
--- /dev/null
+++ b/ld/testsuite/ld-elf/gabinormal.rt
@@ -0,0 +1,4 @@
+#...
+ +\[[0-9a-f]+\]: .*COMPRESSED
+ +ZLIB, [0-9a-f]+, 1
+#pass
diff --git a/ld/testsuite/ld-elf/gnubegin.rS b/ld/testsuite/ld-elf/gnubegin.rS
new file mode 100644
index 0000000..54de24c
--- /dev/null
+++ b/ld/testsuite/ld-elf/gnubegin.rS
@@ -0,0 +1,3 @@
+#...
+ +\[[ 0-9]+\] .zdebug_.* +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +0 +0 +1
+#pass
diff --git a/ld/testsuite/ld-elf/gnunormal.rS b/ld/testsuite/ld-elf/gnunormal.rS
new file mode 100644
index 0000000..54de24c
--- /dev/null
+++ b/ld/testsuite/ld-elf/gnunormal.rS
@@ -0,0 +1,3 @@
+#...
+ +\[[ 0-9]+\] .zdebug_.* +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +0 +0 +1
+#pass
diff --git a/ld/testsuite/ld-elf/zlibbegin.rS b/ld/testsuite/ld-elf/zlibbegin.rS
new file mode 100644
index 0000000..54de24c
--- /dev/null
+++ b/ld/testsuite/ld-elf/zlibbegin.rS
@@ -0,0 +1,3 @@
+#...
+ +\[[ 0-9]+\] .zdebug_.* +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +0 +0 +1
+#pass
diff --git a/ld/testsuite/ld-elf/zlibnormal.rS b/ld/testsuite/ld-elf/zlibnormal.rS
new file mode 100644
index 0000000..54de24c
--- /dev/null
+++ b/ld/testsuite/ld-elf/zlibnormal.rS
@@ -0,0 +1,3 @@
+#...
+ +\[[ 0-9]+\] .zdebug_.* +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +0 +0 +1
+#pass
-- 
2.1.0


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-13 12:38 PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld H.J. Lu
@ 2015-04-15  0:55 ` Alan Modra
  2015-04-15  2:44   ` H.J. Lu
  0 siblings, 1 reply; 23+ messages in thread
From: Alan Modra @ 2015-04-15  0:55 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

On Mon, Apr 13, 2015 at 05:38:24AM -0700, H.J. Lu wrote:
> On Sun, Apr 12, 2015 at 6:13 PM, Alan Modra <amodra@gmail.com> wrote:
> > On Thu, Apr 09, 2015 at 03:07:20PM -0700, H.J. Lu wrote:
> >> +  if (arg->link_info
> >> +      && (arg->link_info->compress_debug & COMPRESS_DEBUG)
> >> +      && arg->link_info->compress_debug != COMPRESS_DEBUG_GABI_ZLIB
> >> +      && (asect->flags & SEC_DEBUGGING)
> >> +      && name[1] == 'd'
> >> +      && name[6] == '_')
> >
> > Here and in a couple of other places you omit checking the full prefix
> > of the name.  Are you certain you won't see something like a ".de"
> > section here?  It you might, then name[6] is a buffer overflow and a
> > potential segfault.
> 
> elf.c has
> 
>   if ((flags & SEC_ALLOC) == 0)
>     {
>       /* The debugging sections appear to be recognized only by name,
>          not any sort of flag.  Their SEC_ALLOC bits are cleared.  */

OK, good.

> Here is the completed patch.  OK for master?

Would you mind looking at doing this a little cleaner?  The patch as
it stands looks very much like a bolt-on.  I mean, you probably
wouldn't write the code this way if elflink.c had compression in mind
in the beginning..

So, I'm wondering whether things would look better if
elf_link_input_bfd allocated the extra buffer needed rather than in
both _bfd_write_merged_section and _bfd_elf_set_section_contents.
Of course, _bfd_write_merged_section would need two extra parameters,
contents and offset, and write to "contents" if non-NULL rather than
to the output file.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-15  0:55 ` Alan Modra
@ 2015-04-15  2:44   ` H.J. Lu
  2015-04-15  3:58     ` Alan Modra
  0 siblings, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2015-04-15  2:44 UTC (permalink / raw)
  To: Binutils

[-- Attachment #1: Type: text/plain, Size: 1856 bytes --]

On Tue, Apr 14, 2015 at 5:55 PM, Alan Modra <amodra@gmail.com> wrote:
> On Mon, Apr 13, 2015 at 05:38:24AM -0700, H.J. Lu wrote:
>> On Sun, Apr 12, 2015 at 6:13 PM, Alan Modra <amodra@gmail.com> wrote:
>> > On Thu, Apr 09, 2015 at 03:07:20PM -0700, H.J. Lu wrote:
>> >> +  if (arg->link_info
>> >> +      && (arg->link_info->compress_debug & COMPRESS_DEBUG)
>> >> +      && arg->link_info->compress_debug != COMPRESS_DEBUG_GABI_ZLIB
>> >> +      && (asect->flags & SEC_DEBUGGING)
>> >> +      && name[1] == 'd'
>> >> +      && name[6] == '_')
>> >
>> > Here and in a couple of other places you omit checking the full prefix
>> > of the name.  Are you certain you won't see something like a ".de"
>> > section here?  It you might, then name[6] is a buffer overflow and a
>> > potential segfault.
>>
>> elf.c has
>>
>>   if ((flags & SEC_ALLOC) == 0)
>>     {
>>       /* The debugging sections appear to be recognized only by name,
>>          not any sort of flag.  Their SEC_ALLOC bits are cleared.  */
>
> OK, good.
>
>> Here is the completed patch.  OK for master?
>
> Would you mind looking at doing this a little cleaner?  The patch as
> it stands looks very much like a bolt-on.  I mean, you probably
> wouldn't write the code this way if elflink.c had compression in mind
> in the beginning..
>
> So, I'm wondering whether things would look better if
> elf_link_input_bfd allocated the extra buffer needed rather than in
> both _bfd_write_merged_section and _bfd_elf_set_section_contents.
> Of course, _bfd_write_merged_section would need two extra parameters,
> contents and offset, and write to "contents" if non-NULL rather than
> to the output file.

Thanks for the suggestion.  I allocated the buffer in bfd_elf_final_link
instead without adding extra arguments to _bfd_write_merged_section.
Here is the updated patch. OK for master?

-- 
H.J.

[-- Attachment #2: 0001-Add-compress-debug-sections-none-zlib-zlib-gnu-zlib-.patch --]
[-- Type: text/x-patch, Size: 34301 bytes --]

From 8b16cbf8193c9bf26cd3c03d17a3f9afb7971879 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 13 Apr 2015 05:30:52 -0700
Subject: [PATCH] Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi]

This patch adds --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi]
to ld for ELF targets to support generating compressed DWARF debug
sections.  We always generate .zdebug_* section since section names have
been finalized and they can't be changed easily when compression is
being performed.

bfd/

	* bfd-in.h (compressed_debug_section_type): New.
	* compress.c (bfd_compress_section_contents): Add an argument
	for linker write compression and always generate .zdebug_*
	section when linking.
	(bfd_init_section_compress_status): Pass FALSE to
	bfd_compress_section_contents.
	(bfd_compress_section): New function.
	* elf.c (elf_fake_sections): For linking, set SEC_ELF_COMPRESS
	on DWARF debug sections if COMPRESS_DEBUG is set and rename
	section if COMPRESS_DEBUG_GABI_ZLIB isn't set.
	(assign_file_positions_for_non_load_sections): Set sh_offset
	to -1 if SEC_ELF_COMPRESS is set.
	(assign_file_positions_except_relocs): Likwise.
	(_bfd_elf_assign_file_positions_for_relocs): Renamed to ...
	(_bfd_elf_assign_file_positions_for_non_load): This.  Change
	return time to bfd_boolean.  Compress the section if
	SEC_ELF_COMPRESS is set.
	(_bfd_elf_write_object_contents): Updated.
	(_bfd_elf_set_section_contents): Write section contents to
	the buffer if SEC_ELF_COMPRESS is set.
	* merge.c: Include "elf-bfd.h".
	(sec_merge_emit): Add an argument for offset.  For ELF, write
	to contents if sh_offset is -1.
	(_bfd_write_merged_section): Write section contents to the
	buffer if SEC_ELF_COMPRESS is set.  Pass output_offset to
	sec_merge_emit.
	* elflink.c (bfd_elf_final_link): Allocate the buffer for
	output section contents if SEC_ELF_COMPRESS is set.
	* section.c (SEC_ELF_COMPRESS): New.
	* bfd-in2.h: Regenerated.

gas/

	* as.h (compressed_debug_section_type): Removed.

include/

	* bfdlink.h (bfd_link_info): Add compress_debug.

ld/

	* ld.texinfo: Document --compress-debug-sections=.
	* ldmain.c (main): Set BFD_COMPRESS on output_bfd if
	COMPRESS_DEBUG is set.  Set BFD_COMPRESS_GABI on output_bfd
	for COMPRESS_DEBUG_GABI_ZLIB.
	* lexsup.c (elf_static_list_options): Add
	--compress-debug-sections=.
	* emultempl/elf32.em (OPTION_COMPRESS_DEBUG): New.
	(xtra_long): Add "compress-debug-sections".
	(gld${EMULATION_NAME}_handle_option): Handle
	OPTION_COMPRESS_DEBUG.

ld/testsuite/

	* ld-elf/compress.exp (build_tests): Add tests for
	--compress-debug-sections=.
	(run_tests): Likewise.
	Add additonal tests for --compress-debug-sections=.
	* ld-elf/gabiend.rt: New file.
	* ld-elf/gabinormal.rt: Likewise.
	* ld-elf/gnubegin.rS: Likewise.
	* ld-elf/gnunormal.rS: Likewise.
	* ld-elf/zlibbegin.rS: Likewise.
	* ld-elf/zlibnormal.rS: Likewise.
---
 bfd/bfd-in.h                      |  11 +++
 bfd/bfd-in2.h                     |  18 ++++
 bfd/compress.c                    |  51 +++++++++++-
 bfd/elf.c                         |  89 ++++++++++++++++++--
 bfd/elflink.c                     |  15 ++++
 bfd/merge.c                       |  67 ++++++++++++---
 bfd/section.c                     |   4 +
 gas/as.h                          |  10 ---
 include/bfdlink.h                 |   3 +
 ld/emultempl/elf32.em             |  15 ++++
 ld/ld.texinfo                     |  16 ++++
 ld/ldmain.c                       |   7 ++
 ld/lexsup.c                       |   3 +
 ld/testsuite/ld-elf/compress.exp  | 167 +++++++++++++++++++++++++++++++++++++-
 ld/testsuite/ld-elf/gabiend.rt    |   4 +
 ld/testsuite/ld-elf/gabinormal.rt |   4 +
 ld/testsuite/ld-elf/gnubegin.rS   |   3 +
 ld/testsuite/ld-elf/gnunormal.rS  |   3 +
 ld/testsuite/ld-elf/zlibbegin.rS  |   3 +
 ld/testsuite/ld-elf/zlibnormal.rS |   3 +
 20 files changed, 464 insertions(+), 32 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/gabiend.rt
 create mode 100644 ld/testsuite/ld-elf/gabinormal.rt
 create mode 100644 ld/testsuite/ld-elf/gnubegin.rS
 create mode 100644 ld/testsuite/ld-elf/gnunormal.rS
 create mode 100644 ld/testsuite/ld-elf/zlibbegin.rS
 create mode 100644 ld/testsuite/ld-elf/zlibnormal.rS

diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index 1f8a72c..2e324cd 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -437,6 +437,17 @@ extern void bfd_hash_traverse
    this size.  */
 extern unsigned long bfd_hash_set_default_size (unsigned long);
 
+/* Types of compressed DWARF debug sections.  We currently support
+   zlib.  */
+enum compressed_debug_section_type
+{
+  COMPRESS_DEBUG_NONE = 0,
+  COMPRESS_DEBUG = 1 << 0,
+  COMPRESS_DEBUG_ZLIB = COMPRESS_DEBUG | 1 << 1,
+  COMPRESS_DEBUG_GNU_ZLIB = COMPRESS_DEBUG | 1 << 2,
+  COMPRESS_DEBUG_GABI_ZLIB = COMPRESS_DEBUG | 1 << 3
+};
+
 /* This structure is used to keep track of stabs in sections
    information while linking.  */
 
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 679595e..122caa0 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -444,6 +444,17 @@ extern void bfd_hash_traverse
    this size.  */
 extern unsigned long bfd_hash_set_default_size (unsigned long);
 
+/* Types of compressed DWARF debug sections.  We currently support
+   zlib.  */
+enum compressed_debug_section_type
+{
+  COMPRESS_DEBUG_NONE = 0,
+  COMPRESS_DEBUG = 1 << 0,
+  COMPRESS_DEBUG_ZLIB = COMPRESS_DEBUG | 1 << 1,
+  COMPRESS_DEBUG_GNU_ZLIB = COMPRESS_DEBUG | 1 << 2,
+  COMPRESS_DEBUG_GABI_ZLIB = COMPRESS_DEBUG | 1 << 3
+};
+
 /* This structure is used to keep track of stabs in sections
    information while linking.  */
 
@@ -1378,6 +1389,10 @@ typedef struct bfd_section
      executables or shared objects. This is for COFF only.  */
 #define SEC_COFF_SHARED 0x8000000
 
+  /* This section should be compressed.  This is for ELF linker
+     internal use only.  */
+#define SEC_ELF_COMPRESS 0x8000000
+
   /* When a section with this flag is being linked, then if the size of
      the input section is less than a page, it should not cross a page
      boundary.  If the size of the input section is one page or more,
@@ -7316,6 +7331,9 @@ bfd_boolean bfd_init_section_decompress_status
 bfd_boolean bfd_init_section_compress_status
    (bfd *abfd, asection *section);
 
+bfd_boolean bfd_compress_section
+   (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/bfd/compress.c b/bfd/compress.c
index 770ea57..dfde50e 100644
--- a/bfd/compress.c
+++ b/bfd/compress.c
@@ -72,7 +72,8 @@ decompress_contents (bfd_byte *compressed_buffer,
 static bfd_size_type
 bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
 			       bfd_byte *uncompressed_buffer,
-			       bfd_size_type uncompressed_size)
+			       bfd_size_type uncompressed_size,
+			       bfd_boolean write_compress)
 {
   uLong compressed_size;
   bfd_byte *buffer;
@@ -176,8 +177,11 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
 
       compressed_size += header_size;
       /* PR binutils/18087: If compression didn't make the section smaller,
-	 just keep it uncompressed.  */
-      if (compressed_size < uncompressed_size)
+	 just keep it uncompressed.  We always generate .zdebug_* section
+	 when linking since section names have been finalized and they
+	 can't be changed easily.  */
+      if ((write_compress && compression_header_size == 0)
+	   || compressed_size < uncompressed_size)
 	{
 	  bfd_update_compression_header (abfd, buffer, sec);
 
@@ -543,9 +547,48 @@ bfd_init_section_compress_status (bfd *abfd, sec_ptr sec)
     {
       uncompressed_size = bfd_compress_section_contents (abfd, sec,
 							 uncompressed_buffer,
-							 uncompressed_size);
+							 uncompressed_size,
+							 FALSE);
       ret = uncompressed_size != 0;
     }
 
   return ret;
 }
+
+/*
+FUNCTION
+	bfd_compress_section
+
+SYNOPSIS
+	bfd_boolean bfd_compress_section
+	  (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer);
+
+DESCRIPTION
+	If open for write, compress section, update section size with
+	compressed size and set compress_status to COMPRESS_SECTION_DONE.
+
+	Return @code{FALSE} if compression fail.  Otherwise, return
+	@code{TRUE}.
+*/
+
+bfd_boolean
+bfd_compress_section (bfd *abfd, sec_ptr sec, bfd_byte *uncompressed_buffer)
+{
+  bfd_size_type uncompressed_size = sec->size;
+
+  /* Error if not opened for write.  */
+  if (abfd->direction != write_direction
+      || uncompressed_size == 0
+      || uncompressed_buffer == NULL
+      || sec->contents != NULL
+      || sec->compressed_size != 0
+      || sec->compress_status != COMPRESS_SECTION_NONE)
+    {
+      bfd_set_error (bfd_error_invalid_operation);
+      return FALSE;
+    }
+
+  /* Compress it.  */
+  return bfd_compress_section_contents (abfd, sec, uncompressed_buffer,
+					uncompressed_size, TRUE) != 0;
+}
diff --git a/bfd/elf.c b/bfd/elf.c
index 41fb023..85a4b6b 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -2752,6 +2752,7 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
   struct bfd_elf_section_data *esd = elf_section_data (asect);
   Elf_Internal_Shdr *this_hdr;
   unsigned int sh_type;
+  const char *name = asect->name;
 
   if (arg->failed)
     {
@@ -2762,8 +2763,38 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
 
   this_hdr = &esd->this_hdr;
 
+  /* For linking, compress DWARF debug sections with names: .debug_*.  */
+  if (arg->link_info
+      && (arg->link_info->compress_debug & COMPRESS_DEBUG)
+      && (asect->flags & SEC_DEBUGGING)
+      && name[1] == 'd'
+      && name[6] == '_')
+    {
+      /* Set SEC_ELF_COMPRESS to indicate this section should be
+	 compressed.  */
+      asect->flags |= SEC_ELF_COMPRESS;
+
+      if (arg->link_info->compress_debug != COMPRESS_DEBUG_GABI_ZLIB)
+	{
+	  /* If SHF_COMPRESSED isn't used, rename compressed DWARF
+	     debug section to .zdebug_*.  */
+	  unsigned int len = strlen (name);
+	  char *new_name = bfd_alloc (abfd, len + 2);
+	  if (new_name == NULL)
+	    {
+	      arg->failed = TRUE;
+	      return;
+	    }
+	  new_name[0] = '.';
+	  new_name[1] = 'z';
+	  memcpy (new_name + 2, name + 1, len);
+	  bfd_rename_section (abfd, asect, new_name);
+	  name = asect->name;
+	}
+    }
+
   this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
-							  asect->name, FALSE);
+							  name, FALSE);
   if (this_hdr->sh_name == (unsigned int) -1)
     {
       arg->failed = TRUE;
@@ -5116,6 +5147,9 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
 	}
       else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
 		&& hdr->bfd_section == NULL)
+	       || (hdr->bfd_section != NULL
+		   && (hdr->bfd_section->flags & SEC_ELF_COMPRESS))
+		   /* Compress DWARF debug sections.  */
 	       || hdr == i_shdrpp[elf_onesymtab (abfd)]
 	       || hdr == i_shdrpp[elf_symtab_shndx (abfd)]
 	       || hdr == i_shdrpp[elf_strtab_sec (abfd)])
@@ -5365,6 +5399,9 @@ assign_file_positions_except_relocs (bfd *abfd,
 	  hdr = *hdrpp;
 	  if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
 	       && hdr->bfd_section == NULL)
+	      || (hdr->bfd_section != NULL
+		  && (hdr->bfd_section->flags & SEC_ELF_COMPRESS))
+		  /* Compress DWARF debug sections.  */
 	      || i == elf_onesymtab (abfd)
 	      || i == elf_symtab_shndx (abfd)
 	      || i == elf_strtab_sec (abfd))
@@ -5518,8 +5555,8 @@ prep_headers (bfd *abfd)
 /* Assign file positions for all the reloc sections which are not part
    of the loadable file image, and the file position of section headers.  */
 
-static void
-_bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
+static bfd_boolean
+_bfd_elf_assign_file_positions_for_non_load (bfd *abfd)
 {
   file_ptr off;
   unsigned int i, num_sec;
@@ -5535,9 +5572,30 @@ _bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
       Elf_Internal_Shdr *shdrp;
 
       shdrp = *shdrpp;
-      if ((shdrp->sh_type == SHT_REL || shdrp->sh_type == SHT_RELA)
-	  && shdrp->sh_offset == -1)
-	off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE);
+      if (shdrp->sh_offset == -1)
+	{
+	  bfd_boolean is_rel = (shdrp->sh_type == SHT_REL
+				|| shdrp->sh_type == SHT_RELA);
+	  if (is_rel
+	      || (shdrp->bfd_section != NULL
+		  && (shdrp->bfd_section->flags & SEC_ELF_COMPRESS)))
+	    {
+	      if (!is_rel)
+		{
+		  /* Compress DWARF debug sections.  */
+		  if (!bfd_compress_section (abfd, shdrp->bfd_section,
+					     shdrp->contents))
+		    return FALSE;
+		  /* Update section size and contents.  */
+		  shdrp->sh_size = shdrp->bfd_section->size;
+		  shdrp->contents = shdrp->bfd_section->contents;
+		  shdrp->bfd_section->contents = NULL;
+		}
+	      off = _bfd_elf_assign_file_position_for_section (shdrp,
+							       off,
+							       TRUE);
+	    }
+	}
     }
 
 /* Place the section headers.  */
@@ -5547,6 +5605,8 @@ _bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
   i_ehdrp->e_shoff = off;
   off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
   elf_next_file_pos (abfd) = off;
+
+  return TRUE;
 }
 
 bfd_boolean
@@ -5569,7 +5629,8 @@ _bfd_elf_write_object_contents (bfd *abfd)
   if (failed)
     return FALSE;
 
-  _bfd_elf_assign_file_positions_for_relocs (abfd);
+  if (!_bfd_elf_assign_file_positions_for_non_load (abfd))
+    return FALSE;
 
   /* After writing the headers, we need to write the sections too...  */
   num_sec = elf_numsections (abfd);
@@ -7922,7 +7983,21 @@ _bfd_elf_set_section_contents (bfd *abfd,
       && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
     return FALSE;
 
+  if (!count)
+    return TRUE;
+
   hdr = &elf_section_data (section)->this_hdr;
+  if (hdr->sh_offset == (file_ptr) -1)
+    {
+      /* We must compress this section.  Write output to the buffer.  */
+      unsigned char *contents = hdr->contents;
+      if ((offset + count) > hdr->sh_size
+	  || (section->flags & SEC_ELF_COMPRESS) == 0
+	  || contents == NULL)
+	abort ();
+      memcpy (contents + offset, location, count);
+      return TRUE;
+    }
   pos = hdr->sh_offset + offset;
   if (bfd_seek (abfd, pos, SEEK_SET) != 0
       || bfd_bwrite (location, count, abfd) != count)
diff --git a/bfd/elflink.c b/bfd/elflink.c
index ea9246b..6efe1e4 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -10890,6 +10890,21 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 	 to count upwards while actually outputting the relocations.  */
       esdo->rel.count = 0;
       esdo->rela.count = 0;
+
+      if (esdo->this_hdr.sh_offset == (file_ptr) -1)
+	{
+	  /* Cache the section contents so that they can be compressed
+	     later.  Use bfd_malloc since it will be freed by
+	     bfd_compress_section_contents.  */
+	  unsigned char *contents = esdo->this_hdr.contents;
+	  if ((o->flags & SEC_ELF_COMPRESS) == 0 || contents != NULL)
+	    abort ();
+	  contents
+	    = (unsigned char *) bfd_malloc (esdo->this_hdr.sh_size);
+	  if (contents == NULL)
+	    goto error_return;
+	  esdo->this_hdr.contents = contents;
+	}
     }
 
   /* We have now assigned file positions for all the sections except
diff --git a/bfd/merge.c b/bfd/merge.c
index 5f45ba6..ff85833 100644
--- a/bfd/merge.c
+++ b/bfd/merge.c
@@ -25,6 +25,7 @@
 
 #include "sysdep.h"
 #include "bfd.h"
+#include "elf-bfd.h"
 #include "libbfd.h"
 #include "hashtab.h"
 #include "libiberty.h"
@@ -283,13 +284,15 @@ sec_merge_add (struct sec_merge_hash *tab, const char *str,
 }
 
 static bfd_boolean
-sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
+sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry,
+		file_ptr offset)
 {
   struct sec_merge_sec_info *secinfo = entry->secinfo;
   asection *sec = secinfo->sec;
   char *pad = NULL;
   bfd_size_type off = 0;
   int alignment_power = sec->output_section->alignment_power;
+  unsigned char *contents = NULL;
 
   if (alignment_power)
     {
@@ -298,6 +301,14 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
 	return FALSE;
     }
 
+  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
+    {
+      Elf_Internal_Shdr *hdr
+	= &elf_section_data (sec->output_section)->this_hdr;
+      if (hdr->sh_offset == (file_ptr) -1)
+	contents = hdr->contents;
+    }
+
   for (; entry != NULL && entry->secinfo == secinfo; entry = entry->next)
     {
       const char *str;
@@ -306,7 +317,12 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
       len = -off & (entry->alignment - 1);
       if (len != 0)
 	{
-	  if (bfd_bwrite (pad, len, abfd) != len)
+	  if (contents)
+	    {
+	      memcpy (contents + offset, pad, len);
+	      offset += len;
+	    }
+	  else if (bfd_bwrite (pad, len, abfd) != len)
 	    goto err;
 	  off += len;
 	}
@@ -314,7 +330,12 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
       str = entry->root.string;
       len = entry->len;
 
-      if (bfd_bwrite (str, len, abfd) != len)
+      if (contents)
+	{
+	  memcpy (contents + offset, str, len);
+	  offset += len;
+	}
+      else if (bfd_bwrite (str, len, abfd) != len)
 	goto err;
 
       off += len;
@@ -322,9 +343,13 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
 
   /* Trailing alignment needed?  */
   off = sec->size - off;
-  if (off != 0
-      && bfd_bwrite (pad, off, abfd) != off)
-    goto err;
+  if (off != 0)
+    {
+      if (contents)
+	memcpy (contents + offset, pad, off);
+      else if (bfd_bwrite (pad, off, abfd) != off)
+	goto err;
+    }
 
   if (pad != NULL)
     free (pad);
@@ -785,6 +810,7 @@ _bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
 {
   struct sec_merge_sec_info *secinfo;
   file_ptr pos;
+  unsigned char *contents;
 
   secinfo = (struct sec_merge_sec_info *) psecinfo;
 
@@ -794,12 +820,33 @@ _bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
   if (secinfo->first_str == NULL)
     return TRUE;
 
+  contents = NULL;
+
   /* FIXME: octets_per_byte.  */
-  pos = sec->output_section->filepos + sec->output_offset;
-  if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
-    return FALSE;
+  if (bfd_get_flavour (output_bfd) == bfd_target_elf_flavour)
+    {
+      Elf_Internal_Shdr *hdr
+	= &elf_section_data (sec->output_section)->this_hdr;
+      if (hdr->sh_offset == (file_ptr) -1)
+	{
+	  /* We must compress this section.  Write output to the
+	     buffer.  */
+	  contents = hdr->contents;
+	  if ((sec->output_section->flags & SEC_ELF_COMPRESS) == 0
+	      || contents == NULL)
+	    abort ();
+	}
+    }
+
+  if (contents == NULL)
+    {
+      pos = sec->output_section->filepos + sec->output_offset;
+      if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
+	return FALSE;
+    }
 
-  if (! sec_merge_emit (output_bfd, secinfo->first_str))
+  if (! sec_merge_emit (output_bfd, secinfo->first_str,
+			sec->output_offset))
     return FALSE;
 
   return TRUE;
diff --git a/bfd/section.c b/bfd/section.c
index 4a6f2e4..d59a0e3 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -334,6 +334,10 @@ CODE_FRAGMENT
 .     executables or shared objects. This is for COFF only.  *}
 .#define SEC_COFF_SHARED 0x8000000
 .
+.  {* This section should be compressed.  This is for ELF linker
+.     internal use only.  *}
+.#define SEC_ELF_COMPRESS 0x8000000
+.
 .  {* When a section with this flag is being linked, then if the size of
 .     the input section is less than a page, it should not cross a page
 .     boundary.  If the size of the input section is one page or more,
diff --git a/gas/as.h b/gas/as.h
index e04cc0f..6de319e 100644
--- a/gas/as.h
+++ b/gas/as.h
@@ -370,16 +370,6 @@ COMMON int flag_strip_local_absolute;
 /* True if we should generate a traditional format object file.  */
 COMMON int flag_traditional_format;
 
-/* Types of compressed debug sections.  We currently support zlib.  */
-enum compressed_debug_section_type
-{
-  COMPRESS_DEBUG_NONE = 0,
-  COMPRESS_DEBUG,
-  COMPRESS_DEBUG_ZLIB,
-  COMPRESS_DEBUG_GNU_ZLIB,
-  COMPRESS_DEBUG_GABI_ZLIB
-};
-
 /* Type of compressed debug sections we should generate.   */
 COMMON enum compressed_debug_section_type flag_compress_debug;
 
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 1b15826..3989c60 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -431,6 +431,9 @@ struct bfd_link_info
   /* Separator between archive and filename in linker script filespecs.  */
   char path_separator;
 
+  /* Compress DWARF debug sections.  */
+  enum compressed_debug_section_type compress_debug;
+
   /* Default stack size.  Zero means default (often zero itself), -1
      means explicitly zero-sized.  */
   bfd_signed_vma stacksize;
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 5db5a93..0802d76 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -2110,6 +2110,7 @@ fragment <<EOF
 #define OPTION_HASH_STYLE		(OPTION_EXCLUDE_LIBS + 1)
 #define OPTION_BUILD_ID			(OPTION_HASH_STYLE + 1)
 #define OPTION_AUDIT			(OPTION_BUILD_ID + 1)
+#define OPTION_COMPRESS_DEBUG		(OPTION_AUDIT + 1)
 
 static void
 gld${EMULATION_NAME}_add_options
@@ -2137,6 +2138,7 @@ EOF
 fi
 fragment <<EOF
     {"build-id", optional_argument, NULL, OPTION_BUILD_ID},
+    {"compress-debug-sections", required_argument, NULL, OPTION_COMPRESS_DEBUG},
 EOF
 if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
 fragment <<EOF
@@ -2186,6 +2188,19 @@ gld${EMULATION_NAME}_handle_option (int optc)
 	emit_note_gnu_build_id = xstrdup (optarg);
       break;
 
+    case OPTION_COMPRESS_DEBUG:
+      if (strcasecmp (optarg, "none") == 0)
+	link_info.compress_debug = COMPRESS_DEBUG_NONE;
+      else if (strcasecmp (optarg, "zlib") == 0)
+	link_info.compress_debug = COMPRESS_DEBUG_ZLIB;
+      else if (strcasecmp (optarg, "zlib-gnu") == 0)
+	link_info.compress_debug = COMPRESS_DEBUG_GNU_ZLIB;
+      else if (strcasecmp (optarg, "zlib-gabi") == 0)
+	link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
+      else
+	einfo (_("%P%F: invalid --compress-debug-sections option: \`%s'\n"),
+	       optarg);
+      break;
 EOF
 
 if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 4348c88..77c02d6 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -2201,6 +2201,22 @@ new style GNU @code{.gnu.hash} section or @code{both} for both
 the classic ELF @code{.hash} and new style GNU @code{.gnu.hash}
 hash tables.  The default is @code{sysv}.
 
+@kindex --compress-debug-sections=none
+@kindex --compress-debug-sections=zlib
+@kindex --compress-debug-sections=zlib-gnu
+@kindex --compress-debug-sections=zlib-gabi
+@item --compress-debug-sections=none
+@itemx --compress-debug-sections=zlib
+@itemx --compress-debug-sections=zlib-gnu
+@itemx --compress-debug-sections=zlib-gabi
+On ELF platforms , these options control how DWARF debug sections are
+compressed using zlib.  @option{--compress-debug-sections=none} doesn't
+compress DWARF debug sections.  @option{--compress-debug-sections=zlib}
+and @option{--compress-debug-sections=zlib-gnu} compress DWARF debug
+sections and rename debug section names to begin with @samp{.zdebug}
+instead of @samp{.debug}.  @option{--compress-debug-sections=zlib-gabi}
+compresses DWARF debug sections with SHF_COMPRESSED from the ELF ABI.
+
 @kindex --reduce-memory-overheads
 @item --reduce-memory-overheads
 This option reduces memory requirements at ld runtime, at the expense of
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 2ecb92d..a7b72bd 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -425,6 +425,13 @@ main (int argc, char **argv)
   else
     link_info.output_bfd->flags |= EXEC_P;
 
+  if ((link_info.compress_debug & COMPRESS_DEBUG))
+    {
+      link_info.output_bfd->flags |= BFD_COMPRESS;
+      if (link_info.compress_debug == COMPRESS_DEBUG_GABI_ZLIB)
+	link_info.output_bfd->flags |= BFD_COMPRESS_GABI;
+    }
+
   ldwrite ();
 
   if (config.map_file != NULL)
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 4a71ba4..b618241 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -1722,6 +1722,9 @@ elf_static_list_options (FILE *file)
   fprintf (file, _("\
   --build-id[=STYLE]          Generate build ID note\n"));
   fprintf (file, _("\
+  --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi]\n\
+                              Compress DWARF debug sections using zlib\n"));
+  fprintf (file, _("\
   -z common-page-size=SIZE    Set common page size to SIZE\n"));
   fprintf (file, _("\
   -z max-page-size=SIZE       Set maximum page size to SIZE\n"));
diff --git a/ld/testsuite/ld-elf/compress.exp b/ld/testsuite/ld-elf/compress.exp
index adb7fc2..e2448b9 100644
--- a/ld/testsuite/ld-elf/compress.exp
+++ b/ld/testsuite/ld-elf/compress.exp
@@ -49,7 +49,8 @@ set build_tests {
    "-shared" "-fPIC -g -Wa,--compress-debug-sections"
    {foo.c} {} "libfoo.so"}
   {"Build libbar.so with compressed debug sections"
-   "-shared" "-fPIC -g -Wa,--compress-debug-sections"
+   "-shared -Wl,--compress-debug-sections=none"
+   "-fPIC -g -Wa,--compress-debug-sections"
    {begin.c end.c} {} "libbar.so"}
   {"Build libfoozlib.so with compressed debug sections with zlib-gabi"
    "-shared" "-fPIC -g -Wa,--compress-debug-sections=zlib-gabi"
@@ -57,6 +58,30 @@ set build_tests {
   {"Build libbarzlib.so with compressed debug sections with zlib-gabi"
    "-shared" "-fPIC -g -Wa,--compress-debug-sections=zlib-gabi"
    {begin.c end.c} {} "libbarzlib.so"}
+  {"Build libzlibfoo.so with zlib compressed debug sections"
+   "-shared -Wl,--compress-debug-sections=zlib"
+   "-fPIC -g -Wa,--compress-debug-sections=zlib"
+   {foo.c} {} "libzlibfoo.so"}
+  {"Build libgnufoo.so with zlib-gnu compressed debug sections"
+   "-shared -Wl,--compress-debug-sections=zlib-gnu"
+   "-fPIC -g -Wa,--compress-debug-sections=zlib-gnu"
+   {foo.c} {} "libgnufoo.so"}
+  {"Build libgabifoo.so with zlib-gabi compressed debug sections"
+   "-shared -Wl,--compress-debug-sections=zlib-gabi"
+   "-fPIC -g -Wa,--compress-debug-sections=zlib-gabi"
+   {foo.c} {} "libgabifoo.so"}
+  {"Build zlibbegin.o with zlib compressed debug sections"
+   "-r -nostdlib -Wl,--compress-debug-sections=zlib"
+   "-g -Wa,--compress-debug-sections=zlib"
+   {begin.c} {} "zlibbegin.o"}
+  {"Build gnubegin.o with zlib-gnu compressed debug sections"
+   "-r -nostdlib -Wl,--compress-debug-sections=zlib-gnu"
+   "-g -Wa,--compress-debug-sections=zlib-gnu"
+   {begin.c} {} "gnubegin.o"}
+  {"Build gabiend.o with zlib-gabi compressed debug sections"
+   "-r -nostdlib -Wl,--compress-debug-sections=zlib-gabi"
+   "-g -Wa,--compress-debug-sections=zlib-gnu"
+   {end.c} {} "gabiend.o"}
 }
 
 set run_tests {
@@ -66,6 +91,15 @@ set run_tests {
     {"Run normal with libfoo.so with compressed debug sections with zlib-gabi"
      "tmpdir/begin.o tmpdir/libfoozlib.so tmpdir/end.o" ""
      {main.c} "normal" "normal.out" "-Wa,--compress-debug-sections=zlib-gabi"}
+    {"Run zlibnormal with libzlibfoo.so with zlib compressed debug sections"
+     "tmpdir/begin.o tmpdir/libzlibfoo.so tmpdir/end.o --compress-debug-sections=zlib" ""
+     {main.c} "zlibnormal" "normal.out" "-Wa,--compress-debug-sections=zlib"}
+    {"Run gnunormal with libgnufoo.so with zlib-gnu compressed debug sections"
+     "tmpdir/gnubegin.o tmpdir/libgnufoo.so tmpdir/end.o --compress-debug-sections=zlib-gnu" ""
+     {main.c} "gnunormal" "normal.out" "-Wa,--compress-debug-sections=zlib-gnu"}
+    {"Run gabinormal with libgabifoo.so with zlib-gabi compressed debug sections"
+     "tmpdir/zlibbegin.o tmpdir/libgabifoo.so tmpdir/gabiend.o --compress-debug-sections=zlib-gabi" ""
+     {main.c} "gabinormal" "normal.out" "-Wa,--compress-debug-sections=zlib-gabi"}
 }
 
 run_cc_link_tests $build_tests
@@ -79,3 +113,134 @@ if { [catch {exec cmp tmpdir/libfoo.so tmpdir/libfoozlib.so}] } then {
 } else {
     pass "$test_name"
 }
+
+global READELF
+
+set test_name "Link -r with zlib compressed debug output"
+set test zlibbegin
+send_log "$READELF -S -W tmpdir/$test.o > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -S -W tmpdir/$test.o" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rS] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+
+set test_name "Link -r with zlib-gnu compressed debug output"
+set test gnubegin
+send_log "$READELF -S -W tmpdir/$test.o > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -S -W tmpdir/$test.o" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rS] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+
+set test_name "Link -r with zlib-gabi compressed debug output"
+set test gabiend
+send_log "$READELF -t -W tmpdir/$test.o > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -t -W tmpdir/$test.o" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rt] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+
+set test_name "Link with zlib compressed debug output"
+set test normal
+send_log "$READELF -w tmpdir/$test > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -w tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+
+set test_name "Link with zlib compressed debug output"
+set test zlibnormal
+send_log "$READELF -w tmpdir/$test | sed -e \"s/.zdebug_/.debug_/\" > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -w tmpdir/$test | sed -e \"s/.zdebug_/.debug_/\"" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [catch {exec cmp tmpdir/normal.out tmpdir/$test.out}] } then {
+    send_log "tmpdir/normal.out tmpdir/$test.out differ.\n"
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+send_log "$READELF -S -W tmpdir/$test' > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -S -W tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rS] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+
+set test_name "Link with zlib-gnu compressed debug output"
+set test gnunormal
+send_log "$READELF -w tmpdir/$test | sed -e \"s/.zdebug_/.debug_/\" > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -w tmpdir/$test | sed -e \"s/.zdebug_/.debug_/\"" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [catch {exec cmp tmpdir/normal.out tmpdir/$test.out}] } then {
+    send_log "tmpdir/normal.out tmpdir/$test.out differ.\n"
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+send_log "$READELF -S -W tmpdir/$test' > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -S -W tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rS] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+
+set test gabinormal
+set test_name "Link with zlib-gabi compressed debug output"
+send_log "$READELF -w tmpdir/$test > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -w tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [catch {exec cmp tmpdir/normal.out tmpdir/$test.out}] } then {
+    send_log "tmpdir/normal.out tmpdir/$test.out differ.\n"
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+send_log "$READELF -t -W tmpdir/$test > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -t -W tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rt] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
diff --git a/ld/testsuite/ld-elf/gabiend.rt b/ld/testsuite/ld-elf/gabiend.rt
new file mode 100644
index 0000000..23bc36c
--- /dev/null
+++ b/ld/testsuite/ld-elf/gabiend.rt
@@ -0,0 +1,4 @@
+#...
+ +\[[0-9a-f]+\]: .*COMPRESSED
+ +ZLIB, [0-9a-f]+, 1
+#pass
diff --git a/ld/testsuite/ld-elf/gabinormal.rt b/ld/testsuite/ld-elf/gabinormal.rt
new file mode 100644
index 0000000..23bc36c
--- /dev/null
+++ b/ld/testsuite/ld-elf/gabinormal.rt
@@ -0,0 +1,4 @@
+#...
+ +\[[0-9a-f]+\]: .*COMPRESSED
+ +ZLIB, [0-9a-f]+, 1
+#pass
diff --git a/ld/testsuite/ld-elf/gnubegin.rS b/ld/testsuite/ld-elf/gnubegin.rS
new file mode 100644
index 0000000..54de24c
--- /dev/null
+++ b/ld/testsuite/ld-elf/gnubegin.rS
@@ -0,0 +1,3 @@
+#...
+ +\[[ 0-9]+\] .zdebug_.* +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +0 +0 +1
+#pass
diff --git a/ld/testsuite/ld-elf/gnunormal.rS b/ld/testsuite/ld-elf/gnunormal.rS
new file mode 100644
index 0000000..54de24c
--- /dev/null
+++ b/ld/testsuite/ld-elf/gnunormal.rS
@@ -0,0 +1,3 @@
+#...
+ +\[[ 0-9]+\] .zdebug_.* +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +0 +0 +1
+#pass
diff --git a/ld/testsuite/ld-elf/zlibbegin.rS b/ld/testsuite/ld-elf/zlibbegin.rS
new file mode 100644
index 0000000..54de24c
--- /dev/null
+++ b/ld/testsuite/ld-elf/zlibbegin.rS
@@ -0,0 +1,3 @@
+#...
+ +\[[ 0-9]+\] .zdebug_.* +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +0 +0 +1
+#pass
diff --git a/ld/testsuite/ld-elf/zlibnormal.rS b/ld/testsuite/ld-elf/zlibnormal.rS
new file mode 100644
index 0000000..54de24c
--- /dev/null
+++ b/ld/testsuite/ld-elf/zlibnormal.rS
@@ -0,0 +1,3 @@
+#...
+ +\[[ 0-9]+\] .zdebug_.* +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +0 +0 +1
+#pass
-- 
2.1.0


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-15  2:44   ` H.J. Lu
@ 2015-04-15  3:58     ` Alan Modra
  2015-04-15  5:07       ` H.J. Lu
  0 siblings, 1 reply; 23+ messages in thread
From: Alan Modra @ 2015-04-15  3:58 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

On Tue, Apr 14, 2015 at 07:43:36PM -0700, H.J. Lu wrote:
> On Tue, Apr 14, 2015 at 5:55 PM, Alan Modra <amodra@gmail.com> wrote:
> > So, I'm wondering whether things would look better if
> > elf_link_input_bfd allocated the extra buffer needed rather than in
> > both _bfd_write_merged_section and _bfd_elf_set_section_contents.
> > Of course, _bfd_write_merged_section would need two extra parameters,
> > contents and offset, and write to "contents" if non-NULL rather than
> > to the output file.
> 
> Thanks for the suggestion.  I allocated the buffer in bfd_elf_final_link
> instead without adding extra arguments to _bfd_write_merged_section.
> Here is the updated patch. OK for master?

I still think the extra arguments are better, but will OK this one
with some fixes.

> @@ -283,13 +284,15 @@ sec_merge_add (struct sec_merge_hash *tab, const char *str,
>  }
>  
>  static bfd_boolean
> -sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
> +sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry,
> +		file_ptr offset)
>  {
>    struct sec_merge_sec_info *secinfo = entry->secinfo;
>    asection *sec = secinfo->sec;
>    char *pad = NULL;
>    bfd_size_type off = 0;
>    int alignment_power = sec->output_section->alignment_power;
> +  unsigned char *contents = NULL;

pass contents to sec_merge_emit, so that

> @@ -298,6 +301,14 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
>  	return FALSE;
>      }
>  
> +  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
> +    {
> +      Elf_Internal_Shdr *hdr
> +	= &elf_section_data (sec->output_section)->this_hdr;
> +      if (hdr->sh_offset == (file_ptr) -1)
> +	contents = hdr->contents;
> +    }
> +

this hunk can disappear.

> @@ -794,12 +820,33 @@ _bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
>    if (secinfo->first_str == NULL)
>      return TRUE;
>  
> +  contents = NULL;
> +
>    /* FIXME: octets_per_byte.  */
> -  pos = sec->output_section->filepos + sec->output_offset;
> -  if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
> -    return FALSE;
> +  if (bfd_get_flavour (output_bfd) == bfd_target_elf_flavour)

Delete this unnecessary test.  merge.c is only used with ELF output.

-- 
Alan Modra
Australia Development Lab, IBM

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-15  3:58     ` Alan Modra
@ 2015-04-15  5:07       ` H.J. Lu
  2015-04-28 18:57         ` Andreas Schwab
                           ` (2 more replies)
  0 siblings, 3 replies; 23+ messages in thread
From: H.J. Lu @ 2015-04-15  5:07 UTC (permalink / raw)
  To: Binutils

[-- Attachment #1: Type: text/plain, Size: 2427 bytes --]

On Tue, Apr 14, 2015 at 8:58 PM, Alan Modra <amodra@gmail.com> wrote:
> On Tue, Apr 14, 2015 at 07:43:36PM -0700, H.J. Lu wrote:
>> On Tue, Apr 14, 2015 at 5:55 PM, Alan Modra <amodra@gmail.com> wrote:
>> > So, I'm wondering whether things would look better if
>> > elf_link_input_bfd allocated the extra buffer needed rather than in
>> > both _bfd_write_merged_section and _bfd_elf_set_section_contents.
>> > Of course, _bfd_write_merged_section would need two extra parameters,
>> > contents and offset, and write to "contents" if non-NULL rather than
>> > to the output file.
>>
>> Thanks for the suggestion.  I allocated the buffer in bfd_elf_final_link
>> instead without adding extra arguments to _bfd_write_merged_section.
>> Here is the updated patch. OK for master?
>
> I still think the extra arguments are better, but will OK this one
> with some fixes.
>
>> @@ -283,13 +284,15 @@ sec_merge_add (struct sec_merge_hash *tab, const char *str,
>>  }
>>
>>  static bfd_boolean
>> -sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
>> +sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry,
>> +             file_ptr offset)
>>  {
>>    struct sec_merge_sec_info *secinfo = entry->secinfo;
>>    asection *sec = secinfo->sec;
>>    char *pad = NULL;
>>    bfd_size_type off = 0;
>>    int alignment_power = sec->output_section->alignment_power;
>> +  unsigned char *contents = NULL;
>
> pass contents to sec_merge_emit, so that
>
>> @@ -298,6 +301,14 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
>>       return FALSE;
>>      }
>>
>> +  if (bfd_get_flavour (abfd) == bfd_target_elf_flavour)
>> +    {
>> +      Elf_Internal_Shdr *hdr
>> +     = &elf_section_data (sec->output_section)->this_hdr;
>> +      if (hdr->sh_offset == (file_ptr) -1)
>> +     contents = hdr->contents;
>> +    }
>> +
>
> this hunk can disappear.
>
>> @@ -794,12 +820,33 @@ _bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
>>    if (secinfo->first_str == NULL)
>>      return TRUE;
>>
>> +  contents = NULL;
>> +
>>    /* FIXME: octets_per_byte.  */
>> -  pos = sec->output_section->filepos + sec->output_offset;
>> -  if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
>> -    return FALSE;
>> +  if (bfd_get_flavour (output_bfd) == bfd_target_elf_flavour)
>
> Delete this unnecessary test.  merge.c is only used with ELF output.
>

This is what I checked in.

Thanks.


-- 
H.J.

[-- Attachment #2: 0001-Add-compress-debug-sections-none-zlib-zlib-gnu-zlib-.patch --]
[-- Type: text/x-patch, Size: 33611 bytes --]

From 2d8ff38c19a7b6690589788acf1107b224775705 Mon Sep 17 00:00:00 2001
From: "H.J. Lu" <hjl.tools@gmail.com>
Date: Mon, 13 Apr 2015 05:30:52 -0700
Subject: [PATCH] Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi]

This patch adds --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi]
to ld for ELF targets to support generating compressed DWARF debug
sections.  We always generate .zdebug_* section since section names have
been finalized and they can't be changed easily when compression is
being performed.

bfd/

	* bfd-in.h (compressed_debug_section_type): New.
	* compress.c (bfd_compress_section_contents): Add an argument
	for linker write compression and always generate .zdebug_*
	section when linking.
	(bfd_init_section_compress_status): Pass FALSE to
	bfd_compress_section_contents.
	(bfd_compress_section): New function.
	* elf.c (elf_fake_sections): For linking, set SEC_ELF_COMPRESS
	on DWARF debug sections if COMPRESS_DEBUG is set and rename
	section if COMPRESS_DEBUG_GABI_ZLIB isn't set.
	(assign_file_positions_for_non_load_sections): Set sh_offset
	to -1 if SEC_ELF_COMPRESS is set.
	(assign_file_positions_except_relocs): Likwise.
	(_bfd_elf_assign_file_positions_for_relocs): Renamed to ...
	(_bfd_elf_assign_file_positions_for_non_load): This.  Change
	return time to bfd_boolean.  Compress the section if
	SEC_ELF_COMPRESS is set.
	(_bfd_elf_write_object_contents): Updated.
	(_bfd_elf_set_section_contents): Write section contents to
	the buffer if SEC_ELF_COMPRESS is set.
	* merge.c: Include "elf-bfd.h".
	(sec_merge_emit): Add arguments for contents and offset.  Write
	to contents with offset if contents isn't NULL.
	(_bfd_write_merged_section): Write section contents to the
	buffer if SEC_ELF_COMPRESS is set.  Pass contents and
	output_offset to sec_merge_emit.
	* elflink.c (bfd_elf_final_link): Allocate the buffer for
	output section contents if SEC_ELF_COMPRESS is set.
	* section.c (SEC_ELF_COMPRESS): New.
	* bfd-in2.h: Regenerated.

gas/

	* as.h (compressed_debug_section_type): Removed.

include/

	* bfdlink.h (bfd_link_info): Add compress_debug.

ld/

	* ld.texinfo: Document --compress-debug-sections=.
	* ldmain.c (main): Set BFD_COMPRESS on output_bfd if
	COMPRESS_DEBUG is set.  Set BFD_COMPRESS_GABI on output_bfd
	for COMPRESS_DEBUG_GABI_ZLIB.
	* lexsup.c (elf_static_list_options): Add
	--compress-debug-sections=.
	* emultempl/elf32.em (OPTION_COMPRESS_DEBUG): New.
	(xtra_long): Add "compress-debug-sections".
	(gld${EMULATION_NAME}_handle_option): Handle
	OPTION_COMPRESS_DEBUG.

ld/testsuite/

	* ld-elf/compress.exp (build_tests): Add tests for
	--compress-debug-sections=.
	(run_tests): Likewise.
	Add additonal tests for --compress-debug-sections=.
	* ld-elf/gabiend.rt: New file.
	* ld-elf/gabinormal.rt: Likewise.
	* ld-elf/gnubegin.rS: Likewise.
	* ld-elf/gnunormal.rS: Likewise.
	* ld-elf/zlibbegin.rS: Likewise.
	* ld-elf/zlibnormal.rS: Likewise.
---
 bfd/bfd-in.h                      |  11 +++
 bfd/bfd-in2.h                     |  18 ++++
 bfd/compress.c                    |  51 +++++++++++-
 bfd/elf.c                         |  89 ++++++++++++++++++--
 bfd/elflink.c                     |  15 ++++
 bfd/merge.c                       |  53 +++++++++---
 bfd/section.c                     |   4 +
 gas/as.h                          |  10 ---
 include/bfdlink.h                 |   3 +
 ld/emultempl/elf32.em             |  15 ++++
 ld/ld.texinfo                     |  16 ++++
 ld/ldmain.c                       |   7 ++
 ld/lexsup.c                       |   3 +
 ld/testsuite/ld-elf/compress.exp  | 167 +++++++++++++++++++++++++++++++++++++-
 ld/testsuite/ld-elf/gabiend.rt    |   4 +
 ld/testsuite/ld-elf/gabinormal.rt |   4 +
 ld/testsuite/ld-elf/gnubegin.rS   |   3 +
 ld/testsuite/ld-elf/gnunormal.rS  |   3 +
 ld/testsuite/ld-elf/zlibbegin.rS  |   3 +
 ld/testsuite/ld-elf/zlibnormal.rS |   3 +
 20 files changed, 450 insertions(+), 32 deletions(-)
 create mode 100644 ld/testsuite/ld-elf/gabiend.rt
 create mode 100644 ld/testsuite/ld-elf/gabinormal.rt
 create mode 100644 ld/testsuite/ld-elf/gnubegin.rS
 create mode 100644 ld/testsuite/ld-elf/gnunormal.rS
 create mode 100644 ld/testsuite/ld-elf/zlibbegin.rS
 create mode 100644 ld/testsuite/ld-elf/zlibnormal.rS

diff --git a/bfd/bfd-in.h b/bfd/bfd-in.h
index 1f8a72c..2e324cd 100644
--- a/bfd/bfd-in.h
+++ b/bfd/bfd-in.h
@@ -437,6 +437,17 @@ extern void bfd_hash_traverse
    this size.  */
 extern unsigned long bfd_hash_set_default_size (unsigned long);
 
+/* Types of compressed DWARF debug sections.  We currently support
+   zlib.  */
+enum compressed_debug_section_type
+{
+  COMPRESS_DEBUG_NONE = 0,
+  COMPRESS_DEBUG = 1 << 0,
+  COMPRESS_DEBUG_ZLIB = COMPRESS_DEBUG | 1 << 1,
+  COMPRESS_DEBUG_GNU_ZLIB = COMPRESS_DEBUG | 1 << 2,
+  COMPRESS_DEBUG_GABI_ZLIB = COMPRESS_DEBUG | 1 << 3
+};
+
 /* This structure is used to keep track of stabs in sections
    information while linking.  */
 
diff --git a/bfd/bfd-in2.h b/bfd/bfd-in2.h
index 679595e..122caa0 100644
--- a/bfd/bfd-in2.h
+++ b/bfd/bfd-in2.h
@@ -444,6 +444,17 @@ extern void bfd_hash_traverse
    this size.  */
 extern unsigned long bfd_hash_set_default_size (unsigned long);
 
+/* Types of compressed DWARF debug sections.  We currently support
+   zlib.  */
+enum compressed_debug_section_type
+{
+  COMPRESS_DEBUG_NONE = 0,
+  COMPRESS_DEBUG = 1 << 0,
+  COMPRESS_DEBUG_ZLIB = COMPRESS_DEBUG | 1 << 1,
+  COMPRESS_DEBUG_GNU_ZLIB = COMPRESS_DEBUG | 1 << 2,
+  COMPRESS_DEBUG_GABI_ZLIB = COMPRESS_DEBUG | 1 << 3
+};
+
 /* This structure is used to keep track of stabs in sections
    information while linking.  */
 
@@ -1378,6 +1389,10 @@ typedef struct bfd_section
      executables or shared objects. This is for COFF only.  */
 #define SEC_COFF_SHARED 0x8000000
 
+  /* This section should be compressed.  This is for ELF linker
+     internal use only.  */
+#define SEC_ELF_COMPRESS 0x8000000
+
   /* When a section with this flag is being linked, then if the size of
      the input section is less than a page, it should not cross a page
      boundary.  If the size of the input section is one page or more,
@@ -7316,6 +7331,9 @@ bfd_boolean bfd_init_section_decompress_status
 bfd_boolean bfd_init_section_compress_status
    (bfd *abfd, asection *section);
 
+bfd_boolean bfd_compress_section
+   (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer);
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/bfd/compress.c b/bfd/compress.c
index 770ea57..dfde50e 100644
--- a/bfd/compress.c
+++ b/bfd/compress.c
@@ -72,7 +72,8 @@ decompress_contents (bfd_byte *compressed_buffer,
 static bfd_size_type
 bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
 			       bfd_byte *uncompressed_buffer,
-			       bfd_size_type uncompressed_size)
+			       bfd_size_type uncompressed_size,
+			       bfd_boolean write_compress)
 {
   uLong compressed_size;
   bfd_byte *buffer;
@@ -176,8 +177,11 @@ bfd_compress_section_contents (bfd *abfd, sec_ptr sec,
 
       compressed_size += header_size;
       /* PR binutils/18087: If compression didn't make the section smaller,
-	 just keep it uncompressed.  */
-      if (compressed_size < uncompressed_size)
+	 just keep it uncompressed.  We always generate .zdebug_* section
+	 when linking since section names have been finalized and they
+	 can't be changed easily.  */
+      if ((write_compress && compression_header_size == 0)
+	   || compressed_size < uncompressed_size)
 	{
 	  bfd_update_compression_header (abfd, buffer, sec);
 
@@ -543,9 +547,48 @@ bfd_init_section_compress_status (bfd *abfd, sec_ptr sec)
     {
       uncompressed_size = bfd_compress_section_contents (abfd, sec,
 							 uncompressed_buffer,
-							 uncompressed_size);
+							 uncompressed_size,
+							 FALSE);
       ret = uncompressed_size != 0;
     }
 
   return ret;
 }
+
+/*
+FUNCTION
+	bfd_compress_section
+
+SYNOPSIS
+	bfd_boolean bfd_compress_section
+	  (bfd *abfd, asection *section, bfd_byte *uncompressed_buffer);
+
+DESCRIPTION
+	If open for write, compress section, update section size with
+	compressed size and set compress_status to COMPRESS_SECTION_DONE.
+
+	Return @code{FALSE} if compression fail.  Otherwise, return
+	@code{TRUE}.
+*/
+
+bfd_boolean
+bfd_compress_section (bfd *abfd, sec_ptr sec, bfd_byte *uncompressed_buffer)
+{
+  bfd_size_type uncompressed_size = sec->size;
+
+  /* Error if not opened for write.  */
+  if (abfd->direction != write_direction
+      || uncompressed_size == 0
+      || uncompressed_buffer == NULL
+      || sec->contents != NULL
+      || sec->compressed_size != 0
+      || sec->compress_status != COMPRESS_SECTION_NONE)
+    {
+      bfd_set_error (bfd_error_invalid_operation);
+      return FALSE;
+    }
+
+  /* Compress it.  */
+  return bfd_compress_section_contents (abfd, sec, uncompressed_buffer,
+					uncompressed_size, TRUE) != 0;
+}
diff --git a/bfd/elf.c b/bfd/elf.c
index 41fb023..85a4b6b 100644
--- a/bfd/elf.c
+++ b/bfd/elf.c
@@ -2752,6 +2752,7 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
   struct bfd_elf_section_data *esd = elf_section_data (asect);
   Elf_Internal_Shdr *this_hdr;
   unsigned int sh_type;
+  const char *name = asect->name;
 
   if (arg->failed)
     {
@@ -2762,8 +2763,38 @@ elf_fake_sections (bfd *abfd, asection *asect, void *fsarg)
 
   this_hdr = &esd->this_hdr;
 
+  /* For linking, compress DWARF debug sections with names: .debug_*.  */
+  if (arg->link_info
+      && (arg->link_info->compress_debug & COMPRESS_DEBUG)
+      && (asect->flags & SEC_DEBUGGING)
+      && name[1] == 'd'
+      && name[6] == '_')
+    {
+      /* Set SEC_ELF_COMPRESS to indicate this section should be
+	 compressed.  */
+      asect->flags |= SEC_ELF_COMPRESS;
+
+      if (arg->link_info->compress_debug != COMPRESS_DEBUG_GABI_ZLIB)
+	{
+	  /* If SHF_COMPRESSED isn't used, rename compressed DWARF
+	     debug section to .zdebug_*.  */
+	  unsigned int len = strlen (name);
+	  char *new_name = bfd_alloc (abfd, len + 2);
+	  if (new_name == NULL)
+	    {
+	      arg->failed = TRUE;
+	      return;
+	    }
+	  new_name[0] = '.';
+	  new_name[1] = 'z';
+	  memcpy (new_name + 2, name + 1, len);
+	  bfd_rename_section (abfd, asect, new_name);
+	  name = asect->name;
+	}
+    }
+
   this_hdr->sh_name = (unsigned int) _bfd_elf_strtab_add (elf_shstrtab (abfd),
-							  asect->name, FALSE);
+							  name, FALSE);
   if (this_hdr->sh_name == (unsigned int) -1)
     {
       arg->failed = TRUE;
@@ -5116,6 +5147,9 @@ assign_file_positions_for_non_load_sections (bfd *abfd,
 	}
       else if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
 		&& hdr->bfd_section == NULL)
+	       || (hdr->bfd_section != NULL
+		   && (hdr->bfd_section->flags & SEC_ELF_COMPRESS))
+		   /* Compress DWARF debug sections.  */
 	       || hdr == i_shdrpp[elf_onesymtab (abfd)]
 	       || hdr == i_shdrpp[elf_symtab_shndx (abfd)]
 	       || hdr == i_shdrpp[elf_strtab_sec (abfd)])
@@ -5365,6 +5399,9 @@ assign_file_positions_except_relocs (bfd *abfd,
 	  hdr = *hdrpp;
 	  if (((hdr->sh_type == SHT_REL || hdr->sh_type == SHT_RELA)
 	       && hdr->bfd_section == NULL)
+	      || (hdr->bfd_section != NULL
+		  && (hdr->bfd_section->flags & SEC_ELF_COMPRESS))
+		  /* Compress DWARF debug sections.  */
 	      || i == elf_onesymtab (abfd)
 	      || i == elf_symtab_shndx (abfd)
 	      || i == elf_strtab_sec (abfd))
@@ -5518,8 +5555,8 @@ prep_headers (bfd *abfd)
 /* Assign file positions for all the reloc sections which are not part
    of the loadable file image, and the file position of section headers.  */
 
-static void
-_bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
+static bfd_boolean
+_bfd_elf_assign_file_positions_for_non_load (bfd *abfd)
 {
   file_ptr off;
   unsigned int i, num_sec;
@@ -5535,9 +5572,30 @@ _bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
       Elf_Internal_Shdr *shdrp;
 
       shdrp = *shdrpp;
-      if ((shdrp->sh_type == SHT_REL || shdrp->sh_type == SHT_RELA)
-	  && shdrp->sh_offset == -1)
-	off = _bfd_elf_assign_file_position_for_section (shdrp, off, TRUE);
+      if (shdrp->sh_offset == -1)
+	{
+	  bfd_boolean is_rel = (shdrp->sh_type == SHT_REL
+				|| shdrp->sh_type == SHT_RELA);
+	  if (is_rel
+	      || (shdrp->bfd_section != NULL
+		  && (shdrp->bfd_section->flags & SEC_ELF_COMPRESS)))
+	    {
+	      if (!is_rel)
+		{
+		  /* Compress DWARF debug sections.  */
+		  if (!bfd_compress_section (abfd, shdrp->bfd_section,
+					     shdrp->contents))
+		    return FALSE;
+		  /* Update section size and contents.  */
+		  shdrp->sh_size = shdrp->bfd_section->size;
+		  shdrp->contents = shdrp->bfd_section->contents;
+		  shdrp->bfd_section->contents = NULL;
+		}
+	      off = _bfd_elf_assign_file_position_for_section (shdrp,
+							       off,
+							       TRUE);
+	    }
+	}
     }
 
 /* Place the section headers.  */
@@ -5547,6 +5605,8 @@ _bfd_elf_assign_file_positions_for_relocs (bfd *abfd)
   i_ehdrp->e_shoff = off;
   off += i_ehdrp->e_shnum * i_ehdrp->e_shentsize;
   elf_next_file_pos (abfd) = off;
+
+  return TRUE;
 }
 
 bfd_boolean
@@ -5569,7 +5629,8 @@ _bfd_elf_write_object_contents (bfd *abfd)
   if (failed)
     return FALSE;
 
-  _bfd_elf_assign_file_positions_for_relocs (abfd);
+  if (!_bfd_elf_assign_file_positions_for_non_load (abfd))
+    return FALSE;
 
   /* After writing the headers, we need to write the sections too...  */
   num_sec = elf_numsections (abfd);
@@ -7922,7 +7983,21 @@ _bfd_elf_set_section_contents (bfd *abfd,
       && ! _bfd_elf_compute_section_file_positions (abfd, NULL))
     return FALSE;
 
+  if (!count)
+    return TRUE;
+
   hdr = &elf_section_data (section)->this_hdr;
+  if (hdr->sh_offset == (file_ptr) -1)
+    {
+      /* We must compress this section.  Write output to the buffer.  */
+      unsigned char *contents = hdr->contents;
+      if ((offset + count) > hdr->sh_size
+	  || (section->flags & SEC_ELF_COMPRESS) == 0
+	  || contents == NULL)
+	abort ();
+      memcpy (contents + offset, location, count);
+      return TRUE;
+    }
   pos = hdr->sh_offset + offset;
   if (bfd_seek (abfd, pos, SEEK_SET) != 0
       || bfd_bwrite (location, count, abfd) != count)
diff --git a/bfd/elflink.c b/bfd/elflink.c
index ea9246b..6efe1e4 100644
--- a/bfd/elflink.c
+++ b/bfd/elflink.c
@@ -10890,6 +10890,21 @@ bfd_elf_final_link (bfd *abfd, struct bfd_link_info *info)
 	 to count upwards while actually outputting the relocations.  */
       esdo->rel.count = 0;
       esdo->rela.count = 0;
+
+      if (esdo->this_hdr.sh_offset == (file_ptr) -1)
+	{
+	  /* Cache the section contents so that they can be compressed
+	     later.  Use bfd_malloc since it will be freed by
+	     bfd_compress_section_contents.  */
+	  unsigned char *contents = esdo->this_hdr.contents;
+	  if ((o->flags & SEC_ELF_COMPRESS) == 0 || contents != NULL)
+	    abort ();
+	  contents
+	    = (unsigned char *) bfd_malloc (esdo->this_hdr.sh_size);
+	  if (contents == NULL)
+	    goto error_return;
+	  esdo->this_hdr.contents = contents;
+	}
     }
 
   /* We have now assigned file positions for all the sections except
diff --git a/bfd/merge.c b/bfd/merge.c
index 5f45ba6..174ec90 100644
--- a/bfd/merge.c
+++ b/bfd/merge.c
@@ -25,6 +25,7 @@
 
 #include "sysdep.h"
 #include "bfd.h"
+#include "elf-bfd.h"
 #include "libbfd.h"
 #include "hashtab.h"
 #include "libiberty.h"
@@ -283,7 +284,8 @@ sec_merge_add (struct sec_merge_hash *tab, const char *str,
 }
 
 static bfd_boolean
-sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
+sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry,
+		unsigned char *contents, file_ptr offset)
 {
   struct sec_merge_sec_info *secinfo = entry->secinfo;
   asection *sec = secinfo->sec;
@@ -306,7 +308,12 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
       len = -off & (entry->alignment - 1);
       if (len != 0)
 	{
-	  if (bfd_bwrite (pad, len, abfd) != len)
+	  if (contents)
+	    {
+	      memcpy (contents + offset, pad, len);
+	      offset += len;
+	    }
+	  else if (bfd_bwrite (pad, len, abfd) != len)
 	    goto err;
 	  off += len;
 	}
@@ -314,7 +321,12 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
       str = entry->root.string;
       len = entry->len;
 
-      if (bfd_bwrite (str, len, abfd) != len)
+      if (contents)
+	{
+	  memcpy (contents + offset, str, len);
+	  offset += len;
+	}
+      else if (bfd_bwrite (str, len, abfd) != len)
 	goto err;
 
       off += len;
@@ -322,9 +334,13 @@ sec_merge_emit (bfd *abfd, struct sec_merge_hash_entry *entry)
 
   /* Trailing alignment needed?  */
   off = sec->size - off;
-  if (off != 0
-      && bfd_bwrite (pad, off, abfd) != off)
-    goto err;
+  if (off != 0)
+    {
+      if (contents)
+	memcpy (contents + offset, pad, off);
+      else if (bfd_bwrite (pad, off, abfd) != off)
+	goto err;
+    }
 
   if (pad != NULL)
     free (pad);
@@ -785,6 +801,8 @@ _bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
 {
   struct sec_merge_sec_info *secinfo;
   file_ptr pos;
+  unsigned char *contents;
+  Elf_Internal_Shdr *hdr;
 
   secinfo = (struct sec_merge_sec_info *) psecinfo;
 
@@ -795,11 +813,26 @@ _bfd_write_merged_section (bfd *output_bfd, asection *sec, void *psecinfo)
     return TRUE;
 
   /* FIXME: octets_per_byte.  */
-  pos = sec->output_section->filepos + sec->output_offset;
-  if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
-    return FALSE;
+  hdr = &elf_section_data (sec->output_section)->this_hdr;
+  if (hdr->sh_offset == (file_ptr) -1)
+    {
+      /* We must compress this section.  Write output to the
+	 buffer.  */
+      contents = hdr->contents;
+      if ((sec->output_section->flags & SEC_ELF_COMPRESS) == 0
+	  || contents == NULL)
+	abort ();
+    }
+  else
+    {
+      contents = NULL;
+      pos = sec->output_section->filepos + sec->output_offset;
+      if (bfd_seek (output_bfd, pos, SEEK_SET) != 0)
+	return FALSE;
+    }
 
-  if (! sec_merge_emit (output_bfd, secinfo->first_str))
+  if (! sec_merge_emit (output_bfd, secinfo->first_str, contents,
+			sec->output_offset))
     return FALSE;
 
   return TRUE;
diff --git a/bfd/section.c b/bfd/section.c
index 4a6f2e4..d59a0e3 100644
--- a/bfd/section.c
+++ b/bfd/section.c
@@ -334,6 +334,10 @@ CODE_FRAGMENT
 .     executables or shared objects. This is for COFF only.  *}
 .#define SEC_COFF_SHARED 0x8000000
 .
+.  {* This section should be compressed.  This is for ELF linker
+.     internal use only.  *}
+.#define SEC_ELF_COMPRESS 0x8000000
+.
 .  {* When a section with this flag is being linked, then if the size of
 .     the input section is less than a page, it should not cross a page
 .     boundary.  If the size of the input section is one page or more,
diff --git a/gas/as.h b/gas/as.h
index e04cc0f..6de319e 100644
--- a/gas/as.h
+++ b/gas/as.h
@@ -370,16 +370,6 @@ COMMON int flag_strip_local_absolute;
 /* True if we should generate a traditional format object file.  */
 COMMON int flag_traditional_format;
 
-/* Types of compressed debug sections.  We currently support zlib.  */
-enum compressed_debug_section_type
-{
-  COMPRESS_DEBUG_NONE = 0,
-  COMPRESS_DEBUG,
-  COMPRESS_DEBUG_ZLIB,
-  COMPRESS_DEBUG_GNU_ZLIB,
-  COMPRESS_DEBUG_GABI_ZLIB
-};
-
 /* Type of compressed debug sections we should generate.   */
 COMMON enum compressed_debug_section_type flag_compress_debug;
 
diff --git a/include/bfdlink.h b/include/bfdlink.h
index 1b15826..3989c60 100644
--- a/include/bfdlink.h
+++ b/include/bfdlink.h
@@ -431,6 +431,9 @@ struct bfd_link_info
   /* Separator between archive and filename in linker script filespecs.  */
   char path_separator;
 
+  /* Compress DWARF debug sections.  */
+  enum compressed_debug_section_type compress_debug;
+
   /* Default stack size.  Zero means default (often zero itself), -1
      means explicitly zero-sized.  */
   bfd_signed_vma stacksize;
diff --git a/ld/emultempl/elf32.em b/ld/emultempl/elf32.em
index 5db5a93..0802d76 100644
--- a/ld/emultempl/elf32.em
+++ b/ld/emultempl/elf32.em
@@ -2110,6 +2110,7 @@ fragment <<EOF
 #define OPTION_HASH_STYLE		(OPTION_EXCLUDE_LIBS + 1)
 #define OPTION_BUILD_ID			(OPTION_HASH_STYLE + 1)
 #define OPTION_AUDIT			(OPTION_BUILD_ID + 1)
+#define OPTION_COMPRESS_DEBUG		(OPTION_AUDIT + 1)
 
 static void
 gld${EMULATION_NAME}_add_options
@@ -2137,6 +2138,7 @@ EOF
 fi
 fragment <<EOF
     {"build-id", optional_argument, NULL, OPTION_BUILD_ID},
+    {"compress-debug-sections", required_argument, NULL, OPTION_COMPRESS_DEBUG},
 EOF
 if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
 fragment <<EOF
@@ -2186,6 +2188,19 @@ gld${EMULATION_NAME}_handle_option (int optc)
 	emit_note_gnu_build_id = xstrdup (optarg);
       break;
 
+    case OPTION_COMPRESS_DEBUG:
+      if (strcasecmp (optarg, "none") == 0)
+	link_info.compress_debug = COMPRESS_DEBUG_NONE;
+      else if (strcasecmp (optarg, "zlib") == 0)
+	link_info.compress_debug = COMPRESS_DEBUG_ZLIB;
+      else if (strcasecmp (optarg, "zlib-gnu") == 0)
+	link_info.compress_debug = COMPRESS_DEBUG_GNU_ZLIB;
+      else if (strcasecmp (optarg, "zlib-gabi") == 0)
+	link_info.compress_debug = COMPRESS_DEBUG_GABI_ZLIB;
+      else
+	einfo (_("%P%F: invalid --compress-debug-sections option: \`%s'\n"),
+	       optarg);
+      break;
 EOF
 
 if test x"$GENERATE_SHLIB_SCRIPT" = xyes; then
diff --git a/ld/ld.texinfo b/ld/ld.texinfo
index 4348c88..77c02d6 100644
--- a/ld/ld.texinfo
+++ b/ld/ld.texinfo
@@ -2201,6 +2201,22 @@ new style GNU @code{.gnu.hash} section or @code{both} for both
 the classic ELF @code{.hash} and new style GNU @code{.gnu.hash}
 hash tables.  The default is @code{sysv}.
 
+@kindex --compress-debug-sections=none
+@kindex --compress-debug-sections=zlib
+@kindex --compress-debug-sections=zlib-gnu
+@kindex --compress-debug-sections=zlib-gabi
+@item --compress-debug-sections=none
+@itemx --compress-debug-sections=zlib
+@itemx --compress-debug-sections=zlib-gnu
+@itemx --compress-debug-sections=zlib-gabi
+On ELF platforms , these options control how DWARF debug sections are
+compressed using zlib.  @option{--compress-debug-sections=none} doesn't
+compress DWARF debug sections.  @option{--compress-debug-sections=zlib}
+and @option{--compress-debug-sections=zlib-gnu} compress DWARF debug
+sections and rename debug section names to begin with @samp{.zdebug}
+instead of @samp{.debug}.  @option{--compress-debug-sections=zlib-gabi}
+compresses DWARF debug sections with SHF_COMPRESSED from the ELF ABI.
+
 @kindex --reduce-memory-overheads
 @item --reduce-memory-overheads
 This option reduces memory requirements at ld runtime, at the expense of
diff --git a/ld/ldmain.c b/ld/ldmain.c
index 2ecb92d..a7b72bd 100644
--- a/ld/ldmain.c
+++ b/ld/ldmain.c
@@ -425,6 +425,13 @@ main (int argc, char **argv)
   else
     link_info.output_bfd->flags |= EXEC_P;
 
+  if ((link_info.compress_debug & COMPRESS_DEBUG))
+    {
+      link_info.output_bfd->flags |= BFD_COMPRESS;
+      if (link_info.compress_debug == COMPRESS_DEBUG_GABI_ZLIB)
+	link_info.output_bfd->flags |= BFD_COMPRESS_GABI;
+    }
+
   ldwrite ();
 
   if (config.map_file != NULL)
diff --git a/ld/lexsup.c b/ld/lexsup.c
index 4a71ba4..b618241 100644
--- a/ld/lexsup.c
+++ b/ld/lexsup.c
@@ -1722,6 +1722,9 @@ elf_static_list_options (FILE *file)
   fprintf (file, _("\
   --build-id[=STYLE]          Generate build ID note\n"));
   fprintf (file, _("\
+  --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi]\n\
+                              Compress DWARF debug sections using zlib\n"));
+  fprintf (file, _("\
   -z common-page-size=SIZE    Set common page size to SIZE\n"));
   fprintf (file, _("\
   -z max-page-size=SIZE       Set maximum page size to SIZE\n"));
diff --git a/ld/testsuite/ld-elf/compress.exp b/ld/testsuite/ld-elf/compress.exp
index adb7fc2..e2448b9 100644
--- a/ld/testsuite/ld-elf/compress.exp
+++ b/ld/testsuite/ld-elf/compress.exp
@@ -49,7 +49,8 @@ set build_tests {
    "-shared" "-fPIC -g -Wa,--compress-debug-sections"
    {foo.c} {} "libfoo.so"}
   {"Build libbar.so with compressed debug sections"
-   "-shared" "-fPIC -g -Wa,--compress-debug-sections"
+   "-shared -Wl,--compress-debug-sections=none"
+   "-fPIC -g -Wa,--compress-debug-sections"
    {begin.c end.c} {} "libbar.so"}
   {"Build libfoozlib.so with compressed debug sections with zlib-gabi"
    "-shared" "-fPIC -g -Wa,--compress-debug-sections=zlib-gabi"
@@ -57,6 +58,30 @@ set build_tests {
   {"Build libbarzlib.so with compressed debug sections with zlib-gabi"
    "-shared" "-fPIC -g -Wa,--compress-debug-sections=zlib-gabi"
    {begin.c end.c} {} "libbarzlib.so"}
+  {"Build libzlibfoo.so with zlib compressed debug sections"
+   "-shared -Wl,--compress-debug-sections=zlib"
+   "-fPIC -g -Wa,--compress-debug-sections=zlib"
+   {foo.c} {} "libzlibfoo.so"}
+  {"Build libgnufoo.so with zlib-gnu compressed debug sections"
+   "-shared -Wl,--compress-debug-sections=zlib-gnu"
+   "-fPIC -g -Wa,--compress-debug-sections=zlib-gnu"
+   {foo.c} {} "libgnufoo.so"}
+  {"Build libgabifoo.so with zlib-gabi compressed debug sections"
+   "-shared -Wl,--compress-debug-sections=zlib-gabi"
+   "-fPIC -g -Wa,--compress-debug-sections=zlib-gabi"
+   {foo.c} {} "libgabifoo.so"}
+  {"Build zlibbegin.o with zlib compressed debug sections"
+   "-r -nostdlib -Wl,--compress-debug-sections=zlib"
+   "-g -Wa,--compress-debug-sections=zlib"
+   {begin.c} {} "zlibbegin.o"}
+  {"Build gnubegin.o with zlib-gnu compressed debug sections"
+   "-r -nostdlib -Wl,--compress-debug-sections=zlib-gnu"
+   "-g -Wa,--compress-debug-sections=zlib-gnu"
+   {begin.c} {} "gnubegin.o"}
+  {"Build gabiend.o with zlib-gabi compressed debug sections"
+   "-r -nostdlib -Wl,--compress-debug-sections=zlib-gabi"
+   "-g -Wa,--compress-debug-sections=zlib-gnu"
+   {end.c} {} "gabiend.o"}
 }
 
 set run_tests {
@@ -66,6 +91,15 @@ set run_tests {
     {"Run normal with libfoo.so with compressed debug sections with zlib-gabi"
      "tmpdir/begin.o tmpdir/libfoozlib.so tmpdir/end.o" ""
      {main.c} "normal" "normal.out" "-Wa,--compress-debug-sections=zlib-gabi"}
+    {"Run zlibnormal with libzlibfoo.so with zlib compressed debug sections"
+     "tmpdir/begin.o tmpdir/libzlibfoo.so tmpdir/end.o --compress-debug-sections=zlib" ""
+     {main.c} "zlibnormal" "normal.out" "-Wa,--compress-debug-sections=zlib"}
+    {"Run gnunormal with libgnufoo.so with zlib-gnu compressed debug sections"
+     "tmpdir/gnubegin.o tmpdir/libgnufoo.so tmpdir/end.o --compress-debug-sections=zlib-gnu" ""
+     {main.c} "gnunormal" "normal.out" "-Wa,--compress-debug-sections=zlib-gnu"}
+    {"Run gabinormal with libgabifoo.so with zlib-gabi compressed debug sections"
+     "tmpdir/zlibbegin.o tmpdir/libgabifoo.so tmpdir/gabiend.o --compress-debug-sections=zlib-gabi" ""
+     {main.c} "gabinormal" "normal.out" "-Wa,--compress-debug-sections=zlib-gabi"}
 }
 
 run_cc_link_tests $build_tests
@@ -79,3 +113,134 @@ if { [catch {exec cmp tmpdir/libfoo.so tmpdir/libfoozlib.so}] } then {
 } else {
     pass "$test_name"
 }
+
+global READELF
+
+set test_name "Link -r with zlib compressed debug output"
+set test zlibbegin
+send_log "$READELF -S -W tmpdir/$test.o > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -S -W tmpdir/$test.o" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rS] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+
+set test_name "Link -r with zlib-gnu compressed debug output"
+set test gnubegin
+send_log "$READELF -S -W tmpdir/$test.o > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -S -W tmpdir/$test.o" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rS] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+
+set test_name "Link -r with zlib-gabi compressed debug output"
+set test gabiend
+send_log "$READELF -t -W tmpdir/$test.o > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -t -W tmpdir/$test.o" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rt] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+
+set test_name "Link with zlib compressed debug output"
+set test normal
+send_log "$READELF -w tmpdir/$test > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -w tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+
+set test_name "Link with zlib compressed debug output"
+set test zlibnormal
+send_log "$READELF -w tmpdir/$test | sed -e \"s/.zdebug_/.debug_/\" > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -w tmpdir/$test | sed -e \"s/.zdebug_/.debug_/\"" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [catch {exec cmp tmpdir/normal.out tmpdir/$test.out}] } then {
+    send_log "tmpdir/normal.out tmpdir/$test.out differ.\n"
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+send_log "$READELF -S -W tmpdir/$test' > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -S -W tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rS] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+
+set test_name "Link with zlib-gnu compressed debug output"
+set test gnunormal
+send_log "$READELF -w tmpdir/$test | sed -e \"s/.zdebug_/.debug_/\" > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -w tmpdir/$test | sed -e \"s/.zdebug_/.debug_/\"" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [catch {exec cmp tmpdir/normal.out tmpdir/$test.out}] } then {
+    send_log "tmpdir/normal.out tmpdir/$test.out differ.\n"
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+send_log "$READELF -S -W tmpdir/$test' > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -S -W tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rS] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+
+set test gabinormal
+set test_name "Link with zlib-gabi compressed debug output"
+send_log "$READELF -w tmpdir/$test > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -w tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [catch {exec cmp tmpdir/normal.out tmpdir/$test.out}] } then {
+    send_log "tmpdir/normal.out tmpdir/$test.out differ.\n"
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
+send_log "$READELF -t -W tmpdir/$test > tmpdir/$test.out\n"
+set got [remote_exec host "$READELF -t -W tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
+if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
+    send_log "$got\n"
+    unresolved "$test_name"
+}
+if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rt] } then {
+    fail "$test_name"
+} else {
+    pass "$test_name"
+}
diff --git a/ld/testsuite/ld-elf/gabiend.rt b/ld/testsuite/ld-elf/gabiend.rt
new file mode 100644
index 0000000..23bc36c
--- /dev/null
+++ b/ld/testsuite/ld-elf/gabiend.rt
@@ -0,0 +1,4 @@
+#...
+ +\[[0-9a-f]+\]: .*COMPRESSED
+ +ZLIB, [0-9a-f]+, 1
+#pass
diff --git a/ld/testsuite/ld-elf/gabinormal.rt b/ld/testsuite/ld-elf/gabinormal.rt
new file mode 100644
index 0000000..23bc36c
--- /dev/null
+++ b/ld/testsuite/ld-elf/gabinormal.rt
@@ -0,0 +1,4 @@
+#...
+ +\[[0-9a-f]+\]: .*COMPRESSED
+ +ZLIB, [0-9a-f]+, 1
+#pass
diff --git a/ld/testsuite/ld-elf/gnubegin.rS b/ld/testsuite/ld-elf/gnubegin.rS
new file mode 100644
index 0000000..54de24c
--- /dev/null
+++ b/ld/testsuite/ld-elf/gnubegin.rS
@@ -0,0 +1,3 @@
+#...
+ +\[[ 0-9]+\] .zdebug_.* +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +0 +0 +1
+#pass
diff --git a/ld/testsuite/ld-elf/gnunormal.rS b/ld/testsuite/ld-elf/gnunormal.rS
new file mode 100644
index 0000000..54de24c
--- /dev/null
+++ b/ld/testsuite/ld-elf/gnunormal.rS
@@ -0,0 +1,3 @@
+#...
+ +\[[ 0-9]+\] .zdebug_.* +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +0 +0 +1
+#pass
diff --git a/ld/testsuite/ld-elf/zlibbegin.rS b/ld/testsuite/ld-elf/zlibbegin.rS
new file mode 100644
index 0000000..54de24c
--- /dev/null
+++ b/ld/testsuite/ld-elf/zlibbegin.rS
@@ -0,0 +1,3 @@
+#...
+ +\[[ 0-9]+\] .zdebug_.* +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +0 +0 +1
+#pass
diff --git a/ld/testsuite/ld-elf/zlibnormal.rS b/ld/testsuite/ld-elf/zlibnormal.rS
new file mode 100644
index 0000000..54de24c
--- /dev/null
+++ b/ld/testsuite/ld-elf/zlibnormal.rS
@@ -0,0 +1,3 @@
+#...
+ +\[[ 0-9]+\] .zdebug_.* +(PROGBITS|MIPS_DWARF) +0+ +[0-9a-f]+ +[0-9a-f]+ [0-9a-f]+ +0 +0 +1
+#pass
-- 
2.1.0


^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-15  5:07       ` H.J. Lu
@ 2015-04-28 18:57         ` Andreas Schwab
  2015-04-28 19:15           ` H.J. Lu
  2015-04-28 19:26         ` Andreas Schwab
  2015-04-28 19:36         ` Andreas Schwab
  2 siblings, 1 reply; 23+ messages in thread
From: Andreas Schwab @ 2015-04-28 18:57 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

"H.J. Lu" <hjl.tools@gmail.com> writes:

>  ld/testsuite/ld-elf/compress.exp  | 167 +++++++++++++++++++++++++++++++++++++-

gcc  -B/daten/src/binutils/test/ld/tmpdir/ld/ -I/home/andreas/src/binutils/binutils/ld/testsuite/ld-elf -O2 -g   -c -O2 -g -fPIC -g -Wa,--compress-debug-sections=zlib-gabi -c /home/andreas/src/binutils/binutils/ld/testsuite/ld-elf/foo.c -o tmpdir/foo.o
Executing on host: sh -c {gcc  -B/daten/src/binutils/test/ld/tmpdir/ld/ -I/home/andreas/src/binutils/binutils/ld/testsuite/ld-elf -O2 -g   -c -O2 -g -fPIC -g -Wa,--compress-debug-sections=zlib-gabi -c /home/andreas/src/binutils/binutils/ld/testsuite/ld-elf/foo.c -o tmpdir/foo.o 2>&1}  /dev/null ld.tmp (timeout = 300)
spawn [open ...].
/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/as: option '--compress-debug-sections' doesn't allow an argument
/usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/as: option '--compress-debug-sections' doesn't allow an argument

ERROR: /home/andreas/src/binutils/binutils/ld/testsuite/ld-elf/foo.c: compilation failed
gcc -B/daten/src/binutils/test/ld/tmpdir/ld/   -L/usr/x86_64-linux/lib64 -L/usr/lib64 -L/usr/local/lib64 -L/lib64 -L/usr/x86_64-linux/lib -L/usr/local/lib -L/lib -L/usr/lib  -o tmpdir/libfoozlib.so  -L/home/andreas/src/binutils/binutils/ld/testsuite/ld-elf -shared tmpdir/foo.o
Executing on host: sh -c {gcc -B/daten/src/binutils/test/ld/tmpdir/ld/   -L/usr/x86_64-linux/lib64 -L/usr/lib64 -L/usr/local/lib64 -L/lib64 -L/usr/x86_64-linux/lib -L/usr/local/lib -L/lib -L/usr/lib  -o tmpdir/libfoozlib.so  -L/home/andreas/src/binutils/binutils/ld/testsuite/ld-elf -shared tmpdir/foo.o 2>&1}  /dev/null ld.tmp (timeout = 300)
spawn [open ...].
gcc: error: tmpdir/foo.o: No such file or directory
gcc: fatal error: no input files
compilation terminated.
gcc: error: tmpdir/foo.o: No such file or directory
gcc: fatal error: no input files
compilation terminated.
FAIL: Build libfoozlib.so with compressed debug sections with zlib-gabi
FAIL: Build libfoozlib.so with compressed debug sections with zlib-gabi

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-28 18:57         ` Andreas Schwab
@ 2015-04-28 19:15           ` H.J. Lu
  2015-04-28 19:22             ` Andreas Schwab
  0 siblings, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2015-04-28 19:15 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Binutils

On Tue, Apr 28, 2015 at 11:57 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>>  ld/testsuite/ld-elf/compress.exp  | 167 +++++++++++++++++++++++++++++++++++++-
>
> gcc  -B/daten/src/binutils/test/ld/tmpdir/ld/ -I/home/andreas/src/binutils/binutils/ld/testsuite/ld-elf -O2 -g   -c -O2 -g -fPIC -g -Wa,--compress-debug-sections=zlib-gabi -c

There is  -B/daten/src/binutils/test/ld/tmpdir/ld.  Why isn't gcc
picking up the new assembler in /daten/src/binutils/test/ld/tmpdir/ld?

/home/andreas/src/binutils/binutils/ld/testsuite/ld-elf/foo.c -o tmpdir/foo.o
> Executing on host: sh -c {gcc  -B/daten/src/binutils/test/ld/tmpdir/ld/ -I/home/andreas/src/binutils/binutils/ld/testsuite/ld-elf -O2 -g   -c -O2 -g -fPIC -g -Wa,--compress-debug-sections=zlib-gabi -c /home/andreas/src/binutils/binutils/ld/testsuite/ld-elf/foo.c -o tmpdir/foo.o 2>&1}  /dev/null ld.tmp (timeout = 300)
> spawn [open ...].
> /usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/as: option '--compress-debug-sections' doesn't allow an argument
> /usr/lib64/gcc/x86_64-suse-linux/4.8/../../../../x86_64-suse-linux/bin/as: option '--compress-debug-sections' doesn't allow an argument
>
> ERROR: /home/andreas/src/binutils/binutils/ld/testsuite/ld-elf/foo.c: compilation failed
> gcc -B/daten/src/binutils/test/ld/tmpdir/ld/   -L/usr/x86_64-linux/lib64 -L/usr/lib64 -L/usr/local/lib64 -L/lib64 -L/usr/x86_64-linux/lib -L/usr/local/lib -L/lib -L/usr/lib  -o tmpdir/libfoozlib.so  -L/home/andreas/src/binutils/binutils/ld/testsuite/ld-elf -shared tmpdir/foo.o
> Executing on host: sh -c {gcc -B/daten/src/binutils/test/ld/tmpdir/ld/   -L/usr/x86_64-linux/lib64 -L/usr/lib64 -L/usr/local/lib64 -L/lib64 -L/usr/x86_64-linux/lib -L/usr/local/lib -L/lib -L/usr/lib  -o tmpdir/libfoozlib.so  -L/home/andreas/src/binutils/binutils/ld/testsuite/ld-elf -shared tmpdir/foo.o 2>&1}  /dev/null ld.tmp (timeout = 300)
> spawn [open ...].
> gcc: error: tmpdir/foo.o: No such file or directory
> gcc: fatal error: no input files
> compilation terminated.
> gcc: error: tmpdir/foo.o: No such file or directory
> gcc: fatal error: no input files
> compilation terminated.
> FAIL: Build libfoozlib.so with compressed debug sections with zlib-gabi
> FAIL: Build libfoozlib.so with compressed debug sections with zlib-gabi
>
> Andreas.
>
> --
> Andreas Schwab, schwab@linux-m68k.org
> GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
> "And now for something completely different."



-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-28 19:15           ` H.J. Lu
@ 2015-04-28 19:22             ` Andreas Schwab
  2015-04-28 19:25               ` H.J. Lu
  0 siblings, 1 reply; 23+ messages in thread
From: Andreas Schwab @ 2015-04-28 19:22 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

"H.J. Lu" <hjl.tools@gmail.com> writes:

> On Tue, Apr 28, 2015 at 11:57 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
>> "H.J. Lu" <hjl.tools@gmail.com> writes:
>>
>>>  ld/testsuite/ld-elf/compress.exp  | 167 +++++++++++++++++++++++++++++++++++++-
>>
>> gcc  -B/daten/src/binutils/test/ld/tmpdir/ld/ -I/home/andreas/src/binutils/binutils/ld/testsuite/ld-elf -O2 -g   -c -O2 -g -fPIC -g -Wa,--compress-debug-sections=zlib-gabi -c
>
> There is  -B/daten/src/binutils/test/ld/tmpdir/ld.  Why isn't gcc
> picking up the new assembler in /daten/src/binutils/test/ld/tmpdir/ld?

Because an incremental build didn't create the link.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-28 19:22             ` Andreas Schwab
@ 2015-04-28 19:25               ` H.J. Lu
  2015-04-28 19:46                 ` Andreas Schwab
  0 siblings, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2015-04-28 19:25 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Binutils

On Tue, Apr 28, 2015 at 12:22 PM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>> On Tue, Apr 28, 2015 at 11:57 AM, Andreas Schwab <schwab@linux-m68k.org> wrote:
>>> "H.J. Lu" <hjl.tools@gmail.com> writes:
>>>
>>>>  ld/testsuite/ld-elf/compress.exp  | 167 +++++++++++++++++++++++++++++++++++++-
>>>
>>> gcc  -B/daten/src/binutils/test/ld/tmpdir/ld/ -I/home/andreas/src/binutils/binutils/ld/testsuite/ld-elf -O2 -g   -c -O2 -g -fPIC -g -Wa,--compress-debug-sections=zlib-gabi -c
>>
>> There is  -B/daten/src/binutils/test/ld/tmpdir/ld.  Why isn't gcc
>> picking up the new assembler in /daten/src/binutils/test/ld/tmpdir/ld?
>
> Because an incremental build didn't create the link.
>

So a fresh build works?

-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-15  5:07       ` H.J. Lu
  2015-04-28 18:57         ` Andreas Schwab
@ 2015-04-28 19:26         ` Andreas Schwab
  2015-04-28 19:29           ` H.J. Lu
  2015-04-28 19:36         ` Andreas Schwab
  2 siblings, 1 reply; 23+ messages in thread
From: Andreas Schwab @ 2015-04-28 19:26 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

"H.J. Lu" <hjl.tools@gmail.com> writes:

> +set test gabinormal
> +set test_name "Link with zlib-gabi compressed debug output"
> +send_log "$READELF -w tmpdir/$test > tmpdir/$test.out\n"
> +set got [remote_exec host "$READELF -w tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
> +if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
> +    send_log "$got\n"
> +    unresolved "$test_name"
> +}
> +if { [catch {exec cmp tmpdir/normal.out tmpdir/$test.out}] } then {
> +    send_log "tmpdir/normal.out tmpdir/$test.out differ.\n"
> +    fail "$test_name"
> +} else {
> +    pass "$test_name"
> +}
> +send_log "$READELF -t -W tmpdir/$test > tmpdir/$test.out\n"
> +set got [remote_exec host "$READELF -t -W tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
> +if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
> +    send_log "$got\n"
> +    unresolved "$test_name"
> +}
> +if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rt] } then {
> +    fail "$test_name"
> +} else {
> +    pass "$test_name"
> +}

  [26] .debug_aranges
       PROGBITS        0000000000000000 001440 000093 00   0   0 16
       [0000000000000800]: COMPRESSED
       ZLIB, 0000000000000180, 16

regexp_diff match failure
regexp "^ +ZLIB, [0-9a-f]+, 1$"
line   "       ZLIB, 0000000000000180, 16"
FAIL: Link with zlib-gabi compressed debug output

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-28 19:26         ` Andreas Schwab
@ 2015-04-28 19:29           ` H.J. Lu
  2015-04-28 19:46             ` Andreas Schwab
  2015-04-29  7:35             ` Andreas Schwab
  0 siblings, 2 replies; 23+ messages in thread
From: H.J. Lu @ 2015-04-28 19:29 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Binutils

On Tue, Apr 28, 2015 at 12:26 PM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>> +set test gabinormal
>> +set test_name "Link with zlib-gabi compressed debug output"
>> +send_log "$READELF -w tmpdir/$test > tmpdir/$test.out\n"
>> +set got [remote_exec host "$READELF -w tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
>> +if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
>> +    send_log "$got\n"
>> +    unresolved "$test_name"
>> +}
>> +if { [catch {exec cmp tmpdir/normal.out tmpdir/$test.out}] } then {
>> +    send_log "tmpdir/normal.out tmpdir/$test.out differ.\n"
>> +    fail "$test_name"
>> +} else {
>> +    pass "$test_name"
>> +}
>> +send_log "$READELF -t -W tmpdir/$test > tmpdir/$test.out\n"
>> +set got [remote_exec host "$READELF -t -W tmpdir/$test" "" "/dev/null" "tmpdir/$test.out"]
>> +if { [lindex $got 0] != 0 || ![string match "" [lindex $got 1]] } then {
>> +    send_log "$got\n"
>> +    unresolved "$test_name"
>> +}
>> +if { [regexp_diff tmpdir/$test.out $srcdir/$subdir/$test.rt] } then {
>> +    fail "$test_name"
>> +} else {
>> +    pass "$test_name"
>> +}
>
>   [26] .debug_aranges
>        PROGBITS        0000000000000000 001440 000093 00   0   0 16
>        [0000000000000800]: COMPRESSED
>        ZLIB, 0000000000000180, 16
>
> regexp_diff match failure
> regexp "^ +ZLIB, [0-9a-f]+, 1$"
> line   "       ZLIB, 0000000000000180, 16"
> FAIL: Link with zlib-gabi compressed debug output
>

Which target requires 16-byte alignment on .debug_aranges section?


-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-15  5:07       ` H.J. Lu
  2015-04-28 18:57         ` Andreas Schwab
  2015-04-28 19:26         ` Andreas Schwab
@ 2015-04-28 19:36         ` Andreas Schwab
  2015-04-28 19:43           ` H.J. Lu
  2 siblings, 1 reply; 23+ messages in thread
From: Andreas Schwab @ 2015-04-28 19:36 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

tmpdir/normal.out tmpdir/gnunormal.out differ.
FAIL: Link with zlib-gnu compressed debug output

--- tmpdir/normal.out	2015-04-28 21:33:33.668537097 +0200
+++ tmpdir/gnunormal.out	2015-04-28 21:33:57.804523964 +0200
@@ -136,7 +136,7 @@ Contents of the .debug_aranges section:
   Segment Size:             0
 
     Address            Length
-    00000000004004e0 0000000000000015 
+    00000000004004d8 0000000000000015 
     00000000004006c4 0000000000000004 
     0000000000000000 0000000000000000 
   Length:                   28
@@ -181,7 +181,7 @@ Contents of the .debug_aranges section:
   Segment Size:             0
 
     Address            Length
-    00000000004004f5 0000000000000005 
+    00000000004004ed 0000000000000005 
     00000000004006c8 0000000000000005 
     0000000000000000 0000000000000000 
 
@@ -1745,14 +1745,14 @@ Raw dump of debug contents of section .d
   1	1	0	0	crti.S
 
  Line Number Statements:
-  [0x000000bd]  Extended opcode 2: set Address to 0x4004e0
+  [0x000000bd]  Extended opcode 2: set Address to 0x4004d8
   [0x000000c8]  Advance Line by 63 to 64
   [0x000000ca]  Copy
-  [0x000000cb]  Special opcode 63: advance Address by 4 to 0x4004e4 and Line by 2 to 66
-  [0x000000cc]  Special opcode 104: advance Address by 7 to 0x4004eb and Line by 1 to 67
-  [0x000000cd]  Special opcode 48: advance Address by 3 to 0x4004ee and Line by 1 to 68
-  [0x000000ce]  Special opcode 34: advance Address by 2 to 0x4004f0 and Line by 1 to 69
-  [0x000000cf]  Advance PC by 5 to 0x4004f5
+  [0x000000cb]  Special opcode 63: advance Address by 4 to 0x4004dc and Line by 2 to 66
+  [0x000000cc]  Special opcode 104: advance Address by 7 to 0x4004e3 and Line by 1 to 67
+  [0x000000cd]  Special opcode 48: advance Address by 3 to 0x4004e6 and Line by 1 to 68
+  [0x000000ce]  Special opcode 34: advance Address by 2 to 0x4004e8 and Line by 1 to 69
+  [0x000000cf]  Advance PC by 5 to 0x4004ed
   [0x000000d1]  Extended opcode 1: End of Sequence
 
   [0x000000d4]  Extended opcode 2: set Address to 0x4006c4
@@ -1986,11 +1986,11 @@ Raw dump of debug contents of section .d
   1	1	0	0	crtn.S
 
  Line Number Statements:
-  [0x0000040f]  Extended opcode 2: set Address to 0x4004f5
+  [0x0000040f]  Extended opcode 2: set Address to 0x4004ed
   [0x0000041a]  Advance Line by 39 to 40
   [0x0000041c]  Copy
-  [0x0000041d]  Special opcode 62: advance Address by 4 to 0x4004f9 and Line by 1 to 41
-  [0x0000041e]  Advance PC by 1 to 0x4004fa
+  [0x0000041d]  Special opcode 62: advance Address by 4 to 0x4004f1 and Line by 1 to 41
+  [0x0000041e]  Advance PC by 1 to 0x4004f2
   [0x00000420]  Extended opcode 1: End of Sequence
 
   [0x00000423]  Extended opcode 2: set Address to 0x4006c8
@@ -2124,7 +2124,7 @@ Contents of the .debug_ranges section:
 
     Offset   Begin    End
     00000000 ffffffffffffffff 0000000000000000 (base address)
-    00000000 00000000004004e0 00000000004004f5 
+    00000000 00000000004004d8 00000000004004ed 
     00000000 00000000004006c4 00000000004006c8 
     00000000 <End of list>
     00000040 0000000000400540 0000000000400555 
@@ -2135,7 +2135,7 @@ Contents of the .debug_ranges section:
     00000060 0000000000400683 00000000004006a6 
     00000060 <End of list>
     000000b0 ffffffffffffffff 0000000000000000 (base address)
-    000000b0 00000000004004f5 00000000004004fa 
+    000000b0 00000000004004ed 00000000004004f2 
     000000b0 00000000004006c8 00000000004006cd 
     000000b0 <End of list>
 

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-28 19:36         ` Andreas Schwab
@ 2015-04-28 19:43           ` H.J. Lu
  0 siblings, 0 replies; 23+ messages in thread
From: H.J. Lu @ 2015-04-28 19:43 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Binutils

On Tue, Apr 28, 2015 at 12:36 PM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> tmpdir/normal.out tmpdir/gnunormal.out differ.
> FAIL: Link with zlib-gnu compressed debug output
>
> --- tmpdir/normal.out   2015-04-28 21:33:33.668537097 +0200
> +++ tmpdir/gnunormal.out        2015-04-28 21:33:57.804523964 +0200
> @@ -136,7 +136,7 @@ Contents of the .debug_aranges section:
>    Segment Size:             0
>
>      Address            Length
> -    00000000004004e0 0000000000000015
> +    00000000004004d8 0000000000000015
>      00000000004006c4 0000000000000004
>      0000000000000000 0000000000000000
>    Length:                   28

Which target is it?

-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-28 19:25               ` H.J. Lu
@ 2015-04-28 19:46                 ` Andreas Schwab
  0 siblings, 0 replies; 23+ messages in thread
From: Andreas Schwab @ 2015-04-28 19:46 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

"H.J. Lu" <hjl.tools@gmail.com> writes:

> So a fresh build works?

Yes, it does.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-28 19:29           ` H.J. Lu
@ 2015-04-28 19:46             ` Andreas Schwab
  2015-04-28 20:00               ` H.J. Lu
  2015-04-29  7:35             ` Andreas Schwab
  1 sibling, 1 reply; 23+ messages in thread
From: Andreas Schwab @ 2015-04-28 19:46 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

"H.J. Lu" <hjl.tools@gmail.com> writes:

> Which target requires 16-byte alignment on .debug_aranges section?

../binutils/configure '--prefix=/usr' '--build=x86_64-linux' '--enable-shared' '--enable-targets=aarch64-suse-linux,alpha-suse-linux,armv5l-suse-linux,armv7l-suse-linux,armv8l-suse-linux,hppa-suse-linux,hppa64-suse-linux,i686-suse-linux,ia64-suse-linux,m68k-suse-linux,mips-suse-linux,powerpc-suse-linux,powerpc64-suse-linux,s390-suse-linux,s390x-suse-linux,sh4-suse-linux,sparc-suse-linux,sparc64-suse-linux,x86_64-suse-linux,powerpc-macos,powerpc-macos10,spu-elf,x86_64-pep,powerpc64-suse-linux' --with-system-zlib '--disable-ld-targets' '--enable-gold' '--disable-gdb' '--disable-libdecnumber' '--disable-readline' '--disable-sim'

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-28 19:46             ` Andreas Schwab
@ 2015-04-28 20:00               ` H.J. Lu
  2015-04-28 20:21                 ` Andreas Schwab
  0 siblings, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2015-04-28 20:00 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Binutils

On Tue, Apr 28, 2015 at 12:46 PM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>> Which target requires 16-byte alignment on .debug_aranges section?
>
> ../binutils/configure '--prefix=/usr' '--build=x86_64-linux' '--enable-shared' '--enable-targets=aarch64-suse-linux,alpha-suse-linux,armv5l-suse-linux,armv7l-suse-linux,armv8l-suse-linux,hppa-suse-linux,hppa64-suse-linux,i686-suse-linux,ia64-suse-linux,m68k-suse-linux,mips-suse-linux,powerpc-suse-linux,powerpc64-suse-linux,s390-suse-linux,s390x-suse-linux,sh4-suse-linux,sparc-suse-linux,sparc64-suse-linux,x86_64-suse-linux,powerpc-macos,powerpc-macos10,spu-elf,x86_64-pep,powerpc64-suse-linux' --with-system-zlib '--disable-ld-targets' '--enable-gold' '--disable-gdb' '--disable-libdecnumber' '--disable-readline' '--disable-sim'
>

It won't build for me:

configure: error: "unsupported target alpha-suse-linux-gnu"
make[3]: *** [configure-gold] Error 1



-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-28 20:00               ` H.J. Lu
@ 2015-04-28 20:21                 ` Andreas Schwab
  2015-04-28 20:34                   ` H.J. Lu
  0 siblings, 1 reply; 23+ messages in thread
From: Andreas Schwab @ 2015-04-28 20:21 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

"H.J. Lu" <hjl.tools@gmail.com> writes:

> It won't build for me:
>
> configure: error: "unsupported target alpha-suse-linux-gnu"
> make[3]: *** [configure-gold] Error 1

diff --git a/gold/configure.ac b/gold/configure.ac
index 94cae31..6d14e2a 100644
--- a/gold/configure.ac
+++ b/gold/configure.ac
@@ -166,7 +166,11 @@ for targ in $target $canon_targets; do
     . ${srcdir}/configure.tgt
 
     if test "$targ_obj" = "UNKNOWN"; then
-      AC_MSG_ERROR("unsupported target $targ")
+      if test "$targ" = "$target"; then
+        AC_MSG_ERROR("unsupported target $targ")
+      else
+        AC_MSG_WARN("unsupported target $targ")
+      fi
     else
       targetobjs="$targetobjs ${targ_obj}.\$(OBJEXT)"
       if test "$targ_extra_obj" != ""; then

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-28 20:21                 ` Andreas Schwab
@ 2015-04-28 20:34                   ` H.J. Lu
  2015-04-28 20:44                     ` Andreas Schwab
  0 siblings, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2015-04-28 20:34 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Binutils

On Tue, Apr 28, 2015 at 1:21 PM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>> It won't build for me:
>>
>> configure: error: "unsupported target alpha-suse-linux-gnu"
>> make[3]: *** [configure-gold] Error 1
>
> diff --git a/gold/configure.ac b/gold/configure.ac
> index 94cae31..6d14e2a 100644
> --- a/gold/configure.ac
> +++ b/gold/configure.ac
> @@ -166,7 +166,11 @@ for targ in $target $canon_targets; do
>      . ${srcdir}/configure.tgt
>
>      if test "$targ_obj" = "UNKNOWN"; then
> -      AC_MSG_ERROR("unsupported target $targ")
> +      if test "$targ" = "$target"; then
> +        AC_MSG_ERROR("unsupported target $targ")
> +      else
> +        AC_MSG_WARN("unsupported target $targ")
> +      fi
>      else
>        targetobjs="$targetobjs ${targ_obj}.\$(OBJEXT)"
>        if test "$targ_extra_obj" != ""; then
>

How can I reproduce it on an unmodified master branch?


-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-28 20:34                   ` H.J. Lu
@ 2015-04-28 20:44                     ` Andreas Schwab
  2015-04-28 20:45                       ` H.J. Lu
  0 siblings, 1 reply; 23+ messages in thread
From: Andreas Schwab @ 2015-04-28 20:44 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

"H.J. Lu" <hjl.tools@gmail.com> writes:

> How can I reproduce it on an unmodified master branch?

Use openSUSE 13.2.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-28 20:44                     ` Andreas Schwab
@ 2015-04-28 20:45                       ` H.J. Lu
  2015-04-28 20:49                         ` Andreas Schwab
  0 siblings, 1 reply; 23+ messages in thread
From: H.J. Lu @ 2015-04-28 20:45 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Binutils

On Tue, Apr 28, 2015 at 1:44 PM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>> How can I reproduce it on an unmodified master branch?
>
> Use openSUSE 13.2.
>

Can I reproduce it on Fedora 20 or 21?

-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-28 20:45                       ` H.J. Lu
@ 2015-04-28 20:49                         ` Andreas Schwab
  2015-04-28 21:02                           ` H.J. Lu
  0 siblings, 1 reply; 23+ messages in thread
From: Andreas Schwab @ 2015-04-28 20:49 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

"H.J. Lu" <hjl.tools@gmail.com> writes:

> On Tue, Apr 28, 2015 at 1:44 PM, Andreas Schwab <schwab@linux-m68k.org> wrote:
>> "H.J. Lu" <hjl.tools@gmail.com> writes:
>>
>>> How can I reproduce it on an unmodified master branch?
>>
>> Use openSUSE 13.2.
>>
>
> Can I reproduce it on Fedora 20 or 21?

I have no idea.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-28 20:49                         ` Andreas Schwab
@ 2015-04-28 21:02                           ` H.J. Lu
  0 siblings, 0 replies; 23+ messages in thread
From: H.J. Lu @ 2015-04-28 21:02 UTC (permalink / raw)
  To: Andreas Schwab; +Cc: Binutils

On Tue, Apr 28, 2015 at 1:49 PM, Andreas Schwab <schwab@linux-m68k.org> wrote:
> "H.J. Lu" <hjl.tools@gmail.com> writes:
>
>> On Tue, Apr 28, 2015 at 1:44 PM, Andreas Schwab <schwab@linux-m68k.org> wrote:
>>> "H.J. Lu" <hjl.tools@gmail.com> writes:
>>>
>>>> How can I reproduce it on an unmodified master branch?
>>>
>>> Use openSUSE 13.2.
>>>
>>
>> Can I reproduce it on Fedora 20 or 21?
>
> I have no idea.

On Fedora 20/x86-64, I configured binutils with:

--with-sysroot=/ --with-system-zlib --disable-gdb
--disable-libdecnumber --disable-readline --disable-sim
--disable-ld-targets \
--enable-targets=aarch64-suse-linux,alpha-suse-linux,armv5l-suse-linux,armv7l-suse-linux,armv8l-suse-linux,hppa-suse-linux,hppa64-suse-linux,i686-suse-linux,ia64-suse-linux,m68k-suse-linux,mips-suse-linux,powerpc-suse-linux,powerpc64-suse-linux,s390-suse-linux,s390x-suse-linux,sh4-suse-linux,sparc-suse-linux,sparc64-suse-linux,x86_64-suse-linux,powerpc-macos,powerpc-macos10,spu-elf,x86_64-pep,powerpc64-suse-linux
\
--prefix=/usr/local \
--with-local-prefix=/usr/local

"make check'" passed.

-- 
H.J.

^ permalink raw reply	[flat|nested] 23+ messages in thread

* Re: PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld
  2015-04-28 19:29           ` H.J. Lu
  2015-04-28 19:46             ` Andreas Schwab
@ 2015-04-29  7:35             ` Andreas Schwab
  1 sibling, 0 replies; 23+ messages in thread
From: Andreas Schwab @ 2015-04-29  7:35 UTC (permalink / raw)
  To: H.J. Lu; +Cc: Binutils

"H.J. Lu" <hjl.tools@gmail.com> writes:

> Which target requires 16-byte alignment on .debug_aranges section?

There is nothing that forbids 16-byte alignment on debug sections.

Andreas.

-- 
Andreas Schwab, schwab@linux-m68k.org
GPG Key fingerprint = 58CA 54C7 6D53 942B 1756  01D3 44D5 214B 8276 4ED5
"And now for something completely different."

^ permalink raw reply	[flat|nested] 23+ messages in thread

end of thread, other threads:[~2015-04-29  7:35 UTC | newest]

Thread overview: 23+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2015-04-13 12:38 PATCH: Add --compress-debug-sections=[none|zlib|zlib-gnu|zlib-gabi] to ld H.J. Lu
2015-04-15  0:55 ` Alan Modra
2015-04-15  2:44   ` H.J. Lu
2015-04-15  3:58     ` Alan Modra
2015-04-15  5:07       ` H.J. Lu
2015-04-28 18:57         ` Andreas Schwab
2015-04-28 19:15           ` H.J. Lu
2015-04-28 19:22             ` Andreas Schwab
2015-04-28 19:25               ` H.J. Lu
2015-04-28 19:46                 ` Andreas Schwab
2015-04-28 19:26         ` Andreas Schwab
2015-04-28 19:29           ` H.J. Lu
2015-04-28 19:46             ` Andreas Schwab
2015-04-28 20:00               ` H.J. Lu
2015-04-28 20:21                 ` Andreas Schwab
2015-04-28 20:34                   ` H.J. Lu
2015-04-28 20:44                     ` Andreas Schwab
2015-04-28 20:45                       ` H.J. Lu
2015-04-28 20:49                         ` Andreas Schwab
2015-04-28 21:02                           ` H.J. Lu
2015-04-29  7:35             ` Andreas Schwab
2015-04-28 19:36         ` Andreas Schwab
2015-04-28 19:43           ` H.J. Lu

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).