Mirror of the gdb-patches mailing list
 help / color / mirror / Atom feed
* RFC: support debug info in separate files
@ 2002-11-25 20:27 Jim Blandy
  2002-11-25 22:34 ` Eli Zaretskii
                   ` (3 more replies)
  0 siblings, 4 replies; 14+ messages in thread
From: Jim Blandy @ 2002-11-25 20:27 UTC (permalink / raw)
  To: gdb-patches


This patch, written by Alexander Larsson, allows GDB to use debug info
that has been extracted into a separate executable file, using the
"strip -f" command as provided in Ulrich Drepper's elfutils.  This
allows a distribution to provide debug info in separate packages from
the executables it describes.

If you've got all the previous patches I've posted (and if I haven't
botched anything), this should cause no test suite regressions, and
the results of running the test suite both with and without separated
debug info are identical.  Starting with current GDB sources, the
other patches you need are:

RFA: testsuite: pass optimization flag in the proper way
RFA: testsuite: attach.exp: don't move executables to /tmp
Re: RFC: allow syms_from_objfile to take a section offset table directly
RFC: Allow symbol_file_add to take section_offsets table

To run the GDB test suite against executables with separated debug info, 
see: http://sources.redhat.com/ml/gdb/2002-11/msg00202.html
and: http://sources.redhat.com/ml/gdb/2002-11/msg00215.html

(Note: there is a bug in the elfutils strip that causes some stripped
executables to crash.  This has been fixed only very recently, so
you'll need a bleeding-edge version of elfutils, or else you'll get
failures in try_catch.exp due to the inferior crashing.)

If folks don't have concerns about this, I'll commit it on Fri Dec 6.

2002-11-25  Alexander Larsson <alexl@redhat.com>
	    Jim Blandy  <jimb@redhat.com>

	Add support for executables whose debug info has been separated
	out into a separate file, leaving only a link behind.
	* objfiles.h (struct objfile): New fields: separate_debug_objfile
	and separate_debug_objfile_backlink.
	(put_objfile_before): New declaration.
	* symfile.c (symbol_file_add_with_addrs_or_offsets): If this
	objfile has its debug info in a separate file, read that,
	too. Save the addrs argument, so we can use it again to read the
	separated debug info; syms_from_objfile modifies the table we pass
	it.
	(reread_symbols): After re-reading an objfile, call
	reread_separate_symbols to refresh its separate debug info
	objfile, if it has one.
	(reread_separate_symbols, find_separate_debug_file,
	get_debug_link_info, separate_debug_file_exists): New functions.
	(debug_file_directory): New global var.
	(_initialize_symfile): Initialize debug_file_directory, and
	provide the new `set debug-file-directory' command to let the user
	change it.
	* objfiles.c (free_objfile): If this objfile has its debug info in
	a separate objfile, free that one too.  If this is itself a
	separate debug info objfile, clear our parent's backlink.
	(put_objfile_before): New function.
	* utils.c (calc_crc32): New function.
	* defs.h (calc_crc32): New declaration.
	* configure.in: Handle --with-separate-debug-dir config option.
	* acinclude.m4 (AC_DEFINE_DIR): New macro.
	* acconfig.h (DEBUGDIR): New macro.
	* configure, aclocal.m4, config.in: Regenerated.

Index: gdb/acconfig.h
===================================================================
RCS file: /cvs/src/src/gdb/acconfig.h,v
retrieving revision 1.18
diff -u -r1.18 acconfig.h
--- gdb/acconfig.h	11 Apr 2002 18:32:51 -0000	1.18
+++ gdb/acconfig.h	26 Nov 2002 03:42:20 -0000
@@ -176,3 +176,7 @@
 
 /* nativefile */
 #undef GDB_NM_FILE
+
+/* debugdir */
+#undef DEBUGDIR
+
Index: gdb/acinclude.m4
===================================================================
RCS file: /cvs/src/src/gdb/acinclude.m4,v
retrieving revision 1.4
diff -u -r1.4 acinclude.m4
--- gdb/acinclude.m4	20 Sep 2002 00:24:01 -0000	1.4
+++ gdb/acinclude.m4	26 Nov 2002 03:42:20 -0000
@@ -1044,3 +1044,18 @@
   fi
   AC_SUBST(LIBICONV)
 ])
+
+dnl written by Guido Draheim <guidod@gmx.de>, original by Alexandre Oliva 
+dnl Version 1.3 (2001/03/02)
+dnl source http://www.gnu.org/software/ac-archive/Miscellaneous/ac_define_dir.html
+
+AC_DEFUN([AC_DEFINE_DIR], [
+  test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+  test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+  ac_define_dir=`eval echo [$]$2`
+  ac_define_dir=`eval echo [$]ac_define_dir`
+  ifelse($3, ,
+    AC_DEFINE_UNQUOTED($1, "$ac_define_dir"),
+    AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3))
+])
+
Index: gdb/configure.in
===================================================================
RCS file: /cvs/src/src/gdb/configure.in,v
retrieving revision 1.93
diff -u -r1.93 configure.in
--- gdb/configure.in	12 Nov 2002 02:39:41 -0000	1.93
+++ gdb/configure.in	26 Nov 2002 03:42:25 -0000
@@ -237,6 +237,14 @@
 AC_CHECK_LIB(socket, socketpair)
 AC_CHECK_FUNCS(socketpair)
 
+debugdir=${libdir}/debug
+	 
+AC_ARG_WITH(separate-debug-dir,
+[  --with-separate-debug-dir=path   Look for global separate debug info in this path [LIBDIR/debug]],
+[debugdir="${withval}"])
+	
+AC_DEFINE_DIR(DEBUGDIR, debugdir)
+#AC_DEFINE_UNQUOTED(DEBUGDIR, "$debugdir"),
 
 BFD_NEED_DECLARATION(malloc)
 BFD_NEED_DECLARATION(realloc)
Index: gdb/defs.h
===================================================================
RCS file: /cvs/src/src/gdb/defs.h,v
retrieving revision 1.102
diff -u -r1.102 defs.h
--- gdb/defs.h	15 Oct 2002 02:16:51 -0000	1.102
+++ gdb/defs.h	26 Nov 2002 03:42:26 -0000
@@ -382,6 +382,9 @@
 extern char *gdb_realpath (const char *);
 extern char *xfullpath (const char *);
 
+extern unsigned long calc_crc32 (unsigned long crc,
+                                 unsigned char *buf, size_t len);
+
 /* From demangle.c */
 
 extern void set_demangling_style (char *);
Index: gdb/objfiles.c
===================================================================
RCS file: /cvs/src/src/gdb/objfiles.c,v
retrieving revision 1.22
diff -u -r1.22 objfiles.c
--- gdb/objfiles.c	29 Jul 2002 22:55:26 -0000	1.22
+++ gdb/objfiles.c	26 Nov 2002 03:42:27 -0000
@@ -333,6 +333,30 @@
   return (objfile);
 }
 
+/* Put one object file before a specified on in the global list.
+   This can be used to make sure an object file is destroyed before
+   another when using ALL_OBJFILES_SAFE to free all objfiles. */
+void
+put_objfile_before (struct objfile *objfile, struct objfile *before_this)
+{
+  struct objfile **objp;
+
+  unlink_objfile (objfile);
+  
+  for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
+    {
+      if (*objp == before_this)
+	{
+	  objfile->next = *objp;
+	  *objp = objfile;
+	  return;
+	}
+    }
+  
+  internal_error (__FILE__, __LINE__,
+		  "put_objfile_before: before objfile not in list");
+}
+
 /* Put OBJFILE at the front of the list.  */
 
 void
@@ -405,6 +429,18 @@
 void
 free_objfile (struct objfile *objfile)
 {
+  if (objfile->separate_debug_objfile)
+    {
+      free_objfile (objfile->separate_debug_objfile);
+    }
+  
+  if (objfile->separate_debug_objfile_backlink)
+    {
+      /* We freed the separate debug file, make sure the base objfile
+	 doesn't reference it.  */
+      objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL;
+    }
+  
   /* First do any symbol file specific actions required when we are
      finished with a particular symbol file.  Note that if the objfile
      is using reusable symbol information (via mmalloc) then each of
Index: gdb/objfiles.h
===================================================================
RCS file: /cvs/src/src/gdb/objfiles.h,v
retrieving revision 1.15
diff -u -r1.15 objfiles.h
--- gdb/objfiles.h	5 Aug 2002 16:17:41 -0000	1.15
+++ gdb/objfiles.h	26 Nov 2002 03:42:27 -0000
@@ -414,6 +414,15 @@
     ExportEntry *export_list;
     int export_list_size;
 
+    /* Link to objfile that contains the debug symbols for this one.
+       One is loaded if this file has an debug link to an existing
+       debug file with the right checksum */
+    struct objfile *separate_debug_objfile;
+
+    /* If this is a separate debug object, this is used as a link to the
+       actual executable objfile. */
+    struct objfile *separate_debug_objfile_backlink;
+    
     /* Place to stash various statistics about this objfile */
       OBJSTATS;
   };
@@ -504,6 +513,8 @@
 extern struct objfile *allocate_objfile (bfd *, int);
 
 extern int build_objfile_section_table (struct objfile *);
+
+extern void put_objfile_before (struct objfile *, struct objfile *);
 
 extern void objfile_to_front (struct objfile *);
 
Index: gdb/symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.74.2.2
diff -u -r1.74.2.2 symfile.c
--- gdb/symfile.c	26 Nov 2002 03:14:15 -0000	1.74.2.2
+++ gdb/symfile.c	26 Nov 2002 03:42:31 -0000
@@ -38,6 +38,7 @@
 #include "complaints.h"
 #include "demangle.h"
 #include "inferior.h"		/* for write_pc */
+#include "filenames.h"		/* for DOSish file names */
 #include "gdb-stabs.h"
 #include "gdb_obstack.h"
 #include "completer.h"
@@ -104,6 +105,8 @@
 
 static void add_shared_symbol_files_command (char *, int);
 
+static void reread_separate_symbols (struct objfile *objfile);
+
 static void cashier_psymtab (struct partial_symtab *);
 
 bfd *symfile_bfd_open (char *);
@@ -148,6 +151,8 @@
 
 static void info_ext_lang_command (char *args, int from_tty);
 
+static char *find_separate_debug_file (struct objfile *objfile);
+
 static void init_filename_language_table (void);
 
 void _initialize_symfile (void);
@@ -887,7 +892,12 @@
 {
   struct objfile *objfile;
   struct partial_symtab *psymtab;
+  char *debugfile;
   bfd *abfd;
+  struct section_addr_info orig_addrs;
+  
+  if (addrs)
+    orig_addrs = *addrs;
 
   /* Open a bfd for the file, and give user a chance to burp if we'd be
      interactively wiping out any existing symbols.  */
@@ -962,6 +972,37 @@
 	}
     }
 
+  debugfile = find_separate_debug_file (objfile);
+  if (debugfile)
+    {
+      if (from_tty || info_verbose)
+        {
+          printf_filtered ("loading separate debug info from '%s'",
+                           debugfile);
+          wrap_here ("");
+          gdb_flush (gdb_stdout);
+        }
+
+      if (addrs != NULL)
+	{
+	  objfile->separate_debug_objfile
+            = symbol_file_add (debugfile, from_tty, &orig_addrs, 0, flags);
+	}
+      else
+	{
+	  objfile->separate_debug_objfile
+            = symbol_file_add (debugfile, from_tty, NULL, 0, flags);
+	}
+      objfile->separate_debug_objfile->separate_debug_objfile_backlink
+        = objfile;
+      
+      /* Put the separate debug object before the normal one, this is so that
+         usage of the ALL_OBJFILES_SAFE macro will stay safe. */
+      put_objfile_before (objfile->separate_debug_objfile, objfile);
+      
+      xfree (debugfile);
+    }
+  
   if (from_tty || info_verbose)
     {
       if (post_add_symbol_hook)
@@ -1057,6 +1098,135 @@
 #endif
 }
 
+static char *
+get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out)
+{
+  asection *sect;
+  bfd_size_type debuglink_size;
+  unsigned long crc32;
+  char *contents;
+  int crc_offset;
+  unsigned char *p;
+  
+  sect = bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink");
+
+  if (sect == NULL)
+    return NULL;
+
+  debuglink_size = bfd_section_size (objfile->obfd, sect);
+  
+  contents = xmalloc (debuglink_size);
+  bfd_get_section_contents (objfile->obfd, sect, contents,
+			    (file_ptr)0, (bfd_size_type)debuglink_size);
+
+  /* Crc value is stored after the filename, aligned up to 4 bytes. */
+  crc_offset = strlen (contents) + 1;
+  crc_offset = (crc_offset + 3) & ~3;
+
+  crc32 = bfd_get_32 (objfile->obfd, (bfd_byte *) (contents + crc_offset));
+  
+  *crc32_out = crc32;
+  return contents;
+}
+
+static int
+separate_debug_file_exists (const char *name, unsigned long crc)
+{
+  unsigned long file_crc = 0;
+  int fd;
+  char buffer[8*1024];
+  int count;
+
+  fd = open (name, O_RDONLY | O_BINARY);
+  if (fd < 0)
+    return 0;
+
+  while ((count = read (fd, buffer, sizeof (buffer))) > 0)
+    file_crc = calc_crc32 (file_crc, buffer, count);
+
+  close (fd);
+
+  return crc == file_crc;
+}
+
+static char *debug_file_directory = NULL;
+
+static char *
+find_separate_debug_file (struct objfile *objfile)
+{
+  asection *sect;
+  char *basename;
+  char *dir;
+  char *debugfile;
+  char *name_copy;
+  bfd_size_type debuglink_size;
+  unsigned long crc32;
+  int i;
+
+  basename = get_debug_link_info (objfile, &crc32);
+
+  if (basename == NULL)
+    return NULL;
+  
+  dir = xstrdup (objfile->name);
+
+  /* Strip off filename part */
+  for (i = strlen(dir) - 1; i >= 0; i--)
+    {
+      if (IS_DIR_SEPARATOR (dir[i]))
+	break;
+    }
+  dir[i+1] = '\0';
+  
+  debugfile = alloca (strlen (debug_file_directory) + 1
+                      + strlen (dir)
+                      + strlen (".debug/")
+                      + strlen (basename) 
+                      + 1);
+
+  /* First try in the same directory as the original file: */
+  strcpy (debugfile, dir);
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (basename);
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  /* Then try in a subdirectory called .debug */
+  strcpy (debugfile, dir);
+  strcat (debugfile, ".debug/");
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (basename);
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  /* Then try in the global debugfile directory */
+  strcpy (debugfile, debug_file_directory);
+  strcat (debugfile, "/");
+  strcat (debugfile, dir);
+  strcat (debugfile, "/");
+  strcat (debugfile, basename);
+
+  if (separate_debug_file_exists (debugfile, crc32))
+    {
+      xfree (basename);
+      xfree (dir);
+      return xstrdup (debugfile);
+    }
+  
+  xfree (basename);
+  xfree (dir);
+  return NULL;
+}
+
+
 /* This is the symbol-file command.  Read the file, analyze its
    symbols, and add a struct symtab to a symtab list.  The syntax of
    the command is rather bizarre--(1) buildargv implements various
@@ -1902,6 +2072,8 @@
 	         needs to keep track of (such as _sigtramp, or whatever).  */
 
 	      TARGET_SYMFILE_POSTREAD (objfile);
+
+              reread_separate_symbols (objfile);
 	    }
 	}
     }
@@ -1909,6 +2081,73 @@
   if (reread_one)
     clear_symtab_users ();
 }
+
+
+/* Handle separate debug info for OBJFILE, which has just been
+   re-read:
+   - If we had separate debug info before, but now we don't, get rid
+     of the separated objfile.
+   - If we didn't have separated debug info before, but now we do,
+     read in the new separated debug info file.
+   - If the debug link points to a different file, toss the old one
+     and read the new one.
+   This function does *not* handle the case where objfile is still
+   using the same separate debug info file, but that file's timestamp
+   has changed.  That case should be handled by the loop in
+   reread_symbols already.  */
+static void
+reread_separate_symbols (struct objfile *objfile)
+{
+  char *debug_file;
+  unsigned long crc32;
+
+  /* Does the updated objfile's debug info live in a
+     separate file?  */
+  debug_file = find_separate_debug_file (objfile);
+
+  if (objfile->separate_debug_objfile)
+    {
+      /* There are two cases where we need to get rid of
+         the old separated debug info objfile:
+         - if the new primary objfile doesn't have
+         separated debug info, or
+         - if the new primary objfile has separate debug
+         info, but it's under a different filename.
+ 
+         If the old and new objfiles both have separate
+         debug info, under the same filename, then we're
+         okay --- if the separated file's contents have
+         changed, we will have caught that when we
+         visited it in this function's outermost
+         loop.  */
+      if (! debug_file
+          || strcmp (debug_file, objfile->separate_debug_objfile->name) != 0)
+        free_objfile (objfile->separate_debug_objfile);
+    }
+
+  /* If the new objfile has separate debug info, and we
+     haven't loaded it already, do so now.  */
+  if (debug_file
+      && ! objfile->separate_debug_objfile)
+    {
+      /* Use the same section offset table as objfile itself.
+         Preserve the flags from objfile that make sense.  */
+      objfile->separate_debug_objfile
+        = (symbol_file_add_with_addrs_or_offsets
+           (debug_file,
+            info_verbose, /* from_tty: Don't override the default. */
+            0, /* No addr table.  */
+            objfile->section_offsets, objfile->num_sections,
+            0, /* Not mainline.  See comments about this above.  */
+            objfile->flags & (OBJF_MAPPED | OBJF_REORDERED
+                              | OBJF_SHARED | OBJF_READNOW
+                              | OBJF_USERLOADED)));
+      objfile->separate_debug_objfile->separate_debug_objfile_backlink
+        = objfile;
+    }
+}
+
+
 \f
 
 
@@ -3417,4 +3656,18 @@
 		  "cache.\n",
 		  &setlist),
      &showlist);
+
+  debug_file_directory = xstrdup (DEBUGDIR);
+  c = (add_set_cmd
+       ("debug-file-directory", class_support, var_string,
+        (char *) &debug_file_directory,
+        "Set the directory where separate debug symbols are searched for.\n"
+        "Separate debug symbols are first searched for in the same\n"
+        "directory as the binary, then in the .debug subdirectory,\n"
+        "and lastly at the path of the directory of the binary with\n"
+        "the global debug-file directory prepended\n",
+        &setlist));
+  add_show_from_set (c, &showlist);
+  set_cmd_completer (c, filename_completer);
+
 }
Index: gdb/utils.c
===================================================================
RCS file: /cvs/src/src/gdb/utils.c,v
retrieving revision 1.85
diff -u -r1.85 utils.c
--- gdb/utils.c	12 Nov 2002 20:26:05 -0000	1.85
+++ gdb/utils.c	26 Nov 2002 03:42:34 -0000
@@ -2810,3 +2810,69 @@
   xfree (real_path);
   return result;
 }
+
+unsigned long
+calc_crc32 (unsigned long crc, unsigned char *buf, size_t len)
+{
+  static const unsigned long crc32_table[256] =
+    {
+      0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+      0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+      0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+      0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+      0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+      0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+      0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+      0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+      0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+      0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+      0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+      0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+      0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+      0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+      0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+      0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+      0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+      0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+      0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+      0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+      0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+      0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+      0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+      0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+      0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+      0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+      0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+      0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+      0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+      0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+      0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+      0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+      0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+      0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+      0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+      0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+      0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+      0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+      0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+      0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+      0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+      0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+      0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+      0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+      0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+      0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+      0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+      0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+      0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+      0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+      0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+      0x2d02ef8d
+    };
+  unsigned char *end;
+
+  crc = ~crc & 0xffffffff;
+  for (end = buf + len; buf < end; ++buf)
+    crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+  return ~crc & 0xffffffff;;
+}
Index: gdb/doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.131
diff -u -r1.131 gdb.texinfo
--- gdb/doc/gdb.texinfo	11 Oct 2002 16:13:15 -0000	1.131
+++ gdb/doc/gdb.texinfo	26 Nov 2002 03:42:46 -0000
@@ -10206,6 +10206,29 @@
 Display the current autoloading size threshold, in megabytes.
 @end table
 
+On @sc{elf} based systems, @value{GDBN} supports automatically loading
+symbol tables and debug information from a file separate from the
+executable.  This works by putting information in the executable about
+the name and checksum of the file with debug information.  When
+@value{GDBN} reads such an executable it automatically tries to locate
+the debug file and load it. 
+
+@value{GDBN} searchs for the file first in the same directory as the
+executable, and then in a subdirectory called @file{.debug}. 
+If both these fail @value{GDBN} looks in the global debug directory, with the
+full pathname of the executable.  So if you are loading
+@file{/usr/bin/ls} and it references the debug file @file{ls.debug}
+@value{GDBN} will look for @file{usr/bin/ls.debug} in the global debug
+directory.
+
+@table @code
+@kindex set debug-file-directory
+@item set debug-file-directory @var{directory}
+Set the global directory where @value{GDBN} searches for separate
+debug files to @var{directory}.
+@end table
+
+
 @node Symbol Errors
 @section Errors reading symbol files
 


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

* Re: RFC: support debug info in separate files
  2002-11-25 20:27 RFC: support debug info in separate files Jim Blandy
@ 2002-11-25 22:34 ` Eli Zaretskii
  2002-12-09 19:55   ` Jim Blandy
  2002-12-09 22:13 ` Elena Zannoni
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 14+ messages in thread
From: Eli Zaretskii @ 2002-11-25 22:34 UTC (permalink / raw)
  To: Jim Blandy; +Cc: gdb-patches


