From 0ce398f106dac65c3a1d2f7d254213fa652af089 Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Tue, 14 Apr 2015 22:01:25 -0700 Subject: 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/merge.c | 53 +++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 10 deletions(-) (limited to 'bfd/merge.c') 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; -- cgit v1.1