This is the mail archive of the gdb-patches@sourceware.org mailing list for the GDB project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: RFA: handle "MiniDebuginfo" section


>>>>> "Tom" == Tom Tromey <tromey@redhat.com> writes:

Tom> Fedora recently approved and committed the "MiniDebuginfo" feature:
Tom>     http://fedoraproject.org/wiki/Features/MiniDebugInfo

Here is a new version of the patch.

I think I've addressed all the review comments.

The new LZMA-using code is now in a new file.  I made the new code not
be ELF-specific; instead it is a general fallback implemented in
symfile.c.  I added a warning in the case where the new section is
available and would be used, but can't be since LZMA wasn't compiled in.
I renamed the test file since I think it isn't DWARF-specific.

Tom

2012-11-12  Alexander Larsson  <alexl@redhat.com>
	    Jan Kratochvil  <jan.kratochvil@redhat.com>
	    Tom Tromey  <tromey@redhat.com>

	* NEWS: Mention mini debuginfo feature.
	* minidebug.c: New file.
	* configure.ac: Check for lzma.
	* configure, config.in: Rebuild.
	* Makefile.in (LIBLZMA): New variable.
	(CLIBS): Include LIBLZMA.
	(SFILES): Mention minidebug.c.
	(COMMON_OBS): Mention minidebug.o.
	* symfile.c (read_symbols): New function.
	(syms_from_objfile, reread_symbols): Call it.
	* symfile.h (find_separate_debug_file_in_section): Declare.

2012-11-12  Tom Tromey  <tromey@redhat.com>

	* gdb.texinfo (Separate Debug Section): New node.
	(GDB Files): Update.

2012-11-12  Jan Kratochvil  <jan.kratochvil@redhat.com>

	* gdb.base/gnu-debugdata.exp: New file.
	* gdb.base/gnu-debugdata.c: New file.

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 9e7702d..864572c 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -151,6 +151,9 @@ READLINE_CFLAGS = @READLINE_CFLAGS@
 # Where is expat?  This will be empty if expat was not available.
 LIBEXPAT = @LIBEXPAT@
 
+# Where is lzma?  This will be empty if lzma was not available.
+LIBLZMA = @LIBLZMA@
+
 WARN_CFLAGS = @WARN_CFLAGS@
 WERROR_CFLAGS = @WERROR_CFLAGS@
 GDB_WARN_CFLAGS = $(WARN_CFLAGS)