On 25 Nov 2002, Jim Blandy wrote:

> This patch, written by Alexander Larsson, allows GDB to use debug info
> that has been extracted into a separate executable file, using the
> "strip -f" command as provided in Ulrich Drepper's elfutils.

Does that mean this feature is not supported by GNU `strip'?  If so, this 
should be reflected in the docs.

> +  debugfile = alloca (strlen (debug_file_directory) + 1
> +                      + strlen (dir)
> +                      + strlen (".debug/")
> +                      + strlen (basename) 
> +                      + 1);

`.debug' is an invalid file name on DOS 8+3 filesystems (leading dots are 
not allowed).  For the benefit of users of the DJGPP port of GDB, I 
suggest to allow an additional name, `_debug', as a substitute.  Thus, 
conditioned on __MSDOS__, GDB would look for `_debug' subdirectory if 
`.debug' does not exist.

> diff -u -r1.131 gdb.texinfo
> --- gdb/doc/gdb.texinfo	11 Oct 2002 16:13:15 -0000	1.131
> +++ gdb/doc/gdb.texinfo	26 Nov 2002 03:42:46 -0000

The doco patch is approved, but please add at least one index entry that 
leads to this information.  Something like

  @cindex separate debug info file

sounds appropriate.

> +@table @code
> +@kindex set debug-file-directory
> +@item set debug-file-directory @var{directory}
> +Set the global directory where @value{GDBN} searches for separate
> +debug files to @var{directory}.
> +@end table

A "@cindex global debug file directory" here would be good.

Thanks!


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

* Re: RFC: support debug info in separate files
  2002-11-25 22:34 ` Eli Zaretskii
@ 2002-12-09 19:55   ` Jim Blandy
  2002-12-10 12:19     ` Eli Zaretskii
  0 siblings, 1 reply; 14+ messages in thread
From: Jim Blandy @ 2002-12-09 19:55 UTC (permalink / raw)
  To: Eli Zaretskii; +Cc: gdb-patches

Eli Zaretskii <eliz@is.elta.co.il> writes:
> On 25 Nov 2002, Jim Blandy wrote:
> 
> > This patch, written by Alexander Larsson, allows GDB to use debug info
> > that has been extracted into a separate executable file, using the
> > "strip -f" command as provided in Ulrich Drepper's elfutils.
> 
> Does that mean this feature is not supported by GNU `strip'?  If so, this 
> should be reflected in the docs.

On rereading I think the docs should be a bit more detailed about
all that, yeah.

> > +  debugfile = alloca (strlen (debug_file_directory) + 1
> > +                      + strlen (dir)
> > +                      + strlen (".debug/")
> > +                      + strlen (basename) 
> > +                      + 1);
> 
> `.debug' is an invalid file name on DOS 8+3 filesystems (leading dots are 
> not allowed).  For the benefit of users of the DJGPP port of GDB, I 
> suggest to allow an additional name, `_debug', as a substitute.  Thus, 
> conditioned on __MSDOS__, GDB would look for `_debug' subdirectory if 
> `.debug' does not exist.

I'm reluctant to put #if __MSDOS__ in there directly.  Would it be
appropriate to #define something in xm-go32.h, which could be given a
default value of ".debug" in symfile.c?

> > diff -u -r1.131 gdb.texinfo
> > --- gdb/doc/gdb.texinfo	11 Oct 2002 16:13:15 -0000	1.131
> > +++ gdb/doc/gdb.texinfo	26 Nov 2002 03:42:46 -0000
> 
> The doco patch is approved, but please add at least one index entry that 
> leads to this information.  Something like
> 
>   @cindex separate debug info file
> 
> sounds appropriate.

Of course --- thanks for pointing out that omission.


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

* Re: RFC: support debug info in separate files
  2002-11-25 20:27 RFC: support debug info in separate files Jim Blandy
  2002-11-25 22:34 ` Eli Zaretskii
@ 2002-12-09 22:13 ` Elena Zannoni
  2002-12-10  8:13   ` Andrew Cagney
                     ` (2 more replies)
  2002-12-23  1:25 ` Jim Blandy
  2002-12-23  1:58 ` [repost] " Jim Blandy
  3 siblings, 3 replies; 14+ messages in thread
From: Elena Zannoni @ 2002-12-09 22:13 UTC (permalink / raw)
  To: Jim Blandy; +Cc: gdb-patches

Jim Blandy writes:
 > 
 > This patch, written by Alexander Larsson, allows GDB to use debug info
 > that has been extracted into a separate executable file, using the
 > "strip -f" command as provided in Ulrich Drepper's elfutils.  This
 > allows a distribution to provide debug info in separate packages from
 > the executables it describes.
 > 

Actually thinking about this, where can one get a copy of elfutils?
Could the same functionality be added to binutils?

 > If you've got all the previous patches I've posted (and if I haven't
 > botched anything), this should cause no test suite regressions, and
 > the results of running the test suite both with and without separated
 > debug info are identical.  Starting with current GDB sources, the
 > other patches you need are:
 > 
 > RFA: testsuite: pass optimization flag in the proper way
 > RFA: testsuite: attach.exp: don't move executables to /tmp
 > Re: RFC: allow syms_from_objfile to take a section offset table directly
 > RFC: Allow symbol_file_add to take section_offsets table
 > 
 > To run the GDB test suite against executables with separated debug info, 
 > see: http://sources.redhat.com/ml/gdb/2002-11/msg00202.html
 > and: http://sources.redhat.com/ml/gdb/2002-11/msg00215.html
 > 
 > (Note: there is a bug in the elfutils strip that causes some stripped
 > executables to crash.  This has been fixed only very recently, so
 > you'll need a bleeding-edge version of elfutils, or else you'll get
 > failures in try_catch.exp due to the inferior crashing.)
 > 
 > If folks don't have concerns about this, I'll commit it on Fri Dec 6.
 > 

Some random comments...

This works only for Elf. Will this interfere when other file formats
are processed? (I haven't tried with a, say, coff file, which is
impossible of course because this is elfutils based).

 > 	* utils.c (calc_crc32): New function.
 > 	* defs.h (calc_crc32): New declaration.

Now we have 4 identical crc32's functions in gdb. Any chance to
delete a few?

For the debug file name suggest looking at HAVE_DOS_BASED_FILE_SYSTEM
in libiberty, and its uses in gdb/source.c.

[...]

 > +  strcat (debugfile, ".debug/");
[...]

 > +  strcat (debugfile, "/");

[...]
 > +  strcat (debugfile, "/");

Should these be DIR_SEPARATOR instead? I guess DJGPP doesn't care though.

In this message,
http://sources.redhat.com/ml/gdb/2002-09/msg00312.html I pointed out a
few things that could be done to improve this patch.  For instance,
instead of adding a completely new objfile that would be only for the
debug info, add the debug info to the existing objfiles.  I haven't
had a chance to see if you changed the patch to do something different
or not.  It also seemed at that stage that we were gaining an extra
copy of the minimal symbols, and this can bloat gdb even more. Was
this changed?

Other comments I pointed out in that message have been addressed by
Alex already.

Elena



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

* Re: RFC: support debug info in separate files
  2002-12-09 22:13 ` Elena Zannoni
