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