[repost] Re: RFC: support debug info in separate files

Jim Blandy
2002-12-23T09:41:02Z

[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