@ 2002-12-10  8:13   ` Andrew Cagney
  2002-12-10  9:14     ` Elena Zannoni
  2002-12-10 12:43   ` Eli Zaretskii
  2002-12-14 16:48   ` Jim Blandy
  2 siblings, 1 reply; 14+ messages in thread
From: Andrew Cagney @ 2002-12-10  8:13 UTC (permalink / raw)
  To: Jim Blandy; +Cc: Elena Zannoni, gdb-patches

Hmm, to wear fernando's hat :-)  Is there a new test that demonstrates 
this feature?

> Some random comments...
> 
> This works only for Elf. Will this interfere when other file formats
> are processed? (I haven't tried with a, say, coff file, which is
> impossible of course because this is elfutils based).
> 
>  > 	* utils.c (calc_crc32): New function.
>  > 	* defs.h (calc_crc32): New declaration.
> 
> Now we have 4 identical crc32's functions in gdb. Any chance to
> delete a few?
> 
> For the debug file name suggest looking at HAVE_DOS_BASED_FILE_SYSTEM
> in libiberty, and its uses in gdb/source.c.
> 
> [...]
> 
>  > +  strcat (debugfile, ".debug/");
> [...]
> 
>  > +  strcat (debugfile, "/");
> 
> [...]
>  > +  strcat (debugfile, "/");
> 
> Should these be DIR_SEPARATOR instead? I guess DJGPP doesn't care though.
> 
> In this message,
> http://sources.redhat.com/ml/gdb/2002-09/msg00312.html I pointed out a
> few things that could be done to improve this patch.  For instance,
> instead of adding a completely new objfile that would be only for the
> debug info, add the debug info to the existing objfiles.  I haven't
> had a chance to see if you changed the patch to do something different
> or not.  It also seemed at that stage that we were gaining an extra
> copy of the minimal symbols, and this can bloat gdb even more. Was
> this changed?
> 
> Other comments I pointed out in that message have been addressed by
> Alex already.
> 
> Elena
> 
> 
> 



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

* Re: RFC: support debug info in separate files
  2002-12-10  8:13   ` Andrew Cagney
@ 2002-12-10  9:14     ` Elena Zannoni
  2002-12-10 11:39       ` Andrew Cagney
  0 siblings, 1 reply; 14+ messages in thread
From: Elena Zannoni @ 2002-12-10  9:14 UTC (permalink / raw)
  To: Andrew Cagney; +Cc: Jim Blandy, Elena Zannoni, gdb-patches

Andrew Cagney writes:
 > Hmm, to wear fernando's hat :-)  Is there a new test that demonstrates 
 > this feature?

You need the special strip program. One could think of avoiding
running strip by storing the blah.debug files in the gdb.base source
directory, but then the executable built at the time you run the tests
wouldn't be stripped as gdb expects it.  One other way would be to
maybe store the strip program somewhere in the gdb source, but I don't
think this elfutils/strip is FSF.

I know that Jim was able to run the testsuite but I think he relied on
having the proper strip installed on the system.

Elena

 > 
 > > Some random comments...
 > > 
 > > This works only for Elf. Will this interfere when other file formats
 > > are processed? (I haven't tried with a, say, coff file, which is
 > > impossible of course because this is elfutils based).
 > > 
 > >  > 	* utils.c (calc_crc32): New function.
 > >  > 	* defs.h (calc_crc32): New declaration.
 > > 
 > > Now we have 4 identical crc32's functions in gdb. Any chance to
 > > delete a few?
 > > 
 > > For the debug file name suggest looking at HAVE_DOS_BASED_FILE_SYSTEM
 > > in libiberty, and its uses in gdb/source.c.
 > > 
 > > [...]
 > > 
 > >  > +  strcat (debugfile, ".debug/");
 > > [...]
 > > 
 > >  > +  strcat (debugfile, "/");
 > > 
 > > [...]
 > >  > +  strcat (debugfile, "/");
 > > 
 > > Should these be DIR_SEPARATOR instead? I guess DJGPP doesn't care though.
 > > 
 > > In this message,
 > > http://sources.redhat.com/ml/gdb/2002-09/msg00312.html I pointed out a
 > > few things that could be done to improve this patch.  For instance,
 > > instead of adding a completely new objfile that would be only for the
 > > debug info, add the debug info to the existing objfiles.  I haven't
 > > had a chance to see if you changed the patch to do something different
 > > or not.  It also seemed at that stage that we were gaining an extra
 > > copy of the minimal symbols, and this can bloat gdb even more. Was
 > > this changed?
 > > 
 > > Other comments I pointed out in that message have been addressed by
 > > Alex already.
 > > 
 > > Elena
 > > 
 > > 
 > > 
 > 


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

* Re: RFC: support debug info in separate files
  2002-12-10  9:14     ` Elena Zannoni
@ 2002-12-10 11:39       ` Andrew Cagney
  0 siblings, 0 replies; 14+ messages in thread
From: Andrew Cagney @ 2002-12-10 11:39 UTC (permalink / raw)
  To: Elena Zannoni; +Cc: Jim Blandy, gdb-patches

> Andrew Cagney writes:
>  > Hmm, to wear fernando's hat :-)  Is there a new test that demonstrates 
>  > this feature?
> 
> You need the special strip program. One could think of avoiding
> running strip by storing the blah.debug files in the gdb.base source
> directory, but then the executable built at the time you run the tests
> wouldn't be stripped as gdb expects it.  One other way would be to
> maybe store the strip program somewhere in the gdb source, but I don't
> think this elfutils/strip is FSF.

Do you have the specifics of the `strip' command and its behavior?  I'll 
suggest it to binutils.  Hopefully (assuming the feature is as useful as 
it sounds) it will soon be added.

To expand on the test.  What I was thinking of was something to check 
that the prefix command worked.

> I know that Jim was able to run the testsuite but I think he relied on
> having the proper strip installed on the system.

Ah!

Andrew



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

* Re: RFC: support debug info in separate files
  2002-12-09 19:55   ` Jim Blandy
@ 2002-12-10 12:19     ` Eli Zaretskii
  0 siblings, 0 replies; 14+ messages in thread
From: Eli Zaretskii @ 2002-12-10 12:19 UTC (permalink / raw)
  To: jimb; +Cc: gdb-patches

> From: Jim Blandy <jimb@redhat.com>
> Date: 09 Dec 2002 21:56:10 -0500
> 
> > `.debug' is an invalid file name on DOS 8+3 filesystems (leading dots are 
> > not allowed).  For the benefit of users of the DJGPP port of GDB, I 
> > suggest to allow an additional name, `_debug', as a substitute.  Thus, 
> > conditioned on __MSDOS__, GDB would look for `_debug' subdirectory if 
> > `.debug' does not exist.
> 
> I'm reluctant to put #if __MSDOS__ in there directly.  Would it be
> appropriate to #define something in xm-go32.h, which could be given a
> default value of ".debug" in symfile.c?

That'd be fine, thanks.


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

* Re: RFC: support debug info in separate files
  2002-12-09 22:13 ` Elena Zannoni
  2002-12-10  8:13   ` Andrew Cagney
@ 2002-12-10 12:43   ` Eli Zaretskii
  2002-12-14 16:48   ` Jim Blandy
  2 siblings, 0 replies; 14+ messages in thread
From: Eli Zaretskii @ 2002-12-10 12:43 UTC (permalink / raw)
  To: ezannoni; +Cc: jimb, gdb-patches

> From: Elena Zannoni <ezannoni@redhat.com>
> Date: Tue, 10 Dec 2002 00:00:47 -0500
> 
>  > +  strcat (debugfile, ".debug/");
> [...]
> 
>  > +  strcat (debugfile, "/");
> 
> [...]
>  > +  strcat (debugfile, "/");
> 
> Should these be DIR_SEPARATOR instead? I guess DJGPP doesn't care though.

Neither DJGPP nor any other DOS/Windows port of GDB should care, since
DOS and Windows system calls support both flavors of slashes alike.

In general, DIR_SEPARATOR should be used when testing characters to be
separators, but there's no need to do that when constructing file
names.


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

* Re: RFC: support debug info in separate files
  2002-12-09 22:13 ` Elena Zannoni
  2002-12-10  8:13   ` Andrew Cagney
  2002-12-10 12:43   ` Eli Zaretskii
@ 2002-12-14 16:48   ` Jim Blandy
  2 siblings, 0 replies; 14+ messages in thread
From: Jim Blandy @ 2002-12-14 16:48 UTC (permalink / raw)
  To: Elena Zannoni; +Cc: gdb-patches


Elena Zannoni <ezannoni@redhat.com> writes:

> Jim Blandy writes:
>  > 
>  > This patch, written by Alexander Larsson, allows GDB to use debug info
>  > that has been extracted into a separate executable file, using the
>  > "strip -f" command as provided in Ulrich Drepper's elfutils.  This
>  > allows a distribution to provide debug info in separate packages from
>  > the executables it describes.
>  > 
> 
> Actually thinking about this, where can one get a copy of elfutils?
> Could the same functionality be added to binutils?

Sure, I don't see why not.

>  > If you've got all the previous patches I've posted (and if I haven't
>  > botched anything), this should cause no test suite regressions, and
>  > the results of running the test suite both with and without separated
>  > debug info are identical.  Starting with current GDB sources, the
>  > other patches you need are:
>  > 
>  > RFA: testsuite: pass optimization flag in the proper way
>  > RFA: testsuite: attach.exp: don't move executables to /tmp
>  > Re: RFC: allow syms_from_objfile to take a section offset table directly
>  > RFC: Allow symbol_file_add to take section_offsets table
>  > 
>  > To run the GDB test suite against executables with separated debug info, 
>  > see: http://sources.redhat.com/ml/gdb/2002-11/msg00202.html
>  > and: http://sources.redhat.com/ml/gdb/2002-11/msg00215.html
>  > 
>  > (Note: there is a bug in the elfutils strip that causes some stripped
>  > executables to crash.  This has been fixed only very recently, so
>  > you'll need a bleeding-edge version of elfutils, or else you'll get
>  > failures in try_catch.exp due to the inferior crashing.)
>  > 
>  > If folks don't have concerns about this, I'll commit it on Fri Dec 6.
>  > 
> 
> Some random comments...
> 
> This works only for Elf. Will this interfere when other file formats
> are processed? (I haven't tried with a, say, coff file, which is
> impossible of course because this is elfutils based).

Actually, the GDB side of things is completely format-agnostic.  It
should work with anything that BFD says has a section named
".gnu_debuglink".  If you can get the file constructed in the first
place, GDB should handle it.  It shouldn't affect GDB's handling of
files that don't have .gnu_debuglink sections at all.

>  > 	* utils.c (calc_crc32): New function.
>  > 	* defs.h (calc_crc32): New declaration.
> 
> Now we have 4 identical crc32's functions in gdb. Any chance to
> delete a few?

The one in utils.c and the one in remote.c are not the same:

(top-gdb) print calc_crc32(0, "howdy", 5)
$2 = 1976775978
(top-gdb) print crc32("howdy", 5, 0)
$3 = 701963740

A CRC isn't a well-defined function like MD5 or SHA; you also need to
know which polynomial the CRC is using, and maybe some other things I
don't really understand.  It looks to me as if crc32 and calc_crc32
are using different polynomials.

The choice of which CRC to use in these cases is a matter of public
interface.  We obviously can't change the one remote.c uses, since it
has complementary functions in stubs all over the place.  Since
.gnu_debuglink is a new feature, its CRC function could be changed
without much trouble, but since we'll run into a variety of CRC's
anyway, it's not worth the trouble.

The best thing is probably to give the functions names that better
reflect their purpose; calling them just "crc" is a bit like naming a
Modula-2 compiler "compile".  gnu_debuglink_crc32 and
gdb_remote_crc32?  (It would be nice if someone who really understands
CRCs could write a comment that characterizes each of them.)

m32r-stub.c's crc32 clearly needs to match the one in remote.c ---
which, in fact, it does.  Moving the GDB remote protocol's CRC
function into a separate file, so it could be shared with the stub, is
a possibility, but it'd need to be compiled separately for the host
and target machines.  Definitely work for a separate patch, in any
case.

xmodem.c has a 16-bit CRC, not a 32-bit CRC.  Again a matter of public
protocol.

> For the debug file name suggest looking at HAVE_DOS_BASED_FILE_SYSTEM
> in libiberty, and its uses in gdb/source.c.
> 
> [...]
> 
>  > +  strcat (debugfile, ".debug/");
> [...]
> 
>  > +  strcat (debugfile, "/");
> 
> [...]
>  > +  strcat (debugfile, "/");
> 
> Should these be DIR_SEPARATOR instead? I guess DJGPP doesn't care
> though.

Yeah.  Eli has said it doesn't matter, but I think using DIR_SEPARATOR
would be better.

> In this message,
> http://sources.redhat.com/ml/gdb/2002-09/msg00312.html I pointed out a
> few things that could be done to improve this patch.  For instance,
> instead of adding a completely new objfile that would be only for the
> debug info, add the debug info to the existing objfiles.  I haven't
> had a chance to see if you changed the patch to do something different
> or not.

Yes, I remember the suggestion; this patch still creates a separate
objfile.  It *seems* to me that reading two file's data into a single
objfile structure would make the patch quite a bit more complex than
it is.  It'd be nice to see the patch, so we could assess how much of
a difference it made.

