diff options
-rw-r--r-- | gdb/ChangeLog | 17 | ||||
-rwxr-xr-x | gdb/contrib/cc-with-tweaks.sh | 9 | ||||
-rw-r--r-- | gdb/gdb_bfd.c | 184 | ||||
-rw-r--r-- | gdb/osabi.c | 29 | ||||
-rw-r--r-- | gdb/python/py-auto-load.c | 23 | ||||
-rw-r--r-- | gdb/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gdb/testsuite/gdb.base/comprdebug.exp | 46 | ||||
-rw-r--r-- | gdb/xcoffread.c | 8 |
8 files changed, 153 insertions, 167 deletions
diff --git a/gdb/ChangeLog b/gdb/ChangeLog index 64f0dd8..a099c37 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,5 +1,22 @@ 2012-11-08 Tom Tromey <tromey@redhat.com> + PR gdb/14704: + * gdb_bfd.c (gdb_bfd_ref): Set BFD_DECOMPRESS. + (zlib_decompress_section): Remove. + (gdb_bfd_map_section): Only check for compressed section + in mmap case. Use bfd_get_full_section_contents. + * osabi.c (check_note): Add 'sectsize' argument. Read + section data. + (generic_elf_osabi_sniff_abi_tag_sections): Don't read + section data. Update for check_note change. + * xcoffread.c (xcoff_initial_scan): Use + bfd_get_full_section_contents. + * py-auto-load.c (auto_load_section_scripts): Use + bfd_get_full_section_contents. + * contrib/cc-with-tweaks.sh: Add -Z option. + +2012-11-08 Tom Tromey <tromey@redhat.com> + * python/py-bpevent.c: Include defs.h. * python/py-continueevent.c: Include defs.h. * python/py-event.c: Include defs.h. diff --git a/gdb/contrib/cc-with-tweaks.sh b/gdb/contrib/cc-with-tweaks.sh index ccc9c5a..fbb2b88 100755 --- a/gdb/contrib/cc-with-tweaks.sh +++ b/gdb/contrib/cc-with-tweaks.sh @@ -36,6 +36,7 @@ # (More documentation is to come.) # ARGS determine what is done. They can be: +# -Z invoke objcopy --compress-debug-sections # -z compress using dwz # -m compress using dwz -m # -i make an index @@ -74,9 +75,11 @@ want_index=false want_dwz=false want_multi=false want_dwp=false +want_objcopy_compress=false while [ $# -gt 0 ]; do case "$1" in + -Z) want_objcopy_compress=true ;; -z) want_dwz=true ;; -i) want_index=true ;; -m) want_multi=true ;; @@ -138,6 +141,12 @@ then exit 1 fi +if [ "$want_objcopy_compress" = true ]; then + $OBJCOPY --compress-debug-sections "$output_file" + rc=$? + [ $rc != 0 ] && exit $rc +fi + if [ "$want_index" = true ]; then $GDB --batch-silent -nx -ex "set auto-load no" -ex "file $output_file" -ex "save gdb-index $output_dir" rc=$? diff --git a/gdb/gdb_bfd.c b/gdb/gdb_bfd.c index a346cfb..2bcc4b4 100644 --- a/gdb/gdb_bfd.c +++ b/gdb/gdb_bfd.c @@ -258,6 +258,9 @@ gdb_bfd_ref (struct bfd *abfd) return; } + /* Ask BFD to decompress sections in bfd_get_full_section_contents. */ + abfd->flags |= BFD_DECOMPRESS; + gdata = bfd_zalloc (abfd, sizeof (struct gdb_bfd_data)); gdata->refc = 1; gdata->mtime = bfd_get_mtime (abfd); @@ -337,98 +340,6 @@ get_section_descriptor (asection *section) return result; } -/* Decompress a section that was compressed using zlib. Store the - decompressed buffer, and its size, in DESCRIPTOR. */ - -static void -zlib_decompress_section (asection *sectp, - struct gdb_bfd_section_data *descriptor) -{ - bfd *abfd = sectp->owner; -#ifndef HAVE_ZLIB_H - error (_("Support for zlib-compressed data (from '%s', section '%s') " - "is disabled in this copy of GDB"), - bfd_get_filename (abfd), - bfd_get_section_name (abfd, sectp)); -#else - bfd_size_type compressed_size = bfd_get_section_size (sectp); - gdb_byte *compressed_buffer = xmalloc (compressed_size); - struct cleanup *cleanup = make_cleanup (xfree, compressed_buffer); - struct cleanup *inner_cleanup; - bfd_size_type uncompressed_size; - gdb_byte *uncompressed_buffer; - z_stream strm; - int rc; - int header_size = 12; - - if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0 - || bfd_bread (compressed_buffer, - compressed_size, abfd) != compressed_size) - error (_("can't read data from '%s', section '%s'"), - bfd_get_filename (abfd), - bfd_get_section_name (abfd, sectp)); - - /* Read the zlib header. In this case, it should be "ZLIB" followed - by the uncompressed section size, 8 bytes in big-endian order. */ - if (compressed_size < header_size - || strncmp (compressed_buffer, "ZLIB", 4) != 0) - error (_("corrupt ZLIB header from '%s', section '%s'"), - bfd_get_filename (abfd), - bfd_get_section_name (abfd, sectp)); - uncompressed_size = compressed_buffer[4]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[5]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[6]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[7]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[8]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[9]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[10]; uncompressed_size <<= 8; - uncompressed_size += compressed_buffer[11]; - - /* It is possible the section consists of several compressed - buffers concatenated together, so we uncompress in a loop. */ - strm.zalloc = NULL; - strm.zfree = NULL; - strm.opaque = NULL; - strm.avail_in = compressed_size - header_size; - strm.next_in = (Bytef*) compressed_buffer + header_size; - strm.avail_out = uncompressed_size; - uncompressed_buffer = xmalloc (uncompressed_size); - inner_cleanup = make_cleanup (xfree, uncompressed_buffer); - rc = inflateInit (&strm); - while (strm.avail_in > 0) - { - if (rc != Z_OK) - error (_("setting up uncompression in '%s', section '%s': %d"), - bfd_get_filename (abfd), - bfd_get_section_name (abfd, sectp), - rc); - strm.next_out = ((Bytef*) uncompressed_buffer - + (uncompressed_size - strm.avail_out)); - rc = inflate (&strm, Z_FINISH); - if (rc != Z_STREAM_END) - error (_("zlib error uncompressing from '%s', section '%s': %d"), - bfd_get_filename (abfd), - bfd_get_section_name (abfd, sectp), - rc); - rc = inflateReset (&strm); - } - rc = inflateEnd (&strm); - if (rc != Z_OK - || strm.avail_out != 0) - error (_("concluding uncompression in '%s', section '%s': %d"), - bfd_get_filename (abfd), - bfd_get_section_name (abfd, sectp), - rc); - - discard_cleanups (inner_cleanup); - do_cleanups (cleanup); - - /* Attach the data to the BFD section. */ - descriptor->data = uncompressed_buffer; - descriptor->size = uncompressed_size; -#endif -} - /* See gdb_bfd.h. */ const gdb_byte * @@ -437,6 +348,7 @@ gdb_bfd_map_section (asection *sectp, bfd_size_type *size) bfd *abfd; unsigned char header[4]; struct gdb_bfd_section_data *descriptor; + bfd_byte *data; gdb_assert ((sectp->flags & SEC_RELOC) == 0); gdb_assert (size != NULL); @@ -449,67 +361,53 @@ gdb_bfd_map_section (asection *sectp, bfd_size_type *size) if (descriptor->data != NULL) goto done; - /* Check if the file has a 4-byte header indicating compression. */ - if (bfd_get_section_size (sectp) > sizeof (header) - && bfd_seek (abfd, sectp->filepos, SEEK_SET) == 0 - && bfd_bread (header, sizeof (header), abfd) == sizeof (header)) +#ifdef HAVE_MMAP + if (!bfd_is_section_compressed (abfd, sectp)) { - /* Upon decompression, update the buffer and its size. */ - if (strncmp (header, "ZLIB", sizeof (header)) == 0) - { - zlib_decompress_section (sectp, descriptor); - goto done; - } - } + /* The page size, used when mmapping. */ + static int pagesize; -#ifdef HAVE_MMAP - { - /* The page size, used when mmapping. */ - static int pagesize; - - if (pagesize == 0) - pagesize = getpagesize (); - - /* Only try to mmap sections which are large enough: we don't want - to waste space due to fragmentation. */ - - if (bfd_get_section_size (sectp) > 4 * pagesize) - { - descriptor->size = bfd_get_section_size (sectp); - descriptor->data = bfd_mmap (abfd, 0, descriptor->size, PROT_READ, - MAP_PRIVATE, sectp->filepos, - &descriptor->map_addr, - &descriptor->map_len); - - if ((caddr_t)descriptor->data != MAP_FAILED) - { + if (pagesize == 0) + pagesize = getpagesize (); + + /* Only try to mmap sections which are large enough: we don't want + to waste space due to fragmentation. */ + + if (bfd_get_section_size (sectp) > 4 * pagesize) + { + descriptor->size = bfd_get_section_size (sectp); + descriptor->data = bfd_mmap (abfd, 0, descriptor->size, PROT_READ, + MAP_PRIVATE, sectp->filepos, + &descriptor->map_addr, + &descriptor->map_len); + + if ((caddr_t)descriptor->data != MAP_FAILED) + { #if HAVE_POSIX_MADVISE - posix_madvise (descriptor->map_addr, descriptor->map_len, - POSIX_MADV_WILLNEED); + posix_madvise (descriptor->map_addr, descriptor->map_len, + POSIX_MADV_WILLNEED); #endif - goto done; - } + goto done; + } - /* On failure, clear out the section data and try again. */ - memset (descriptor, 0, sizeof (*descriptor)); - } - } + /* On failure, clear out the section data and try again. */ + memset (descriptor, 0, sizeof (*descriptor)); + } + } #endif /* HAVE_MMAP */ - /* If we get here, we are a normal, not-compressed section. */ + /* Handle compressed sections, or ordinary uncompressed sections in + the no-mmap case. */ descriptor->size = bfd_get_section_size (sectp); - descriptor->data = xmalloc (descriptor->size); + descriptor->data = NULL; - if (bfd_seek (abfd, sectp->filepos, SEEK_SET) != 0 - || bfd_bread (descriptor->data, bfd_get_section_size (sectp), - abfd) != bfd_get_section_size (sectp)) - { - xfree (descriptor->data); - descriptor->data = NULL; - error (_("Can't read data for section '%s'"), - bfd_get_filename (abfd)); - } + data = NULL; + if (!bfd_get_full_section_contents (abfd, sectp, &data)) + error (_("Can't read data for section '%s' in file '%s'"), + bfd_get_section_name (abfd, sectp), + bfd_get_filename (abfd)); + descriptor->data = data; done: gdb_assert (descriptor->data != NULL); diff --git a/gdb/osabi.c b/gdb/osabi.c index faffe30..7f60984 100644 --- a/gdb/osabi.c +++ b/gdb/osabi.c @@ -370,14 +370,23 @@ gdbarch_init_osabi (struct gdbarch_info info, struct gdbarch *gdbarch) /* Limit on the amount of data to be read. */ #define MAX_NOTESZ 128 -/* Return non-zero if NOTE matches NAME, DESCSZ and TYPE. */ +/* Return non-zero if NOTE matches NAME, DESCSZ and TYPE. If + *SECTSIZE is non-zero, then this reads that many bytes from + the start of the section and clears *SECTSIZE. */ static int -check_note (bfd *abfd, asection *sect, const char *note, +check_note (bfd *abfd, asection *sect, char *note, unsigned int *sectsize, const char *name, unsigned long descsz, unsigned long type) { unsigned long notesz; + if (*sectsize) + { + if (!bfd_get_section_contents (abfd, sect, note, 0, *sectsize)) + return 0; + *sectsize = 0; + } + /* Calculate the size of this note. */ notesz = strlen (name) + 1; notesz = ((notesz + 3) & ~3); @@ -424,14 +433,18 @@ generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj) if (sectsize > MAX_NOTESZ) sectsize = MAX_NOTESZ; + /* We lazily read the section data here. Since we use + BFD_DECOMPRESS, we can't use bfd_get_section_contents on a + compressed section. But, since note sections are not compressed, + deferring the reading until we recognize the section avoids any + error. */ note = alloca (sectsize); - bfd_get_section_contents (abfd, sect, note, 0, sectsize); /* .note.ABI-tag notes, used by GNU/Linux and FreeBSD. */ if (strcmp (name, ".note.ABI-tag") == 0) { /* GNU. */ - if (check_note (abfd, sect, note, "GNU", 16, NT_GNU_ABI_TAG)) + if (check_note (abfd, sect, note, §size, "GNU", 16, NT_GNU_ABI_TAG)) { unsigned int abi_tag = bfd_h_get_32 (abfd, note + 16); @@ -467,7 +480,8 @@ generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj) } /* FreeBSD. */ - if (check_note (abfd, sect, note, "FreeBSD", 4, NT_FREEBSD_ABI_TAG)) + if (check_note (abfd, sect, note, §size, "FreeBSD", 4, + NT_FREEBSD_ABI_TAG)) { /* There is no need to check the version yet. */ *osabi = GDB_OSABI_FREEBSD_ELF; @@ -479,7 +493,7 @@ generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj) /* .note.netbsd.ident notes, used by NetBSD. */ if (strcmp (name, ".note.netbsd.ident") == 0 - && check_note (abfd, sect, note, "NetBSD", 4, NT_NETBSD_IDENT)) + && check_note (abfd, sect, note, §size, "NetBSD", 4, NT_NETBSD_IDENT)) { /* There is no need to check the version yet. */ *osabi = GDB_OSABI_NETBSD_ELF; @@ -488,7 +502,8 @@ generic_elf_osabi_sniff_abi_tag_sections (bfd *abfd, asection *sect, void *obj) /* .note.openbsd.ident notes, used by OpenBSD. */ if (strcmp (name, ".note.openbsd.ident") == 0 - && check_note (abfd, sect, note, "OpenBSD", 4, NT_OPENBSD_IDENT)) + && check_note (abfd, sect, note, §size, "OpenBSD", 4, + NT_OPENBSD_IDENT)) { /* There is no need to check the version yet. */ *osabi = GDB_OSABI_OPENBSD_ELF; diff --git a/gdb/python/py-auto-load.c b/gdb/python/py-auto-load.c index a018f5f..91bb34d 100644 --- a/gdb/python/py-auto-load.c +++ b/gdb/python/py-auto-load.c @@ -197,26 +197,25 @@ auto_load_section_scripts (struct objfile *objfile, const char *section_name) { bfd *abfd = objfile->obfd; asection *scripts_sect; - bfd_size_type size; - char *p; - struct cleanup *cleanups; + bfd_byte *data = NULL; scripts_sect = bfd_get_section_by_name (abfd, section_name); if (scripts_sect == NULL) return; - size = bfd_get_section_size (scripts_sect); - p = xmalloc (size); - - cleanups = make_cleanup (xfree, p); - - if (bfd_get_section_contents (abfd, scripts_sect, p, (file_ptr) 0, size)) - source_section_scripts (objfile, section_name, p, p + size); - else + if (!bfd_get_full_section_contents (abfd, scripts_sect, &data)) warning (_("Couldn't read %s section of %s"), section_name, bfd_get_filename (abfd)); + else + { + struct cleanup *cleanups; + char *p = (char *) data; - do_cleanups (cleanups); + cleanups = make_cleanup (xfree, p); + source_section_scripts (objfile, section_name, p, + p + bfd_get_section_size (scripts_sect)); + do_cleanups (cleanups); + } } /* Load any Python auto-loaded scripts for OBJFILE. */ diff --git a/gdb/testsuite/ChangeLog b/gdb/testsuite/ChangeLog index 5147182..689cbd4 100644 --- a/gdb/testsuite/ChangeLog +++ b/gdb/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2012-11-08 Tom Tromey <tromey@redhat.com> + + * gdb.base/comprdebug.exp: New file. + 2012-11-06 Pedro Alves <palves@redhat.com> PR gdb/14810 diff --git a/gdb/testsuite/gdb.base/comprdebug.exp b/gdb/testsuite/gdb.base/comprdebug.exp new file mode 100644 index 0000000..65005bd --- /dev/null +++ b/gdb/testsuite/gdb.base/comprdebug.exp @@ -0,0 +1,46 @@ +# Copyright 2012 Free Software Foundation, Inc. + +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see <http://www.gnu.org/licenses/>. + +standard_testfile average.c + +set ofile "${binfile}0.o" +if {[gdb_compile $srcdir/$subdir/$srcfile $ofile \ + object {debug}] != ""} { + untested comprdebug.exp + return +} + +set objcopy_program [transform objcopy] +set cmd "$objcopy_program --compress-debug-sections $ofile" +verbose "invoking $cmd" +set result [catch "exec $cmd" output] +verbose "result is $result" +verbose "output is $output" + +if {$result == 1} { + untested comprdebug.exp + return +} + +gdb_exit +gdb_start +gdb_reinitialize_dir $srcdir/$subdir +set testname "file [file tail $ofile]" +if {[gdb_file_cmd $ofile] == 0} { + pass $testname +} else { + fail $testname +} + diff --git a/gdb/xcoffread.c b/gdb/xcoffread.c index af93a43..e4d0861 100644 --- a/gdb/xcoffread.c +++ b/gdb/xcoffread.c @@ -2989,7 +2989,7 @@ xcoff_initial_scan (struct objfile *objfile, int symfile_flags) { struct bfd_section *secp; bfd_size_type length; - char *debugsec = NULL; + bfd_byte *debugsec = NULL; secp = bfd_get_section_by_name (abfd, ".debug"); if (secp) @@ -2997,11 +2997,9 @@ xcoff_initial_scan (struct objfile *objfile, int symfile_flags) length = bfd_section_size (abfd, secp); if (length) { - debugsec = - (char *) obstack_alloc (&objfile->objfile_obstack, length); + debugsec = obstack_alloc (&objfile->objfile_obstack, length); - if (!bfd_get_section_contents (abfd, secp, debugsec, - (file_ptr) 0, length)) + if (!bfd_get_full_section_contents (abfd, secp, &debugsec)) { error (_("Error reading .debug section of `%s': %s"), name, bfd_errmsg (bfd_get_error ())); |