@@ -469,7 +472,7 @@ INTERNAL_LDFLAGS = $(CFLAGS) $(GLOBAL_CFLAGS) $(MH_LDFLAGS) $(LDFLAGS) $(CONFIG_
 # LIBIBERTY appears twice on purpose.
 CLIBS = $(SIM) $(READLINE) $(OPCODES) $(BFD) $(INTL) $(LIBIBERTY) $(LIBDECNUMBER) \
 	$(XM_CLIBS) $(NAT_CLIBS) $(GDBTKLIBS) @LIBS@ @PYTHON_LIBS@ \
-	$(LIBEXPAT) \
+	$(LIBEXPAT) $(LIBLZMA) \
 	$(LIBIBERTY) $(WIN32LIBS) $(LIBGNU)
 CDEPS = $(XM_CDEPS) $(NAT_CDEPS) $(SIM) $(BFD) $(READLINE_DEPS) \
 	$(OPCODES) $(INTL_DEPS) $(LIBIBERTY) $(CONFIG_DEPS) $(LIBGNU)
@@ -714,7 +717,7 @@ SFILES = ada-exp.y ada-lang.c ada-typeprint.c ada-valprint.c ada-tasks.c \
 	inline-frame.c \
 	interps.c \
 	jv-exp.y jv-lang.c jv-valprint.c jv-typeprint.c \
-	language.c linespec.c \
+	language.c linespec.c minidebug.c \
 	m2-exp.y m2-lang.c m2-typeprint.c m2-valprint.c \
 	macrotab.c macroexp.c macrocmd.c macroscope.c main.c maint.c \
 	mdebugread.c memattr.c mem-break.c minsyms.c mipsread.c memory-map.c \
@@ -877,6 +880,7 @@ COMMON_OBS = $(DEPFILES) $(CONFIG_OBS) $(YYOBJ) \
 	filesystem.o \
 	inf-child.o \
 	interps.o \
+	minidebug.o \
 	main.o \
 	macrotab.o macrocmd.o macroexp.o macroscope.o \
 	mi-common.o \
diff --git a/gdb/NEWS b/gdb/NEWS
index 4a1988d..0c84008 100644
--- a/gdb/NEWS
+++ b/gdb/NEWS
@@ -70,6 +70,11 @@ py [command]
      containing the absolute file name when GDB can determine it and source
      has been requested.
 
+* GDB now supports the "mini debuginfo" section, .gnu_debugdata.
+  You must have the LZMA library available when configuring GDB for this
+  feature to be enabled.  For more information, see:
+      http://fedoraproject.org/wiki/Features/MiniDebugInfo
+
 *** Changes in GDB 7.5
 
 * GDB now supports x32 ABI.  Visit <http://sites.google.com/site/x32abi/>
diff --git a/gdb/configure.ac b/gdb/configure.ac
index f0b7df3..c751c2d 100644
--- a/gdb/configure.ac
+++ b/gdb/configure.ac
@@ -2056,6 +2056,27 @@ LIBS=$OLD_LIBS
 # Add any host-specific objects to GDB.
 CONFIG_OBS="${CONFIG_OBS} ${gdb_host_obs}"
 
+# If building on ELF, look for lzma support for embedded compressed debug info.
+if test $gdb_cv_var_elf = yes; then
+  AC_ARG_WITH(lzma,
+    AS_HELP_STRING([--with-lzma], [support lzma compression (auto/yes/no)]),
+    [], [with_lzma=auto])
+  AC_MSG_CHECKING([whether to use lzma])
+  AC_MSG_RESULT([$with_lzma])
+
+  if test "${with_lzma}" != no; then
+    AC_LIB_HAVE_LINKFLAGS([lzma], [], [#include "lzma.h"],
+			  [lzma_index_iter iter;
+			   lzma_index_iter_init (&iter, 0);
+			   lzma_mf_is_supported (LZMA_MF_HC3);])
+    if test "$HAVE_LIBLZMA" != yes; then
+      if test "$with_lzma" = yes; then
+        AC_MSG_ERROR([missing liblzma for --with-lzma])
+      fi
+    fi
+  fi
+fi
+
 LIBGUI="../libgui/src/libgui.a"
 GUI_CFLAGS_X="-I${srcdir}/../libgui/src"
 AC_SUBST(LIBGUI)
diff --git a/gdb/doc/gdb.texinfo b/gdb/doc/gdb.texinfo
index ce5415d..9d03aad 100644
--- a/gdb/doc/gdb.texinfo
+++ b/gdb/doc/gdb.texinfo
@@ -15787,6 +15787,7 @@ program.  To debug a core dump of a previous run, you must also tell
 @menu
 * Files::                       Commands to specify files
 * Separate Debug Files::        Debugging information in separate files
+* Separate Debug Section::      Debugging information in a special section
 * Index Files::                 Index files speed up GDB
 * Symbol Errors::               Errors reading symbol files
 * Data Files::                  GDB data files
@@ -16712,6 +16713,44 @@ gnu_debuglink_crc32 (unsigned long crc,
 @noindent
 This computation does not apply to the ``build ID'' method.
 
+@node Separate Debug Section
+@section Debugging information in a special section
+@cindex separate debug sections
+@cindex @samp{.gnu_debugdata} section
+
+Some systems ship pre-built executables and libraries that have a
+special @samp{.gnu_debugdata} section.  This section holds an
+LZMA-compressed object and is used to supply extra symbols for
+backtraces.  @value{GDBN} has support for this extension.
+
+This section can be easily created using @command{objcopy} and other
+standard utilities:
+
+@smallexample
+# Extract the dynamic symbols from the main binary, there is no need
+# to also have these in the normal symbol table
+nm -D @var{binary} --format=posix --defined-only \
+  | awk '@{ print $1 @}' | sort > dynsyms
+
+# Extract all the text (i.e. function) symbols from the debuginfo .
+nm @var{binary} --format=posix --defined-only \
+  | awk '@{ if ($2 == "T" || $2 == "t") print $1 @}' \
+  | sort > funcsyms
+
+# Keep all the function symbols not already in the dynamic symbol
+# table.
+comm -13 dynsyms funcsyms > keep_symbols
+
+# Copy the full debuginfo, keeping only a minimal set of symbols and
+# removing some unnecessary sections.
+objcopy -S --remove-section .gdb_index --remove-section .comment \
+  --keep-symbols=keep_symbols @var{binary} mini_debuginfo
+
+# Inject the compressed data into the .gnu_debugdata section of the
+# original binary.
+xz mini_debuginfo
+objcopy --add-section .gnu_debugdata=mini_debuginfo.xz @var{binary}
+@end smallexample
 
 @node Index Files
 @section Index Files Speed Up @value{GDBN}
diff --git a/gdb/minidebug.c b/gdb/minidebug.c
new file mode 100644
index 0000000..8e1362f
--- /dev/null
+++ b/gdb/minidebug.c
@@ -0,0 +1,284 @@
+/* Read MiniDebugInfo data from an objfile.
+
+   Copyright (C) 2012 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   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/>.  */
+
+#include "defs.h"
+#include "gdb_bfd.h"
+#include "gdb_string.h"
+#include "symfile.h"
+#include "objfiles.h"
+#include "gdbcore.h"
+
+#ifdef HAVE_LIBLZMA
+
+#include <lzma.h>
+
+/* Allocator function for LZMA.  */
+
+static void *
+alloc_lzma (void *opaque, size_t nmemb, size_t size)
+{
+  return xmalloc (nmemb * size);
+}
+
+/* Free function for LZMA.  */
+
+static void
+free_lzma (void *opaque, void *ptr)
+{
+  xfree (ptr);
+}
+
+/* The allocator object for LZMA.  Note that 'gdb_lzma_allocator'
+   cannot be const due to the lzma library function prototypes.  */
+
+static lzma_allocator gdb_lzma_allocator = { alloc_lzma, free_lzma, NULL };
+
+/* Custom bfd_openr_iovec implementation to read compressed data from
+   a section.  This keeps only the last decompressed block in memory
+   to allow larger data without using to much memory.  */
+
+struct lzma_stream
+{
+  /* Section of input BFD from which we are decoding data.  */
+  asection *section;
+
+  /* lzma library decompression state.  */
+  lzma_index *index;
+
+  /* Currently decoded block.  */
+  bfd_size_type data_start;
+  bfd_size_type data_end;
+  gdb_byte *data;
+};
+
+/* bfd_openr_iovec OPEN_P implementation for
+   find_separate_debug_file_in_section.  OPEN_CLOSURE is 'asection *'
+   of the section to decompress.
+
+   Return 'struct lzma_stream *' must be freed by caller by xfree, together
+   with its INDEX lzma data.  */
+
+static void *
+lzma_open (struct bfd *nbfd, void *open_closure)
+{
+  asection *section = open_closure;
+  bfd_size_type size, offset;
+  lzma_stream_flags options;
+  gdb_byte footer[LZMA_STREAM_HEADER_SIZE];
+  gdb_byte *indexdata;
+  lzma_index *index;
+  int ret;
+  uint64_t memlimit = UINT64_MAX;
+  struct lzma_stream *lstream;
+  size_t pos;
+
+  size = bfd_get_section_size (section);
+  offset = section->filepos + size - LZMA_STREAM_HEADER_SIZE;
+  if (size < LZMA_STREAM_HEADER_SIZE
+      || bfd_seek (section->owner, offset, SEEK_SET) != 0
+      || bfd_bread (footer, LZMA_STREAM_HEADER_SIZE, section->owner)
+         != LZMA_STREAM_HEADER_SIZE
+      || lzma_stream_footer_decode (&options, footer) != LZMA_OK
+      || offset < options.backward_size)
+    {
+      bfd_set_error (bfd_error_wrong_format);
+      return NULL;
+    }
+
+  offset -= options.backward_size;
+  indexdata = xmalloc (options.backward_size);
+  index = NULL;
+  pos = 0;
+  if (bfd_seek (section->owner, offset, SEEK_SET) != 0
+      || bfd_bread (indexdata, options.backward_size, section->owner)
+         != options.backward_size
+      || lzma_index_buffer_decode (&index, &memlimit, &gdb_lzma_allocator,
+				   indexdata, &pos, options.backward_size)
+         != LZMA_OK
+      || lzma_index_size (index) != options.backward_size)
+    {
+      xfree (indexdata);
+      bfd_set_error (bfd_error_wrong_format);
+      return NULL;
+    }
+  xfree (indexdata);
+
+  lstream = xzalloc (sizeof (struct lzma_stream));
+  lstream->section = section;
+  lstream->index = index;
+
+  return lstream;
+}
+
+/* bfd_openr_iovec PREAD_P implementation for
+   find_separate_debug_file_in_section.  Passed STREAM
+   is 'struct lzma_stream *'.  */
+
+static file_ptr
+lzma_pread (struct bfd *nbfd, void *stream, void *buf, file_ptr nbytes,
+	    file_ptr offset)
+{
+  struct lzma_stream *lstream = stream;
+  bfd_size_type chunk_size;
+  lzma_index_iter iter;
+  gdb_byte *compressed, *uncompressed;
+  file_ptr block_offset;
+  lzma_filter filters[LZMA_FILTERS_MAX + 1];
+  lzma_block block;
+  size_t compressed_pos, uncompressed_pos;
+  file_ptr res;
+
+  res = 0;
+  while (nbytes > 0)
+    {
+      if (lstream->data == NULL
+	  || lstream->data_start > offset || offset >= lstream->data_end)
+	{
+	  asection *section = lstream->section;
+
+	  lzma_index_iter_init (&iter, lstream->index);
+	  if (lzma_index_iter_locate (&iter, offset))
+	    break;
+
+	  compressed = xmalloc (iter.block.total_size);
+	  block_offset = section->filepos + iter.block.compressed_file_offset;
+	  if (bfd_seek (section->owner, block_offset, SEEK_SET) != 0
+	      || bfd_bread (compressed, iter.block.total_size, section->owner)
+		 != iter.block.total_size)
+	    {
+	      xfree (compressed);
+	      break;
+	    }
+
+	  uncompressed = xmalloc (iter.block.uncompressed_size);
+
+	  memset (&block, 0, sizeof (block));
+	  block.filters = filters;
+	  block.header_size = lzma_block_header_size_decode (compressed[0]);
+	  if (lzma_block_header_decode (&block, &gdb_lzma_allocator, compressed)
+	      != LZMA_OK)
+	    {
+	      xfree (compressed);
+	      xfree (uncompressed);
+	      break;
+	    }
+
+	  compressed_pos = block.header_size;
+	  uncompressed_pos = 0;
+	  if (lzma_block_buffer_decode (&block, &gdb_lzma_allocator,
+					compressed, &compressed_pos,
+					iter.block.total_size,
+					uncompressed, &uncompressed_pos,
+					iter.block.uncompressed_size)
+	      != LZMA_OK)
+	    {
+	      xfree (compressed);
+	      xfree (uncompressed);
+	      break;
+	    }
+
+	  xfree (compressed);
+
+	  xfree (lstream->data);
+	  lstream->data = uncompressed;
+	  lstream->data_start = iter.block.uncompressed_file_offset;
+	  lstream->data_end = (iter.block.uncompressed_file_offset
+			       + iter.block.uncompressed_size);
+	}
+
+      chunk_size = min (nbytes, lstream->data_end - offset);
+      memcpy (buf, lstream->data + offset - lstream->data_start, chunk_size);
+      buf = (gdb_byte *) buf + chunk_size;
+      offset += chunk_size;
+      nbytes -= chunk_size;
+      res += chunk_size;
+    }
+
+  return res;
+}
+
+/* bfd_openr_iovec CLOSE_P implementation for
+   find_separate_debug_file_in_section.  Passed STREAM
+   is 'struct lzma_stream *'.  */
+
+static int
+lzma_close (struct bfd *nbfd,
+	    void *stream)
+{
+  struct lzma_stream *lstream = stream;
+
+  lzma_index_end (lstream->index, &gdb_lzma_allocator);
+  xfree (lstream->data);
+  xfree (lstream);
+  return 0;
+}
+
+/* bfd_openr_iovec STAT_P implementation for
+   find_separate_debug_file_in_section.  Passed STREAM
+   is 'struct lzma_stream *'.  */
+
+static int
+lzma_stat (struct bfd *abfd,
+	   void *stream,
+	   struct stat *sb)
+{
+  struct lzma_stream *lstream = stream;
+
+  sb->st_size = lzma_index_uncompressed_size (lstream->index);
+  return 0;
+}
+
+#endif /* HAVE_LIBLZMA  */
+
+/* This looks for a xz compressed separate debug info object file embedded
+   in a section called .gnu_debugdata.  See
+   http://fedoraproject.org/wiki/Features/MiniDebugInfo
+   or the "Separate Debug Sections" of the manual for details.
+   If we find one we create a iovec based bfd that decompresses the
+   object data on demand.  If we don't find one, return NULL.  */
+
+bfd *
+find_separate_debug_file_in_section (struct objfile *objfile)
+{
+  asection *section;
+  bfd *abfd;
+
+  section = bfd_get_section_by_name (objfile->obfd, ".gnu_debugdata");
+  if (section == NULL)
+    return NULL;
+
+#ifdef HAVE_LIBLZMA
+  abfd = gdb_bfd_openr_iovec (objfile->name, gnutarget, lzma_open, section,
+			      lzma_pread, lzma_close, lzma_stat);
+  if (abfd == NULL)
+    return NULL;
+
+  if (!bfd_check_format (abfd, bfd_object))
+    {
+      gdb_bfd_unref (abfd);
+      return NULL;
+    }
+#else
+  warning (_("Cannot parse .gnu_debugdata section; LZMA support was "
+	     "disabled at compile time"));
+  abfd = NULL;
+#endif /* !HAVE_LIBLZMA */
+
+  return abfd;
+}
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 55af541..6a2fc89 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -876,6 +876,27 @@ default_symfile_segments (bfd *abfd)
   return data;
 }
 
+/* This is a convenience function to call sym_read for OBJFILE and
+   possibly force the partial symbols to be read.  */
+
+static void
+read_symbols (struct objfile *objfile, int add_flags)
+{
+  (*objfile->sf->sym_read) (objfile, add_flags);
+  if (!objfile_has_partial_symbols (objfile))
+    {
+      bfd *abfd = find_separate_debug_file_in_section (objfile);
+      struct cleanup *cleanup = make_cleanup_bfd_unref (abfd);
+
+      if (abfd != NULL)
+	symbol_file_add_separate (abfd, add_flags, objfile);
+
+      do_cleanups (cleanup);
+    }
+  if ((add_flags & SYMFILE_NO_READ) == 0)
+    require_partial_symbols (objfile, 0);
+}
+
 /* Process a symbol file, as either the main file or as a dynamically
    loaded file.
 
@@ -996,10 +1017,7 @@ syms_from_objfile (struct objfile *objfile,
       init_objfile_sect_indices (objfile);
     }
 
-  (*objfile->sf->sym_read) (objfile, add_flags);
-
-  if ((add_flags & SYMFILE_NO_READ) == 0)
-    require_partial_symbols (objfile, 0);
+  read_symbols (objfile, add_flags);
 
   /* Discard cleanups as symbol reading was successful.  */
 
@@ -2601,14 +2619,9 @@ reread_symbols (void)
 
 	  (*objfile->sf->sym_init) (objfile);
 	  clear_complaints (&symfile_complaints, 1, 1);
-	  /* Do not set flags as this is safe and we don't want to be
-             verbose.  */
-	  (*objfile->sf->sym_read) (objfile, 0);
-	  if ((objfile->flags & OBJF_PSYMTABS_READ) != 0)
-	    {
-	      objfile->flags &= ~OBJF_PSYMTABS_READ;
-	      require_partial_symbols (objfile, 0);
-	    }
+
+	  objfile->flags &= ~OBJF_PSYMTABS_READ;
+	  read_symbols (objfile, 0);
 
 	  if (!objfile_has_symbols (objfile))
 	    {
diff --git a/gdb/symfile.h b/gdb/symfile.h
index bb75c18..223f874 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -690,4 +690,8 @@ extern void elfmdebug_build_psymtabs (struct objfile *,
 				      const struct ecoff_debug_swap *,
 				      asection *);
 
+/* From minidebug.c.  */
+
+extern bfd *find_separate_debug_file_in_section (struct objfile *);
+
 #endif /* !defined(SYMFILE_H) */
diff --git a/gdb/testsuite/gdb.base/gnu-debugdata.c b/gdb/testsuite/gdb.base/gnu-debugdata.c
new file mode 100644
index 0000000..b8b7e8a
--- /dev/null
+++ b/gdb/testsuite/gdb.base/gnu-debugdata.c
@@ -0,0 +1,30 @@
+/* This testcase is part of GDB, the GNU debugger.
+
+   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/>.  */
+
+#include <signal.h>
+
+static int
+debugdata_function (void)
+{
+  return raise (SIGSEGV) + 1;
+}
+
+int
+main (void)
+{
+  return debugdata_function () + 1;
+}
diff --git a/gdb/testsuite/gdb.base/gnu-debugdata.exp b/gdb/testsuite/gdb.base/gnu-debugdata.exp
new file mode 100644
index 0000000..2b304f1
--- /dev/null
+++ b/gdb/testsuite/gdb.base/gnu-debugdata.exp
@@ -0,0 +1,97 @@
+# 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
+
+if {[is_remote host]} {
+    return 0
+}
+
+if [build_executable ${testfile}.exp $testfile] {
+    return -1
+}
+
+proc run { test cmdline } {
+    verbose "cmdline is $cmdline"
+    set result [catch "exec $cmdline" output]
+    verbose "result is $result"
+    verbose "output is $output"
+    if {$result == 0} {
+	pass $test
+	return 0
+    } else {
+	fail $test
+	return -1
+    }
+}
+
+set strip_program [transform strip]
+set nm_program [transform nm]
+
+# Extract the dynamic symbols from the main binary, there is no need
+# to also have these in the normal symbol table.
+file delete -- ${binfile}.dynsyms
+if [run "nm -D" "[transform nm] -D ${binfile} --format=posix --defined-only | awk \\{print\\ \\\$1\\} | sort > ${binfile}.dynsyms"] {
+    return -1
+}
+
+# Extract all the text (i.e. function) symbols from the debuginfo.
+file delete -- ${binfile}.funcsyms
+if [run "nm" "[transform nm] ${binfile} --format=posix --defined-only | awk \\{if(\\\$2==\"T\"||\\\$2==\"t\")print\\ \\\$1\\} | sort > ${binfile}.funcsyms"] {
+    return -1
+}
+
+# Keep all the function symbols not already in the dynamic symbol
+# table.
+file delete -- ${binfile}.keep_symbols
+if [run "comm" "comm -13 ${binfile}.dynsyms ${binfile}.funcsyms > ${binfile}.keep_symbols"] {
+    return -1
+}
+
+# Copy the full debuginfo, keeping only a minimal set of symbols and
+# removing some unnecessary sections.
+file delete -- ${binfile}.mini_debuginfo
+if [run "objcopy 1" "[transform objcopy] -S --remove-section .gdb_index --remove-section .comment --keep-symbols=${binfile}.keep_symbols ${binfile} ${binfile}.mini_debuginfo"] {
+    return -1
+}
+
+# GDB specific - we do not have split executable in advance.
+file delete -- ${binfile}.strip
+if [run "strip" "[transform strip] --strip-all -o ${binfile}.strip ${binfile}"] {
+    return -1
+}
+
+# Inject the compressed data into the .gnu_debugdata section of the
+# original binary.
+file delete -- ${binfile}.mini_debuginfo.xz
+if [run "xz" "xz ${binfile}.mini_debuginfo"] {
+    return -1
+}
+file delete -- ${binfile}.test
+if [run "objcopy 2" "[transform objcopy] --add-section .gnu_debugdata=${binfile}.mini_debuginfo.xz ${binfile}.strip ${binfile}.test"] {
+    return -1
+}
+
+clean_restart "$testfile.strip"
+
+gdb_test "p debugdata_function" \
+    {No symbol table is loaded\.  Use the "file" command\.} \
+    "no symtab"
+
+clean_restart "$testfile.test"
+
+gdb_test "p debugdata_function" \
+    { = {<text variable, no debug info>} 0x[0-9a-f]+ <debugdata_function>} \
+    "have symtab"


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]