> It also seemed at that stage that we were gaining an extra
> copy of the minimal symbols, and this can bloat gdb even more. Was
> this changed?

No, it wasn't changed.  There is some duplication going on, but not
quite the way the question suggests.  Here's the whole story:

An unstripped executable has separate symbol tables for the static
linker (.symtab/.strtab) and the dynamic linker
(.dynsym/.dynstr/.hash).  The ordinary `strip' command everyone has
been using for years deletes the static linker symbols and the debug
info, but leaves the dynamic linker symbol table there --- since the
program can't run without it.  The new Elfutils 'strip -f' command
moves the static linker symbols and the debug info into a separate
file, instead of just tossing it.  So 'strip -f' itself never
duplicates anything.  The resulting pair of files contains the same
amount of information the original file did.

The dynamic symtab is usually just a subset of the static symtab, so
there is duplication there.  GDB constructs its minsym table by
reading both the static and dynamic linkers' symbol tables, but if
they're both present, it ignores almost everything from the dynamic
symtab (except for symbols naming PLT entries).  (See elf_symtab_read,
called from elf_symfile_read, for details.)  So the duplication
present in an ordinary executable's static and dynamic linker symbol
tables doesn't bother GDB.

In a separated executable, however, GDB doesn't realize that, although
the stripped file does not have a static linker symbol table, it will
eventually be getting those symbols from the separated debug file.  So
it effectively reads in both the dynamic and static linker symtabs,
where otherwise it would ignore the dynamic symtab.

    $ nm gdb | wc -l
       7970
    $ nm -D gdb | wc -l
       4059
    $

So there's quite a bit of extra data involved.

In context, though, the alternative to using separated debug files is
to have no debug info at all, or to make the user recompile from
source.  So while the dynamic/static duplication should be addressed,
I don't think the patch should be blocked on it.


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

* Re: RFC: support debug info in separate files
  2002-11-25 20:27 RFC: support debug info in separate files Jim Blandy
  2002-11-25 22:34 ` Eli Zaretskii
  2002-12-09 22:13 ` Elena Zannoni
@ 2002-12-23  1:25 ` Jim Blandy
  2002-12-23  1:58 ` [repost] " Jim Blandy
  3 siblings, 0 replies; 14+ messages in thread
From: Jim Blandy @ 2002-12-23  1:25 UTC (permalink / raw)
  To: gdb-patches


Here's a new shot at the separate debug patch.  It's updated to apply
to the current branch, and I believe I've addressed the comments folks
have made:
- The documentation has been completely rewritten, and provides much
  more detail.  It includes all the information needed to implement
  `strip -f' in the GNU binutils, for example.  It is better indexed.
- The name ".debug" can be overridden by xm- files for systems that
  can't handle names like that.
- The CRC function has a more descriptive name.

Using separate debug info does introduce three new test suite
failures:
FAIL: gdb.base/maint.exp: maint print objfiles: psymtabs
FAIL: gdb.base/maint.exp: maint print objfiles: symtabs
FAIL: gdb.base/maint.exp: maint print msymbols

These do not reflect GDB misbehavior: the objfile in question has no
psymtabs, symtabs, or msymbols, but the test suite assumes they
should.  I think 'maint print objfiles' should print something
indicating when an objfile has an associated separated debug file, and
that the test should recognize and cope with this, but it seems like
that should be a separate patch.

Before you can apply this patch, you'll need to apply the following:

Re: RFC: allow syms_from_objfile to take a section offset table directly
    http://sources.redhat.com/ml/gdb-patches/2002-12/msg00627.html

RFC: Allow symbol_file_add to take section_offsets table
    http://sources.redhat.com/ml/gdb-patches/2002-11/msg00634.html

gdb/ChangeLog:
2002-12-23  Alexander Larsson <alexl@redhat.com>
	    Jim Blandy  <jimb@redhat.com>

	Add support for executables whose debug info has been separated
	out into a separate file, leaving only a link behind.
	* objfiles.h (struct objfile): New fields: separate_debug_objfile
	and separate_debug_objfile_backlink.
	(put_objfile_before): New declaration.
	* symfile.c: #include "filenames.h".
	(symbol_file_add_with_addrs_or_offsets): If this objfile has its
	debug info in a separate file, read that, too. Save the addrs
	argument, so we can use it again to read the separated debug info;
	syms_from_objfile modifies the table we pass it.
	(reread_symbols): After re-reading an objfile, call
	reread_separate_symbols to refresh its separate debug info
	objfile, if it has one.
	(reread_separate_symbols, find_separate_debug_file,
	get_debug_link_info, separate_debug_file_exists): New functions.
	(debug_file_directory): New global var.
	(_initialize_symfile): Initialize debug_file_directory, and
	provide the new `set debug-file-directory' command to let the user
	change it.
	* objfiles.c (free_objfile): If this objfile has its debug info in
	a separate objfile, free that one too.  If this is itself a
	separate debug info objfile, clear our parent's backlink.
	(put_objfile_before): New function.
	* utils.c (gnu_debuglink_crc32): New function.
	* defs.h (gnu_debuglink_crc32): New declaration.
	* Makefile.in (symfile.o): Note dependency on "filenames.h".
	* configure.in: Handle --with-separate-debug-dir config option.
	* acinclude.m4 (AC_DEFINE_DIR): New macro.
	* acconfig.h (DEBUGDIR): New macro.
	* configure, aclocal.m4, config.in: Regenerated.

gdb/doc/ChangeLog:
2002-12-23  Jim Blandy  <jimb@redhat.com>

	* gdb.texinfo (Separate Debug Files): New section.

Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.297.2.1
diff -c -r1.297.2.1 Makefile.in
*** gdb/Makefile.in	23 Dec 2002 08:48:07 -0000	1.297.2.1
--- gdb/Makefile.in	23 Dec 2002 08:57:36 -0000
***************
*** 2247,2253 ****
  	$(gdbcmd_h) $(breakpoint_h) $(language_h) $(complaints_h) \
  	$(demangle_h) $(inferior_h) $(gdb_stabs_h) $(gdb_obstack_h) \
  	$(completer_h) $(bcache_h) $(gdb_string_h) $(gdb_stat_h) $(source_h) \
! 	$(gdb_assert_h) $(readline_h)
  symm-nat.o: symm-nat.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
  	$(target_h) $(regcache_h) $(gdb_stat_h) $(gdbcore_h) $(gdbcore_h)
  symm-tdep.o: symm-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
--- 2247,2253 ----
  	$(gdbcmd_h) $(breakpoint_h) $(language_h) $(complaints_h) \
  	$(demangle_h) $(inferior_h) $(gdb_stabs_h) $(gdb_obstack_h) \
  	$(completer_h) $(bcache_h) $(gdb_string_h) $(gdb_stat_h) $(source_h) \
! 	$(gdb_assert_h) $(readline_h) $(filenames_h)
  symm-nat.o: symm-nat.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
  	$(target_h) $(regcache_h) $(gdb_stat_h) $(gdbcore_h) $(gdbcore_h)
  symm-tdep.o: symm-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
Index: gdb/acinclude.m4
===================================================================
RCS file: /cvs/src/src/gdb/acinclude.m4,v
retrieving revision 1.5
diff -c -r1.5 acinclude.m4
*** gdb/acinclude.m4	27 Nov 2002 19:13:08 -0000	1.5
--- gdb/acinclude.m4	23 Dec 2002 08:57:37 -0000
***************
*** 918,920 ****
--- 918,935 ----
    fi
    AC_SUBST(LIBICONV)
  ])
+ 
+ dnl written by Guido Draheim <guidod@gmx.de>, original by Alexandre Oliva 
+ dnl Version 1.3 (2001/03/02)
+ dnl source http://www.gnu.org/software/ac-archive/Miscellaneous/ac_define_dir.html
+ 
+ AC_DEFUN([AC_DEFINE_DIR], [
+   test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+   test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+   ac_define_dir=`eval echo [$]$2`
+   ac_define_dir=`eval echo [$]ac_define_dir`
+   ifelse($3, ,
+     AC_DEFINE_UNQUOTED($1, "$ac_define_dir"),
+     AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3))
+ ])
+ 
Index: gdb/configure.in
===================================================================
RCS file: /cvs/src/src/gdb/configure.in,v
retrieving revision 1.96
diff -c -r1.96 configure.in
*** gdb/configure.in	29 Nov 2002 00:29:27 -0000	1.96
--- gdb/configure.in	23 Dec 2002 08:57:41 -0000
***************
*** 237,242 ****
--- 237,250 ----
  AC_CHECK_LIB(socket, socketpair)
  AC_CHECK_FUNCS(socketpair)
  
+ debugdir=${libdir}/debug
+ 	 
+ AC_ARG_WITH(separate-debug-dir,
+ [  --with-separate-debug-dir=path   Look for global separate debug info in this path [LIBDIR/debug]],
+ [debugdir="${withval}"])
+ 	
+ AC_DEFINE_DIR(DEBUGDIR, debugdir)
+ #AC_DEFINE_UNQUOTED(DEBUGDIR, "$debugdir"),
  
  BFD_NEED_DECLARATION(malloc)
  BFD_NEED_DECLARATION(realloc)
Index: gdb/defs.h
===================================================================
RCS file: /cvs/src/src/gdb/defs.h,v
retrieving revision 1.104
diff -c -r1.104 defs.h
*** gdb/defs.h	13 Dec 2002 17:55:49 -0000	1.104
--- gdb/defs.h	23 Dec 2002 08:57:42 -0000
***************
*** 382,387 ****
--- 382,390 ----
  extern char *gdb_realpath (const char *);
  extern char *xfullpath (const char *);
  
+ extern unsigned long gnu_debuglink_crc32 (unsigned long crc,
+                                           unsigned char *buf, size_t len);
+ 
  /* From demangle.c */
  
  extern void set_demangling_style (char *);
Index: gdb/objfiles.c
===================================================================
RCS file: /cvs/src/src/gdb/objfiles.c,v
retrieving revision 1.22
diff -c -r1.22 objfiles.c
*** gdb/objfiles.c	29 Jul 2002 22:55:26 -0000	1.22
--- gdb/objfiles.c	23 Dec 2002 08:57:43 -0000
***************
*** 333,338 ****
--- 333,362 ----
    return (objfile);
  }
  
+ /* Put one object file before a specified on in the global list.
+    This can be used to make sure an object file is destroyed before
+    another when using ALL_OBJFILES_SAFE to free all objfiles. */
+ void
+ put_objfile_before (struct objfile *objfile, struct objfile *before_this)
+ {
+   struct objfile **objp;
+ 
+   unlink_objfile (objfile);
+   
+   for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
+     {
+       if (*objp == before_this)
+ 	{
+ 	  objfile->next = *objp;
+ 	  *objp = objfile;
+ 	  return;
+ 	}
+     }
+   
+   internal_error (__FILE__, __LINE__,
+ 		  "put_objfile_before: before objfile not in list");
+ }
+ 
  /* Put OBJFILE at the front of the list.  */
  
  void
***************
*** 405,410 ****
--- 429,446 ----
  void
  free_objfile (struct objfile *objfile)
  {
+   if (objfile->separate_debug_objfile)
+     {
+       free_objfile (objfile->separate_debug_objfile);
+     }
+   
+   if (objfile->separate_debug_objfile_backlink)
+     {
+       /* We freed the separate debug file, make sure the base objfile
+ 	 doesn't reference it.  */
+       objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL;
+     }
+   
    /* First do any symbol file specific actions required when we are
       finished with a particular symbol file.  Note that if the objfile
       is using reusable symbol information (via mmalloc) then each of
Index: gdb/objfiles.h
===================================================================
RCS file: /cvs/src/src/gdb/objfiles.h,v
retrieving revision 1.15
diff -c -r1.15 objfiles.h
*** gdb/objfiles.h	5 Aug 2002 16:17:41 -0000	1.15
--- gdb/objfiles.h	23 Dec 2002 08:57:43 -0000
***************
*** 414,419 ****
--- 414,428 ----
      ExportEntry *export_list;
      int export_list_size;
  
+     /* Link to objfile that contains the debug symbols for this one.
+        One is loaded if this file has an debug link to an existing
+        debug file with the right checksum */
+     struct objfile *separate_debug_objfile;
+ 
+     /* If this is a separate debug object, this is used as a link to the
+        actual executable objfile. */
+     struct objfile *separate_debug_objfile_backlink;
+     
      /* Place to stash various statistics about this objfile */
        OBJSTATS;
    };
***************
*** 504,509 ****
--- 513,520 ----
  extern struct objfile *allocate_objfile (bfd *, int);
  
  extern int build_objfile_section_table (struct objfile *);
+ 
+ extern void put_objfile_before (struct objfile *, struct objfile *);
  
  extern void objfile_to_front (struct objfile *);
  
Index: gdb/symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.75.2.2
diff -c -r1.75.2.2 symfile.c
*** gdb/symfile.c	23 Dec 2002 08:50:07 -0000	1.75.2.2
--- gdb/symfile.c	23 Dec 2002 08:57:46 -0000
***************
*** 38,43 ****
--- 38,44 ----
  #include "complaints.h"
  #include "demangle.h"
  #include "inferior.h"		/* for write_pc */
+ #include "filenames.h"		/* for DOSish file names */
  #include "gdb-stabs.h"
  #include "gdb_obstack.h"
  #include "completer.h"
***************
*** 105,110 ****
--- 106,113 ----
  
  static void add_shared_symbol_files_command (char *, int);
  
+ static void reread_separate_symbols (struct objfile *objfile);
+ 
  static void cashier_psymtab (struct partial_symtab *);
  
  bfd *symfile_bfd_open (char *);
***************
*** 149,154 ****
--- 152,159 ----
  
  static void info_ext_lang_command (char *args, int from_tty);
  
+ static char *find_separate_debug_file (struct objfile *objfile);
+ 
  static void init_filename_language_table (void);
  
  void _initialize_symfile (void);
***************
*** 888,894 ****
--- 893,904 ----
  {
    struct objfile *objfile;
    struct partial_symtab *psymtab;
+   char *debugfile;
    bfd *abfd;
+   struct section_addr_info orig_addrs;
+   
+   if (addrs)
+     orig_addrs = *addrs;
  
    /* Open a bfd for the file, and give user a chance to burp if we'd be
       interactively wiping out any existing symbols.  */
***************
*** 963,968 ****
--- 973,1009 ----
  	}
      }
  
+   debugfile = find_separate_debug_file (objfile);
+   if (debugfile)
+     {
+       if (from_tty || info_verbose)
+         {
+           printf_filtered ("loading separate debug info from '%s'",
+                            debugfile);
+           wrap_here ("");
+           gdb_flush (gdb_stdout);
+         }
+ 
+       if (addrs != NULL)
+ 	{
+ 	  objfile->separate_debug_objfile
+             = symbol_file_add (debugfile, from_tty, &orig_addrs, 0, flags);
+ 	}
+       else
+ 	{
+ 	  objfile->separate_debug_objfile
+             = symbol_file_add (debugfile, from_tty, NULL, 0, flags);
+ 	}
+       objfile->separate_debug_objfile->separate_debug_objfile_backlink
+         = objfile;
+       
+       /* Put the separate debug object before the normal one, this is so that
+          usage of the ALL_OBJFILES_SAFE macro will stay safe. */
+       put_objfile_before (objfile->separate_debug_objfile, objfile);
+       
+       xfree (debugfile);
+     }
+   
    if (from_tty || info_verbose)
      {
        if (post_add_symbol_hook)
***************
*** 1058,1063 ****
--- 1099,1239 ----
  #endif
  }
  
+ static char *
+ get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out)
+ {
+   asection *sect;
+   bfd_size_type debuglink_size;
+   unsigned long crc32;
+   char *contents;
+   int crc_offset;
+   unsigned char *p;
+   
+   sect = bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink");
+ 
+   if (sect == NULL)
+     return NULL;
+ 
+   debuglink_size = bfd_section_size (objfile->obfd, sect);
+   
+   contents = xmalloc (debuglink_size);
+   bfd_get_section_contents (objfile->obfd, sect, contents,
+ 			    (file_ptr)0, (bfd_size_type)debuglink_size);
+ 
+   /* Crc value is stored after the filename, aligned up to 4 bytes. */
+   crc_offset = strlen (contents) + 1;
+   crc_offset = (crc_offset + 3) & ~3;
+ 
+   crc32 = bfd_get_32 (objfile->obfd, (bfd_byte *) (contents + crc_offset));
+   
+   *crc32_out = crc32;
+   return contents;
+ }
+ 
+ static int
+ separate_debug_file_exists (const char *name, unsigned long crc)
+ {
+   unsigned long file_crc = 0;
+   int fd;
+   char buffer[8*1024];
+   int count;
+ 
+   fd = open (name, O_RDONLY | O_BINARY);
+   if (fd < 0)
+     return 0;
+ 
+   while ((count = read (fd, buffer, sizeof (buffer))) > 0)
+     file_crc = gnu_debuglink_crc32 (file_crc, buffer, count);
+ 
+   close (fd);
+ 
+   return crc == file_crc;
+ }
+ 
+ static char *debug_file_directory = NULL;
+ 
+ #if ! defined (DEBUG_SUBDIRECTORY)
+ #define DEBUG_SUBDIRECTORY ".debug"
+ #endif
+ 
+ static char *
+ find_separate_debug_file (struct objfile *objfile)
+ {
+   asection *sect;
+   char *basename;
+   char *dir;
+   char *debugfile;
+   char *name_copy;
+   bfd_size_type debuglink_size;
+   unsigned long crc32;
+   int i;
+ 
+   basename = get_debug_link_info (objfile, &crc32);
+ 
+   if (basename == NULL)
+     return NULL;
+   
+   dir = xstrdup (objfile->name);
+ 
+   /* Strip off filename part */
+   for (i = strlen(dir) - 1; i >= 0; i--)
+     {
+       if (IS_DIR_SEPARATOR (dir[i]))
+ 	break;
+     }
+   dir[i+1] = '\0';
+   
+   debugfile = alloca (strlen (debug_file_directory) + 1
+                       + strlen (dir)
+                       + strlen (DEBUG_SUBDIRECTORY)
+                       + strlen ("/")
+                       + strlen (basename) 
+                       + 1);
+ 
+   /* First try in the same directory as the original file.  */
+   strcpy (debugfile, dir);
+   strcat (debugfile, basename);
+ 
+   if (separate_debug_file_exists (debugfile, crc32))
+     {
+       xfree (basename);
+       xfree (dir);
+       return xstrdup (debugfile);
+     }
+   
+   /* Then try in the subdirectory named DEBUG_SUBDIRECTORY.  */
+   strcpy (debugfile, dir);
+   strcat (debugfile, DEBUG_SUBDIRECTORY);
+   strcat (debugfile, "/");
+   strcat (debugfile, basename);
+ 
+   if (separate_debug_file_exists (debugfile, crc32))
+     {
+       xfree (basename);
+       xfree (dir);
+       return xstrdup (debugfile);
+     }
+   
+   /* Then try in the global debugfile directory.  */
+   strcpy (debugfile, debug_file_directory);
+   strcat (debugfile, "/");
+   strcat (debugfile, dir);
+   strcat (debugfile, "/");
+   strcat (debugfile, basename);
+ 
+   if (separate_debug_file_exists (debugfile, crc32))
+     {
+       xfree (basename);
+       xfree (dir);
+       return xstrdup (debugfile);
+     }
+   
+   xfree (basename);
+   xfree (dir);
+   return NULL;
+ }
+ 
+ 
  /* This is the symbol-file command.  Read the file, analyze its
     symbols, and add a struct symtab to a symtab list.  The syntax of
     the command is rather bizarre--(1) buildargv implements various
***************
*** 1903,1908 ****
--- 2079,2086 ----
  	         needs to keep track of (such as _sigtramp, or whatever).  */
  
  	      TARGET_SYMFILE_POSTREAD (objfile);
+ 
+               reread_separate_symbols (objfile);
  	    }
  	}
      }
***************
*** 1910,1915 ****
--- 2088,2160 ----
    if (reread_one)
      clear_symtab_users ();
  }
+ 
+ 
+ /* Handle separate debug info for OBJFILE, which has just been
+    re-read:
+    - If we had separate debug info before, but now we don't, get rid
+      of the separated objfile.
+    - If we didn't have separated debug info before, but now we do,
+      read in the new separated debug info file.
+    - If the debug link points to a different file, toss the old one
+      and read the new one.
+    This function does *not* handle the case where objfile is still
+    using the same separate debug info file, but that file's timestamp
+    has changed.  That case should be handled by the loop in
+    reread_symbols already.  */
+ static void
+ reread_separate_symbols (struct objfile *objfile)
+ {
+   char *debug_file;
+   unsigned long crc32;
+ 
+   /* Does the updated objfile's debug info live in a
+      separate file?  */
+   debug_file = find_separate_debug_file (objfile);
+ 
+   if (objfile->separate_debug_objfile)
+     {
+       /* There are two cases where we need to get rid of
+          the old separated debug info objfile:
+          - if the new primary objfile doesn't have
+          separated debug info, or
+          - if the new primary objfile has separate debug
+          info, but it's under a different filename.
+  
+          If the old and new objfiles both have separate
+          debug info, under the same filename, then we're
+          okay --- if the separated file's contents have
+          changed, we will have caught that when we
+          visited it in this function's outermost
+          loop.  */
+       if (! debug_file
+           || strcmp (debug_file, objfile->separate_debug_objfile->name) != 0)
+         free_objfile (objfile->separate_debug_objfile);
+     }
+ 
+   /* If the new objfile has separate debug info, and we
+      haven't loaded it already, do so now.  */
+   if (debug_file
+       && ! objfile->separate_debug_objfile)
+     {
+       /* Use the same section offset table as objfile itself.
+          Preserve the flags from objfile that make sense.  */
+       objfile->separate_debug_objfile
+         = (symbol_file_add_with_addrs_or_offsets
+            (debug_file,
+             info_verbose, /* from_tty: Don't override the default. */
+             0, /* No addr table.  */
+             objfile->section_offsets, objfile->num_sections,
+             0, /* Not mainline.  See comments about this above.  */
+             objfile->flags & (OBJF_MAPPED | OBJF_REORDERED
+                               | OBJF_SHARED | OBJF_READNOW
+                               | OBJF_USERLOADED)));
+       objfile->separate_debug_objfile->separate_debug_objfile_backlink
+         = objfile;
+     }
+ }
+ 
+ 
  \f
  
  
***************
*** 3418,3421 ****
--- 3663,3681 ----
  		  "cache.\n",
  		  &setlist),
       &showlist);
+ 
+   debug_file_directory = xstrdup (DEBUGDIR);
+   c = (add_set_cmd
+        ("debug-file-directory", class_support, var_string,
+         (char *) &debug_file_directory,
+         "Set the directory where separate debug symbols are searched for.\n"
+         "Separate debug symbols are first searched for in the same\n"
+         "directory as the binary, then in the `" DEBUG_SUBDIRECTORY 
+         "' subdirectory,\n"
+         "and lastly at the path of the directory of the binary with\n"
+         "the global debug-file directory prepended\n",
+         &setlist));
+   add_show_from_set (c, &showlist);
+   set_cmd_completer (c, filename_completer);
+ 
  }
Index: gdb/utils.c
===================================================================
RCS file: /cvs/src/src/gdb/utils.c,v
retrieving revision 1.87
diff -c -r1.87 utils.c
*** gdb/utils.c	30 Nov 2002 16:33:55 -0000	1.87
--- gdb/utils.c	23 Dec 2002 08:57:47 -0000
***************
*** 2809,2811 ****
--- 2809,2883 ----
    xfree (real_path);
    return result;
  }
+ 
+ 
+ /* This is the 32-bit CRC function used by the GNU separate debug
+    facility.  An executable may contain a section named
+    .gnu_debuglink, which holds the name of a separate executable file
+    containing its debug info, and a checksum of that file's contents,
+    computed using this function.  */
+ unsigned long
+ gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len)
+ {
+   static const unsigned long crc32_table[256] =
+     {
+       0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+       0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+       0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+       0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+       0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+       0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+       0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+       0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+       0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+       0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+       0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+       0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+       0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+       0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+       0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+       0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+       0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+       0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+       0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+       0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+       0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+       0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+       0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+       0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+       0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+       0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+       0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+       0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+       0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+       0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+       0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+       0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+       0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+       0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+       0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+       0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+       0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+       0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+       0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+       0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+       0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+       0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+       0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+       0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+       0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+       0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+       0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+       0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+       0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+       0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+       0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+       0x2d02ef8d
+     };
+   unsigned char *end;
+ 
+   crc = ~crc & 0xffffffff;
+   for (end = buf + len; buf < end; ++buf)
+     crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+   return ~crc & 0xffffffff;;
+ }
Index: gdb/doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.131
diff -c -r1.131 gdb.texinfo
*** gdb/doc/gdb.texinfo	11 Oct 2002 16:13:15 -0000	1.131
--- gdb/doc/gdb.texinfo	23 Dec 2002 08:58:02 -0000
***************
*** 9802,9807 ****
--- 9802,9808 ----
  
  @menu
  * Files::                       Commands to specify files
+ * Separate Debug Files::        Debugging information in separate files
  * Symbol Errors::               Errors reading symbol files
  @end menu
  
***************
*** 10205,10210 ****
--- 10206,10393 ----
  @item show auto-solib-limit
  Display the current autoloading size threshold, in megabytes.
  @end table
+ 
+ 
+ @node Separate Debug Files
+ @section Debugging Information in Separate Files
+ @cindex separate debugging information files
+ @cindex debugging information in separate files
+ @cindex .debug subdirectories
+ @cindex debugging information directory, global
+ @cindex global debugging information directory
+ 
+ @value{GDBN} allows you to put a program's debugging information in a
+ file separate from the executable itself, in a way that allows
+ @value{GDBN} to find and load the debugging information automatically.
+ Since debugging information can be very large --- sometimes larger
+ than the executable code itself --- some systems distribute debugging
+ information for their executables in separate files, which users can
+ install only when they need to debug a problem.
+ 
+ If an executable's debugging information has been extracted to a
+ separate file, the executable should contain a @dfn{debug link} giving
+ the name of the debugging information file (with no directory
+ components), and a checksum of its contents.  (The exact form of a
+ debug link is described below.)  If the full name of the directory
+ containing the executable is @var{execdir}, and the executable has a
+ debug link that specifies the name @var{debugfile}, then @value{GDBN}
+ will automatically search for the debugging information file in three
+ places:
+ 
+ @itemize @bullet
+ @item
+ the directory containing the executable file (that is, it will look
+ for a file named @file{@var{execdir}/@var{debugfile}},
+ @item
+ a subdirectory of that directory named @file{.debug} (that is, the
+ file @file{@var{execdir}/.debug/@var{debugfile}}, and
+ @item
+ a subdirectory of the global debug file directory that includes the
+ executable's full path, and the name from the link (that is, the file
+ @file{@var{globaldebugdir}/@var{execdir}/@var{debugfile}}, where
+ @var{globaldebugdir} is the global debug file directory, and
+ @var{execdir} has been turned into a relative path).
+ @end itemize
+ @noindent
+ @value{GDBN} checks under each of these names for a debugging
+ information file whose checksum matches that given in the link, and
+ reads the debugging information from the first one it finds.
+ 
+ So, for example, if you ask @value{GDBN} to debug @file{/usr/bin/ls},
+ which has a link containing the name @file{ls.debug}, and the global
+ debug directory is @file{/usr/lib/debug}, then @value{GDBN} will look
+ for debug information in @file{/usr/bin/ls.debug},
+ @file{/usr/bin/.debug/ls.debug}, and
+ @file{/usr/lib/debug/usr/bin/ls.debug}.
+ 
+ You can set the global debugging info directory's name, and view the
+ name @value{GDBN} is currently using.
+ 
+ @table @code
+ 
+ @kindex set debug-file-directory
+ @item set debug-file-directory @var{directory}
+ Set the directory which @value{GDBN} searches for separate debugging
+ information files to @var{directory}.
+ 
+ @kindex show debug-file-directory
+ @item show debug-file-directory
+ Show the directory @value{GDBN} searches for separate debugging
+ information files.
+ 
+ @end table
+ 
+ @cindex .gnu_debuglink sections
+ @cindex debug links
+ A debug link is a special section of the executable file named
+ @code{.gnu_debuglink}.  The section must contain:
+ 
+ @itemize
+ @item
+ A filename, with any leading directory components removed, followed by
+ a zero byte,
+ @item
+ zero to three bytes of padding, as needed to reach the next four-byte
+ boundary within the section, and
+ @item
+ a four-byte CRC checksum, stored in the same endianness used for the
+ executable file itself.  The checksum is computed on the debugging
+ information file's full contents by the function given below, passing
+ zero as the @var{crc} argument.
+ @end itemize
+ 
+ Any executable file format can carry a debug link, as long as it can
+ contain a section named @code{.gnu_debuglink} with the contents
+ described above.
+ 
+ The debugging information file itself should be an ordinary
+ executable, containing a full set of linker symbols, sections, and
+ debugging information.  The sections of the debugging information file
+ should have the same names, addresses and sizes as the original file,
+ but they need not contain any data --- much like a @code{.bss} section
+ in an ordinary executable.
+ 
+ As of December 2002, there is no standard GNU utility to produce
+ separated executable / debugging information file pairs.  Ulrich
+ Drepper's @file{elfutils} package, starting with version 0.53,
+ contains a version of the @code{strip} command such that the command
+ @samp{strip foo -f foo.debug} removes the debugging information from
+ the executable file @file{foo}, places it in the file
+ @file{foo.debug}, and leaves behind a debug link in @file{foo}.
+ 
+ Since there are many different ways to compute CRC's (different
+ polynomials, reversals, byte ordering, etc.), the simplest way to
+ describe the CRC used in @code{.gnu_debuglink} sections is to give its
+ complete code:
+ 
+ @kindex gnu_debuglink_crc32
+ @example
+ unsigned long
+ gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len)
+ @{
+   static const unsigned long crc32_table[256] =
+     @{
+       0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+       0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+       0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+       0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+       0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+       0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+       0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+       0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+       0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+       0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+       0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+       0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+       0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+       0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+       0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+       0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+       0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+       0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+       0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+       0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+       0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+       0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+       0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+       0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+       0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+       0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+       0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+       0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+       0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+       0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+       0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+       0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+       0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+       0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+       0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+       0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+       0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+       0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+       0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+       0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+       0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+       0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+       0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+       0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+       0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+       0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+       0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+       0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+       0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+       0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+       0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+       0x2d02ef8d
+     @};
+   unsigned char *end;
+ 
+   crc = ~crc & 0xffffffff;
+   for (end = buf + len; buf < end; ++buf)
+     crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+   return ~crc & 0xffffffff;;
+ @}
+ @end example
  
  @node Symbol Errors
  @section Errors reading symbol files


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

* [repost] Re: RFC: support debug info in separate files
  2002-11-25 20:27 RFC: support debug info in separate files Jim Blandy
                   ` (2 preceding siblings ...)
  2002-12-23  1:25 ` Jim Blandy
@ 2002-12-23  1:58 ` Jim Blandy
  2002-12-23  6:59   ` Eli Zaretskii
  2003-01-23 23:04   ` Jim Blandy
  3 siblings, 2 replies; 14+ messages in thread
From: Jim Blandy @ 2002-12-23  1:58 UTC (permalink / raw)
  To: gdb-patches


[My previous post omitted the patch to acconfig.h.]

Here's a new shot at the separate debug patch.  It's updated to apply
to the current branch, and I believe I've addressed the comments folks
have made:
- The documentation has been completely rewritten, and provides much
  more detail.  It includes all the information needed to implement
  `strip -f' in the GNU binutils, for example.  It is better indexed.
- The name ".debug" can be overridden by xm- files for systems that
  can't handle names like that.
- The CRC function has a more descriptive name.

Using separate debug info does introduce three new test suite
failures:
FAIL: gdb.base/maint.exp: maint print objfiles: psymtabs
FAIL: gdb.base/maint.exp: maint print objfiles: symtabs
FAIL: gdb.base/maint.exp: maint print msymbols

These do not reflect GDB misbehavior: the objfile in question has no
psymtabs, symtabs, or msymbols, but the test suite assumes they
should.  I think 'maint print objfiles' should print something
indicating when an objfile has an associated separated debug file, and
that the test should recognize and cope with this, but it seems like
that should be a separate patch.

Before you can apply this patch, you'll need to apply the following:

Re: RFC: allow syms_from_objfile to take a section offset table directly
    http://sources.redhat.com/ml/gdb-patches/2002-12/msg00627.html

RFC: Allow symbol_file_add to take section_offsets table
    http://sources.redhat.com/ml/gdb-patches/2002-11/msg00634.html

gdb/ChangeLog:
2002-12-23  Alexander Larsson <alexl@redhat.com>
	    Jim Blandy  <jimb@redhat.com>

	Add support for executables whose debug info has been separated
	out into a separate file, leaving only a link behind.
	* objfiles.h (struct objfile): New fields: separate_debug_objfile
	and separate_debug_objfile_backlink.
	(put_objfile_before): New declaration.
	* symfile.c: #include "filenames.h".
	(symbol_file_add_with_addrs_or_offsets): If this objfile has its
	debug info in a separate file, read that, too. Save the addrs
	argument, so we can use it again to read the separated debug info;
	syms_from_objfile modifies the table we pass it.
	(reread_symbols): After re-reading an objfile, call
	reread_separate_symbols to refresh its separate debug info
	objfile, if it has one.
	(reread_separate_symbols, find_separate_debug_file,
	get_debug_link_info, separate_debug_file_exists): New functions.
	(debug_file_directory): New global var.
	(_initialize_symfile): Initialize debug_file_directory, and
	provide the new `set debug-file-directory' command to let the user
	change it.
	* objfiles.c (free_objfile): If this objfile has its debug info in
	a separate objfile, free that one too.  If this is itself a
	separate debug info objfile, clear our parent's backlink.
	(put_objfile_before): New function.
	* utils.c (gnu_debuglink_crc32): New function.
	* defs.h (gnu_debuglink_crc32): New declaration.
	* Makefile.in (symfile.o): Note dependency on "filenames.h".
	* configure.in: Handle --with-separate-debug-dir config option.
	* acinclude.m4 (AC_DEFINE_DIR): New macro.
	* acconfig.h (DEBUGDIR): New macro.
	* configure, aclocal.m4, config.in: Regenerated.

gdb/doc/ChangeLog:
2002-12-23  Jim Blandy  <jimb@redhat.com>

	* gdb.texinfo (Separate Debug Files): New section.

Index: gdb/Makefile.in
===================================================================
RCS file: /cvs/src/src/gdb/Makefile.in,v
retrieving revision 1.297.2.1
diff -c -r1.297.2.1 Makefile.in
*** gdb/Makefile.in	23 Dec 2002 08:48:07 -0000	1.297.2.1
--- gdb/Makefile.in	23 Dec 2002 08:57:36 -0000
***************
*** 2247,2253 ****
  	$(gdbcmd_h) $(breakpoint_h) $(language_h) $(complaints_h) \
  	$(demangle_h) $(inferior_h) $(gdb_stabs_h) $(gdb_obstack_h) \
  	$(completer_h) $(bcache_h) $(gdb_string_h) $(gdb_stat_h) $(source_h) \
! 	$(gdb_assert_h) $(readline_h)
  symm-nat.o: symm-nat.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
  	$(target_h) $(regcache_h) $(gdb_stat_h) $(gdbcore_h) $(gdbcore_h)
  symm-tdep.o: symm-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
--- 2247,2253 ----
  	$(gdbcmd_h) $(breakpoint_h) $(language_h) $(complaints_h) \
  	$(demangle_h) $(inferior_h) $(gdb_stabs_h) $(gdb_obstack_h) \
  	$(completer_h) $(bcache_h) $(gdb_string_h) $(gdb_stat_h) $(source_h) \
! 	$(gdb_assert_h) $(readline_h) $(filenames_h)
  symm-nat.o: symm-nat.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
  	$(target_h) $(regcache_h) $(gdb_stat_h) $(gdbcore_h) $(gdbcore_h)
  symm-tdep.o: symm-tdep.c $(defs_h) $(frame_h) $(inferior_h) $(symtab_h) \
Index: gdb/acconfig.h
===================================================================
RCS file: /cvs/src/src/gdb/acconfig.h,v
retrieving revision 1.18
diff -u -r1.18 acconfig.h
--- gdb/acconfig.h	11 Apr 2002 18:32:51 -0000	1.18
+++ gdb/acconfig.h	26 Nov 2002 03:42:20 -0000
@@ -176,3 +176,7 @@
 
 /* nativefile */
 #undef GDB_NM_FILE
+
+/* debugdir */
+#undef DEBUGDIR
+
Index: gdb/acinclude.m4
===================================================================
RCS file: /cvs/src/src/gdb/acinclude.m4,v
retrieving revision 1.5
diff -c -r1.5 acinclude.m4
*** gdb/acinclude.m4	27 Nov 2002 19:13:08 -0000	1.5
--- gdb/acinclude.m4	23 Dec 2002 08:57:37 -0000
***************
*** 918,920 ****
--- 918,935 ----
    fi
    AC_SUBST(LIBICONV)
  ])
+ 
+ dnl written by Guido Draheim <guidod@gmx.de>, original by Alexandre Oliva 
+ dnl Version 1.3 (2001/03/02)
+ dnl source http://www.gnu.org/software/ac-archive/Miscellaneous/ac_define_dir.html
+ 
+ AC_DEFUN([AC_DEFINE_DIR], [
+   test "x$prefix" = xNONE && prefix="$ac_default_prefix"
+   test "x$exec_prefix" = xNONE && exec_prefix='${prefix}'
+   ac_define_dir=`eval echo [$]$2`
+   ac_define_dir=`eval echo [$]ac_define_dir`
+   ifelse($3, ,
+     AC_DEFINE_UNQUOTED($1, "$ac_define_dir"),
+     AC_DEFINE_UNQUOTED($1, "$ac_define_dir", $3))
+ ])
+ 
Index: gdb/configure.in
===================================================================
RCS file: /cvs/src/src/gdb/configure.in,v
retrieving revision 1.96
diff -c -r1.96 configure.in
*** gdb/configure.in	29 Nov 2002 00:29:27 -0000	1.96
--- gdb/configure.in	23 Dec 2002 08:57:41 -0000
***************
*** 237,242 ****
--- 237,250 ----
  AC_CHECK_LIB(socket, socketpair)
  AC_CHECK_FUNCS(socketpair)
  
+ debugdir=${libdir}/debug
+ 	 
+ AC_ARG_WITH(separate-debug-dir,
+ [  --with-separate-debug-dir=path   Look for global separate debug info in this path [LIBDIR/debug]],
+ [debugdir="${withval}"])
+ 	
+ AC_DEFINE_DIR(DEBUGDIR, debugdir)
+ #AC_DEFINE_UNQUOTED(DEBUGDIR, "$debugdir"),
  
  BFD_NEED_DECLARATION(malloc)
  BFD_NEED_DECLARATION(realloc)
Index: gdb/defs.h
===================================================================
RCS file: /cvs/src/src/gdb/defs.h,v
retrieving revision 1.104
diff -c -r1.104 defs.h
*** gdb/defs.h	13 Dec 2002 17:55:49 -0000	1.104
--- gdb/defs.h	23 Dec 2002 08:57:42 -0000
***************
*** 382,387 ****
--- 382,390 ----
  extern char *gdb_realpath (const char *);
  extern char *xfullpath (const char *);
  
+ extern unsigned long gnu_debuglink_crc32 (unsigned long crc,
+                                           unsigned char *buf, size_t len);
+ 
  /* From demangle.c */
  
  extern void set_demangling_style (char *);
Index: gdb/objfiles.c
===================================================================
RCS file: /cvs/src/src/gdb/objfiles.c,v
retrieving revision 1.22
diff -c -r1.22 objfiles.c
*** gdb/objfiles.c	29 Jul 2002 22:55:26 -0000	1.22
--- gdb/objfiles.c	23 Dec 2002 08:57:43 -0000
***************
*** 333,338 ****
--- 333,362 ----
    return (objfile);
  }
  
+ /* Put one object file before a specified on in the global list.
+    This can be used to make sure an object file is destroyed before
+    another when using ALL_OBJFILES_SAFE to free all objfiles. */
+ void
+ put_objfile_before (struct objfile *objfile, struct objfile *before_this)
+ {
+   struct objfile **objp;
+ 
+   unlink_objfile (objfile);
+   
+   for (objp = &object_files; *objp != NULL; objp = &((*objp)->next))
+     {
+       if (*objp == before_this)
+ 	{
+ 	  objfile->next = *objp;
+ 	  *objp = objfile;
+ 	  return;
+ 	}
+     }
+   
+   internal_error (__FILE__, __LINE__,
+ 		  "put_objfile_before: before objfile not in list");
+ }
+ 
  /* Put OBJFILE at the front of the list.  */
  
  void
***************
*** 405,410 ****
--- 429,446 ----
  void
  free_objfile (struct objfile *objfile)
  {
+   if (objfile->separate_debug_objfile)
+     {
+       free_objfile (objfile->separate_debug_objfile);
+     }
+   
+   if (objfile->separate_debug_objfile_backlink)
+     {
+       /* We freed the separate debug file, make sure the base objfile
+ 	 doesn't reference it.  */
+       objfile->separate_debug_objfile_backlink->separate_debug_objfile = NULL;
+     }
+   
    /* First do any symbol file specific actions required when we are
       finished with a particular symbol file.  Note that if the objfile
       is using reusable symbol information (via mmalloc) then each of
Index: gdb/objfiles.h
===================================================================
RCS file: /cvs/src/src/gdb/objfiles.h,v
retrieving revision 1.15
diff -c -r1.15 objfiles.h
*** gdb/objfiles.h	5 Aug 2002 16:17:41 -0000	1.15
--- gdb/objfiles.h	23 Dec 2002 08:57:43 -0000
***************
*** 414,419 ****
--- 414,428 ----
      ExportEntry *export_list;
      int export_list_size;
  
+     /* Link to objfile that contains the debug symbols for this one.
+        One is loaded if this file has an debug link to an existing
+        debug file with the right checksum */
+     struct objfile *separate_debug_objfile;
+ 
+     /* If this is a separate debug object, this is used as a link to the
+        actual executable objfile. */
+     struct objfile *separate_debug_objfile_backlink;
+     
      /* Place to stash various statistics about this objfile */
        OBJSTATS;
    };
***************
*** 504,509 ****
--- 513,520 ----
  extern struct objfile *allocate_objfile (bfd *, int);
  
  extern int build_objfile_section_table (struct objfile *);
+ 
+ extern void put_objfile_before (struct objfile *, struct objfile *);
  
  extern void objfile_to_front (struct objfile *);
  
Index: gdb/symfile.c
===================================================================
RCS file: /cvs/src/src/gdb/symfile.c,v
retrieving revision 1.75.2.2
diff -c -r1.75.2.2 symfile.c
*** gdb/symfile.c	23 Dec 2002 08:50:07 -0000	1.75.2.2
--- gdb/symfile.c	23 Dec 2002 08:57:46 -0000
***************
*** 38,43 ****
--- 38,44 ----
  #include "complaints.h"
  #include "demangle.h"
  #include "inferior.h"		/* for write_pc */
+ #include "filenames.h"		/* for DOSish file names */
  #include "gdb-stabs.h"
  #include "gdb_obstack.h"
  #include "completer.h"
***************
*** 105,110 ****
--- 106,113 ----
  
  static void add_shared_symbol_files_command (char *, int);
  
+ static void reread_separate_symbols (struct objfile *objfile);
+ 
  static void cashier_psymtab (struct partial_symtab *);
  
  bfd *symfile_bfd_open (char *);
***************
*** 149,154 ****
--- 152,159 ----
  
  static void info_ext_lang_command (char *args, int from_tty);
  
+ static char *find_separate_debug_file (struct objfile *objfile);
+ 
  static void init_filename_language_table (void);
  
  void _initialize_symfile (void);
***************
*** 888,894 ****
--- 893,904 ----
  {
    struct objfile *objfile;
    struct partial_symtab *psymtab;
+   char *debugfile;
    bfd *abfd;
+   struct section_addr_info orig_addrs;
+   
+   if (addrs)
+     orig_addrs = *addrs;
  
    /* Open a bfd for the file, and give user a chance to burp if we'd be
       interactively wiping out any existing symbols.  */
***************
*** 963,968 ****
--- 973,1009 ----
  	}
      }
  
+   debugfile = find_separate_debug_file (objfile);
+   if (debugfile)
+     {
+       if (from_tty || info_verbose)
+         {
+           printf_filtered ("loading separate debug info from '%s'",
+                            debugfile);
+           wrap_here ("");
+           gdb_flush (gdb_stdout);
+         }
+ 
+       if (addrs != NULL)
+ 	{
+ 	  objfile->separate_debug_objfile
+             = symbol_file_add (debugfile, from_tty, &orig_addrs, 0, flags);
+ 	}
+       else
+ 	{
+ 	  objfile->separate_debug_objfile
+             = symbol_file_add (debugfile, from_tty, NULL, 0, flags);
+ 	}
+       objfile->separate_debug_objfile->separate_debug_objfile_backlink
+         = objfile;
+       
+       /* Put the separate debug object before the normal one, this is so that
+          usage of the ALL_OBJFILES_SAFE macro will stay safe. */
+       put_objfile_before (objfile->separate_debug_objfile, objfile);
+       
+       xfree (debugfile);
+     }
+   
    if (from_tty || info_verbose)
      {
        if (post_add_symbol_hook)
***************
*** 1058,1063 ****
--- 1099,1239 ----
  #endif
  }
  
+ static char *
+ get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out)
+ {
+   asection *sect;
+   bfd_size_type debuglink_size;
+   unsigned long crc32;
+   char *contents;
+   int crc_offset;
+   unsigned char *p;
+   
+   sect = bfd_get_section_by_name (objfile->obfd, ".gnu_debuglink");
+ 
+   if (sect == NULL)
+     return NULL;
+ 
+   debuglink_size = bfd_section_size (objfile->obfd, sect);
+   
+   contents = xmalloc (debuglink_size);
+   bfd_get_section_contents (objfile->obfd, sect, contents,
+ 			    (file_ptr)0, (bfd_size_type)debuglink_size);
+ 
+   /* Crc value is stored after the filename, aligned up to 4 bytes. */
+   crc_offset = strlen (contents) + 1;
+   crc_offset = (crc_offset + 3) & ~3;
+ 
+   crc32 = bfd_get_32 (objfile->obfd, (bfd_byte *) (contents + crc_offset));
+   
+   *crc32_out = crc32;
+   return contents;
+ }
+ 
+ static int
+ separate_debug_file_exists (const char *name, unsigned long crc)
+ {
+   unsigned long file_crc = 0;
+   int fd;
+   char buffer[8*1024];
+   int count;
+ 
+   fd = open (name, O_RDONLY | O_BINARY);
+   if (fd < 0)
+     return 0;
+ 
+   while ((count = read (fd, buffer, sizeof (buffer))) > 0)
+     file_crc = gnu_debuglink_crc32 (file_crc, buffer, count);
+ 
+   close (fd);
+ 
+   return crc == file_crc;
+ }
+ 
+ static char *debug_file_directory = NULL;
+ 
+ #if ! defined (DEBUG_SUBDIRECTORY)
+ #define DEBUG_SUBDIRECTORY ".debug"
+ #endif
+ 
+ static char *
+ find_separate_debug_file (struct objfile *objfile)
+ {
+   asection *sect;
+   char *basename;
+   char *dir;
+   char *debugfile;
+   char *name_copy;
+   bfd_size_type debuglink_size;
+   unsigned long crc32;
+   int i;
+ 
+   basename = get_debug_link_info (objfile, &crc32);
+ 
+   if (basename == NULL)
+     return NULL;
+   
+   dir = xstrdup (objfile->name);
+ 
+   /* Strip off filename part */
+   for (i = strlen(dir) - 1; i >= 0; i--)
+     {
+       if (IS_DIR_SEPARATOR (dir[i]))
+ 	break;
+     }
+   dir[i+1] = '\0';
+   
+   debugfile = alloca (strlen (debug_file_directory) + 1
+                       + strlen (dir)
+                       + strlen (DEBUG_SUBDIRECTORY)
+                       + strlen ("/")
+                       + strlen (basename) 
+                       + 1);
+ 
+   /* First try in the same directory as the original file.  */
+   strcpy (debugfile, dir);
+   strcat (debugfile, basename);
+ 
+   if (separate_debug_file_exists (debugfile, crc32))
+     {
+       xfree (basename);
+       xfree (dir);
+       return xstrdup (debugfile);
+     }
+   
+   /* Then try in the subdirectory named DEBUG_SUBDIRECTORY.  */
+   strcpy (debugfile, dir);
+   strcat (debugfile, DEBUG_SUBDIRECTORY);
+   strcat (debugfile, "/");
+   strcat (debugfile, basename);
+ 
+   if (separate_debug_file_exists (debugfile, crc32))
+     {
+       xfree (basename);
+       xfree (dir);
+       return xstrdup (debugfile);
+     }
+   
+   /* Then try in the global debugfile directory.  */
+   strcpy (debugfile, debug_file_directory);
+   strcat (debugfile, "/");
+   strcat (debugfile, dir);
+   strcat (debugfile, "/");
+   strcat (debugfile, basename);
+ 
+   if (separate_debug_file_exists (debugfile, crc32))
+     {
+       xfree (basename);
+       xfree (dir);
+       return xstrdup (debugfile);
+     }
+   
+   xfree (basename);
+   xfree (dir);
+   return NULL;
+ }
+ 
+ 
  /* This is the symbol-file command.  Read the file, analyze its
     symbols, and add a struct symtab to a symtab list.  The syntax of
     the command is rather bizarre--(1) buildargv implements various
***************
*** 1903,1908 ****
--- 2079,2086 ----
  	         needs to keep track of (such as _sigtramp, or whatever).  */
  
  	      TARGET_SYMFILE_POSTREAD (objfile);
+ 
+               reread_separate_symbols (objfile);
  	    }
  	}
      }
***************
*** 1910,1915 ****
--- 2088,2160 ----
    if (reread_one)
      clear_symtab_users ();
  }
+ 
+ 
+ /* Handle separate debug info for OBJFILE, which has just been
+    re-read:
+    - If we had separate debug info before, but now we don't, get rid
+      of the separated objfile.
+    - If we didn't have separated debug info before, but now we do,
+      read in the new separated debug info file.
+    - If the debug link points to a different file, toss the old one
+      and read the new one.
+    This function does *not* handle the case where objfile is still
+    using the same separate debug info file, but that file's timestamp
+    has changed.  That case should be handled by the loop in
+    reread_symbols already.  */
+ static void
+ reread_separate_symbols (struct objfile *objfile)
+ {
+   char *debug_file;
+   unsigned long crc32;
+ 
+   /* Does the updated objfile's debug info live in a
+      separate file?  */
+   debug_file = find_separate_debug_file (objfile);
+ 
+   if (objfile->separate_debug_objfile)
+     {
+       /* There are two cases where we need to get rid of
+          the old separated debug info objfile:
+          - if the new primary objfile doesn't have
+          separated debug info, or
+          - if the new primary objfile has separate debug
+          info, but it's under a different filename.
+  
+          If the old and new objfiles both have separate
+          debug info, under the same filename, then we're
+          okay --- if the separated file's contents have
+          changed, we will have caught that when we
+          visited it in this function's outermost
+          loop.  */
+       if (! debug_file
+           || strcmp (debug_file, objfile->separate_debug_objfile->name) != 0)
+         free_objfile (objfile->separate_debug_objfile);
+     }
+ 
+   /* If the new objfile has separate debug info, and we
+      haven't loaded it already, do so now.  */
+   if (debug_file
+       && ! objfile->separate_debug_objfile)
+     {
+       /* Use the same section offset table as objfile itself.
+          Preserve the flags from objfile that make sense.  */
+       objfile->separate_debug_objfile
+         = (symbol_file_add_with_addrs_or_offsets
+            (debug_file,
+             info_verbose, /* from_tty: Don't override the default. */
+             0, /* No addr table.  */
+             objfile->section_offsets, objfile->num_sections,
+             0, /* Not mainline.  See comments about this above.  */
+             objfile->flags & (OBJF_MAPPED | OBJF_REORDERED
+                               | OBJF_SHARED | OBJF_READNOW
+                               | OBJF_USERLOADED)));
+       objfile->separate_debug_objfile->separate_debug_objfile_backlink
+         = objfile;
+     }
+ }
+ 
+ 
  \f
  
  
***************
*** 3418,3421 ****
--- 3663,3681 ----
  		  "cache.\n",
  		  &setlist),
       &showlist);
+ 
+   debug_file_directory = xstrdup (DEBUGDIR);
+   c = (add_set_cmd
+        ("debug-file-directory", class_support, var_string,
+         (char *) &debug_file_directory,
+         "Set the directory where separate debug symbols are searched for.\n"
+         "Separate debug symbols are first searched for in the same\n"
+         "directory as the binary, then in the `" DEBUG_SUBDIRECTORY 
+         "' subdirectory,\n"
+         "and lastly at the path of the directory of the binary with\n"
+         "the global debug-file directory prepended\n",
+         &setlist));
+   add_show_from_set (c, &showlist);
+   set_cmd_completer (c, filename_completer);
+ 
  }
Index: gdb/utils.c
===================================================================
RCS file: /cvs/src/src/gdb/utils.c,v
retrieving revision 1.87
diff -c -r1.87 utils.c
*** gdb/utils.c	30 Nov 2002 16:33:55 -0000	1.87
--- gdb/utils.c	23 Dec 2002 08:57:47 -0000
***************
*** 2809,2811 ****
--- 2809,2883 ----
    xfree (real_path);
    return result;
  }
+ 
+ 
+ /* This is the 32-bit CRC function used by the GNU separate debug
+    facility.  An executable may contain a section named
+    .gnu_debuglink, which holds the name of a separate executable file
+    containing its debug info, and a checksum of that file's contents,
+    computed using this function.  */
+ unsigned long
+ gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len)
+ {
+   static const unsigned long crc32_table[256] =
+     {
+       0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+       0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+       0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+       0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+       0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+       0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+       0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+       0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+       0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+       0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+       0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+       0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+       0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+       0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+       0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+       0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+       0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+       0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+       0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+       0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+       0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+       0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+       0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+       0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+       0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+       0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+       0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+       0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+       0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+       0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+       0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+       0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+       0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+       0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+       0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+       0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+       0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+       0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+       0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+       0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+       0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+       0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+       0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+       0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+       0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+       0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+       0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+       0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+       0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+       0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+       0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+       0x2d02ef8d
+     };
+   unsigned char *end;
+ 
+   crc = ~crc & 0xffffffff;
+   for (end = buf + len; buf < end; ++buf)
+     crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+   return ~crc & 0xffffffff;;
+ }
Index: gdb/doc/gdb.texinfo
===================================================================
RCS file: /cvs/src/src/gdb/doc/gdb.texinfo,v
retrieving revision 1.131
diff -c -r1.131 gdb.texinfo
*** gdb/doc/gdb.texinfo	11 Oct 2002 16:13:15 -0000	1.131
--- gdb/doc/gdb.texinfo	23 Dec 2002 08:58:02 -0000
***************
*** 9802,9807 ****
--- 9802,9808 ----
  
  @menu
  * Files::                       Commands to specify files
+ * Separate Debug Files::        Debugging information in separate files
  * Symbol Errors::               Errors reading symbol files
  @end menu
  
***************
*** 10205,10210 ****
--- 10206,10393 ----
  @item show auto-solib-limit
  Display the current autoloading size threshold, in megabytes.
  @end table
+ 
+ 
+ @node Separate Debug Files
+ @section Debugging Information in Separate Files
+ @cindex separate debugging information files
+ @cindex debugging information in separate files
+ @cindex .debug subdirectories
+ @cindex debugging information directory, global
+ @cindex global debugging information directory
+ 
+ @value{GDBN} allows you to put a program's debugging information in a
+ file separate from the executable itself, in a way that allows
+ @value{GDBN} to find and load the debugging information automatically.
+ Since debugging information can be very large --- sometimes larger
+ than the executable code itself --- some systems distribute debugging
+ information for their executables in separate files, which users can
+ install only when they need to debug a problem.
+ 
+ If an executable's debugging information has been extracted to a
+ separate file, the executable should contain a @dfn{debug link} giving
+ the name of the debugging information file (with no directory
+ components), and a checksum of its contents.  (The exact form of a
+ debug link is described below.)  If the full name of the directory
+ containing the executable is @var{execdir}, and the executable has a
+ debug link that specifies the name @var{debugfile}, then @value{GDBN}
+ will automatically search for the debugging information file in three
+ places:
+ 
+ @itemize @bullet
+ @item
+ the directory containing the executable file (that is, it will look
+ for a file named @file{@var{execdir}/@var{debugfile}},
+ @item
+ a subdirectory of that directory named @file{.debug} (that is, the
+ file @file{@var{execdir}/.debug/@var{debugfile}}, and
+ @item
+ a subdirectory of the global debug file directory that includes the
+ executable's full path, and the name from the link (that is, the file
+ @file{@var{globaldebugdir}/@var{execdir}/@var{debugfile}}, where
+ @var{globaldebugdir} is the global debug file directory, and
+ @var{execdir} has been turned into a relative path).
+ @end itemize
+ @noindent
+ @value{GDBN} checks under each of these names for a debugging
+ information file whose checksum matches that given in the link, and
+ reads the debugging information from the first one it finds.
+ 
+ So, for example, if you ask @value{GDBN} to debug @file{/usr/bin/ls},
+ which has a link containing the name @file{ls.debug}, and the global
+ debug directory is @file{/usr/lib/debug}, then @value{GDBN} will look
+ for debug information in @file{/usr/bin/ls.debug},
+ @file{/usr/bin/.debug/ls.debug}, and
+ @file{/usr/lib/debug/usr/bin/ls.debug}.
+ 
+ You can set the global debugging info directory's name, and view the
+ name @value{GDBN} is currently using.
+ 
+ @table @code
+ 
+ @kindex set debug-file-directory
+ @item set debug-file-directory @var{directory}
+ Set the directory which @value{GDBN} searches for separate debugging
+ information files to @var{directory}.
+ 
+ @kindex show debug-file-directory
+ @item show debug-file-directory
+ Show the directory @value{GDBN} searches for separate debugging
+ information files.
+ 
+ @end table
+ 
+ @cindex .gnu_debuglink sections
+ @cindex debug links
+ A debug link is a special section of the executable file named
+ @code{.gnu_debuglink}.  The section must contain:
+ 
+ @itemize
+ @item
+ A filename, with any leading directory components removed, followed by
+ a zero byte,
+ @item
+ zero to three bytes of padding, as needed to reach the next four-byte
+ boundary within the section, and
+ @item
+ a four-byte CRC checksum, stored in the same endianness used for the
+ executable file itself.  The checksum is computed on the debugging
+ information file's full contents by the function given below, passing
+ zero as the @var{crc} argument.
+ @end itemize
+ 
+ Any executable file format can carry a debug link, as long as it can
+ contain a section named @code{.gnu_debuglink} with the contents
+ described above.
+ 
+ The debugging information file itself should be an ordinary
+ executable, containing a full set of linker symbols, sections, and
+ debugging information.  The sections of the debugging information file
+ should have the same names, addresses and sizes as the original file,
+ but they need not contain any data --- much like a @code{.bss} section
+ in an ordinary executable.
+ 
+ As of December 2002, there is no standard GNU utility to produce
+ separated executable / debugging information file pairs.  Ulrich
+ Drepper's @file{elfutils} package, starting with version 0.53,
+ contains a version of the @code{strip} command such that the command
+ @samp{strip foo -f foo.debug} removes the debugging information from
+ the executable file @file{foo}, places it in the file
+ @file{foo.debug}, and leaves behind a debug link in @file{foo}.
+ 
+ Since there are many different ways to compute CRC's (different
+ polynomials, reversals, byte ordering, etc.), the simplest way to
+ describe the CRC used in @code{.gnu_debuglink} sections is to give its
+ complete code:
+ 
+ @kindex gnu_debuglink_crc32
+ @example
+ unsigned long
+ gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len)
+ @{
+   static const unsigned long crc32_table[256] =
+     @{
+       0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419,
+       0x706af48f, 0xe963a535, 0x9e6495a3, 0x0edb8832, 0x79dcb8a4,
+       0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07,
+       0x90bf1d91, 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
+       0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, 0x136c9856,
+       0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9,
+       0xfa0f3d63, 0x8d080df5, 0x3b6e20c8, 0x4c69105e, 0xd56041e4,
+       0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
+       0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3,
+       0x45df5c75, 0xdcd60dcf, 0xabd13d59, 0x26d930ac, 0x51de003a,
+       0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599,
+       0xb8bda50f, 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
+       0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, 0x76dc4190,
+       0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f,
+       0x9fbfe4a5, 0xe8b8d433, 0x7807c9a2, 0x0f00f934, 0x9609a88e,
+       0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
+       0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed,
+       0x1b01a57b, 0x8208f4c1, 0xf50fc457, 0x65b0d9c6, 0x12b7e950,
+       0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3,
+       0xfbd44c65, 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
+       0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, 0x4369e96a,
+       0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5,
+       0xaa0a4c5f, 0xdd0d7cc9, 0x5005713c, 0x270241aa, 0xbe0b1010,
+       0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
+       0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17,
+       0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, 0xedb88320, 0x9abfb3b6,
+       0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615,
+       0x73dc1683, 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
+       0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, 0xf00f9344,
+       0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb,
+       0x196c3671, 0x6e6b06e7, 0xfed41b76, 0x89d32be0, 0x10da7a5a,
+       0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
+       0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1,
+       0xa6bc5767, 0x3fb506dd, 0x48b2364b, 0xd80d2bda, 0xaf0a1b4c,
+       0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef,
+       0x4669be79, 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
+       0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, 0xc5ba3bbe,
+       0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31,
+       0x2cd99e8b, 0x5bdeae1d, 0x9b64c2b0, 0xec63f226, 0x756aa39c,
+       0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
+       0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b,
+       0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, 0x86d3d2d4, 0xf1d4e242,
+       0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1,
+       0x18b74777, 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
+       0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, 0xa00ae278,
+       0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7,
+       0x4969474d, 0x3e6e77db, 0xaed16a4a, 0xd9d65adc, 0x40df0b66,
+       0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
+       0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605,
+       0xcdd70693, 0x54de5729, 0x23d967bf, 0xb3667a2e, 0xc4614ab8,
+       0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b,
+       0x2d02ef8d
+     @};
+   unsigned char *end;
+ 
+   crc = ~crc & 0xffffffff;
+   for (end = buf + len; buf < end; ++buf)
+     crc = crc32_table[(crc ^ *buf) & 0xff] ^ (crc >> 8);
+   return ~crc & 0xffffffff;;
+ @}
+ @end example
  
  @node Symbol Errors
  @section Errors reading symbol files


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

* Re: [repost] Re: RFC: support debug info in separate files
  2002-12-23  1:58 ` [repost] " Jim Blandy
@ 2002-12-23  6:59   ` Eli Zaretskii
  2003-01-23 23:04   ` Jim Blandy
  1 sibling, 0 replies; 14+ messages in thread
From: Eli Zaretskii @ 2002-12-23  6:59 UTC (permalink / raw)
  To: Jim Blandy; +Cc: gdb-patches


On 23 Dec 2002, Jim Blandy wrote:

> - The documentation has been completely rewritten, and provides much
>   more detail.  It includes all the information needed to implement

Thanks.  The doco patch is approved (assuming that the code is 
accepted).  I have a few minor change requests:

> + @cindex .debug subdirectories

Please use the normal markup in @cindex entries, in this case .debug 
should be in @file...

> + @cindex .gnu_debuglink sections

...and here .gnu_debuglink should be in @code.

> + Drepper's @file{elfutils} package, starting with version 0.53,
> + contains a version of the @code{strip} command such that the command
> + @samp{strip foo -f foo.debug} removes the debugging information from

I think it's better to put commands users type in @kbd instead of @samp.  
But I don't object to @samp if you like it better.

> + @kindex gnu_debuglink_crc32
> + @example
> + unsigned long
> + gnu_debuglink_crc32 (unsigned long crc, unsigned char *buf, size_t len)

IIRC, we decided to use @smallexample throughout.  Also, the last line 
above is too long even for @smallexample (will produce overfull hbox 
warnings from TeX), so please break it into 2 lines.

Thanks again for such a clear and concise description.


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

* Re: [repost] Re: RFC: support debug info in separate files
  2002-12-23  1:58 ` [repost] " Jim Blandy
  2002-12-23  6:59   ` Eli Zaretskii
@ 2003-01-23 23:04   ` Jim Blandy
  1 sibling, 0 replies; 14+ messages in thread
From: Jim Blandy @ 2003-01-23 23:04 UTC (permalink / raw)
  To: gdb-patches


I've committed this patch, after making the changes to the
documentation that Eli suggested.  I'll take care of the maint.exp
regressions in a bit.

Jim Blandy <jimb@redhat.com> writes:

> [My previous post omitted the patch to acconfig.h.]
> 
> Here's a new shot at the separate debug patch.  It's updated to apply
> to the current branch, and I believe I've addressed the comments folks
> have made:
> - The documentation has been completely rewritten, and provides much
>   more detail.  It includes all the information needed to implement
>   `strip -f' in the GNU binutils, for example.  It is better indexed.
> - The name ".debug" can be overridden by xm- files for systems that
>   can't handle names like that.
> - The CRC function has a more descriptive name.
> 
> Using separate debug info does introduce three new test suite
> failures:
> FAIL: gdb.base/maint.exp: maint print objfiles: psymtabs
> FAIL: gdb.base/maint.exp: maint print objfiles: symtabs
> FAIL: gdb.base/maint.exp: maint print msymbols
> 
> These do not reflect GDB misbehavior: the objfile in question has no
> psymtabs, symtabs, or msymbols, but the test suite assumes they
> should.  I think 'maint print objfiles' should print something
> indicating when an objfile has an associated separated debug file, and
> that the test should recognize and cope with this, but it seems like
> that should be a separate patch.
> 
> Before you can apply this patch, you'll need to apply the following:
> 
> Re: RFC: allow syms_from_objfile to take a section offset table directly
>     http://sources.redhat.com/ml/gdb-patches/2002-12/msg00627.html
> 
> RFC: Allow symbol_file_add to take section_offsets table
>     http://sources.redhat.com/ml/gdb-patches/2002-11/msg00634.html
> 
> gdb/ChangeLog:
> 2002-12-23  Alexander Larsson <alexl@redhat.com>
> 	    Jim Blandy  <jimb@redhat.com>
> 
> 	Add support for executables whose debug info has been separated
> 	out into a separate file, leaving only a link behind.
> 	* objfiles.h (struct objfile): New fields: separate_debug_objfile
> 	and separate_debug_objfile_backlink.
> 	(put_objfile_before): New declaration.
> 	* symfile.c: #include "filenames.h".
> 	(symbol_file_add_with_addrs_or_offsets): If this objfile has its
> 	debug info in a separate file, read that, too. Save the addrs
> 	argument, so we can use it again to read the separated debug info;
> 	syms_from_objfile modifies the table we pass it.
> 	(reread_symbols): After re-reading an objfile, call
> 	reread_separate_symbols to refresh its separate debug info
> 	objfile, if it has one.
> 	(reread_separate_symbols, find_separate_debug_file,
> 	get_debug_link_info, separate_debug_file_exists): New functions.
> 	(debug_file_directory): New global var.
> 	(_initialize_symfile): Initialize debug_file_directory, and
> 	provide the new `set debug-file-directory' command to let the user
> 	change it.
> 	* objfiles.c (free_objfile): If this objfile has its debug info in
> 	a separate objfile, free that one too.  If this is itself a
> 	separate debug info objfile, clear our parent's backlink.
> 	(put_objfile_before): New function.
> 	* utils.c (gnu_debuglink_crc32): New function.
> 	* defs.h (gnu_debuglink_crc32): New declaration.
> 	* Makefile.in (symfile.o): Note dependency on "filenames.h".
> 	* configure.in: Handle --with-separate-debug-dir config option.
> 	* acinclude.m4 (AC_DEFINE_DIR): New macro.
> 	* acconfig.h (DEBUGDIR): New macro.
> 	* configure, aclocal.m4, config.in: Regenerated.
> 
> gdb/doc/ChangeLog:
> 2002-12-23  Jim Blandy  <jimb@redhat.com>
> 
> 	* gdb.texinfo (Separate Debug Files): New section.


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

end of thread, other threads:[~2003-01-23 23:04 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-11-25 20:27 RFC: support debug info in separate files Jim Blandy
2002-11-25 22:34 ` Eli Zaretskii
2002-12-09 19:55   ` Jim Blandy
2002-12-10 12:19     ` Eli Zaretskii
2002-12-09 22:13 ` Elena Zannoni
2002-12-10  8:13   ` Andrew Cagney
2002-12-10  9:14     ` Elena Zannoni
2002-12-10 11:39       ` Andrew Cagney
2002-12-10 12:43   ` Eli Zaretskii
2002-12-14 16:48   ` Jim Blandy
2002-12-23  1:25 ` Jim Blandy
2002-12-23  1:58 ` [repost] " Jim Blandy
2002-12-23  6:59   ` Eli Zaretskii
2003-01-23 23:04   ` Jim Blandy

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox