gdb/ChangeLog:

2003-01-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:
2003-01-23  Jim Blandy  <jimb@redhat.com>

	* gdb.texinfo (Separate Debug Files): New section.
This commit is contained in:
Jim Blandy 2003-01-23 23:03:32 +00:00
parent 2e9d253267
commit 5b5d99cf4d
14 changed files with 1249 additions and 580 deletions

View File

@ -1,3 +1,37 @@
2003-01-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.
2003-01-22 Jim Blandy <jimb@redhat.com>
* symfile.c (symbol_file_add_with_addrs_or_offsets): New function,

View File

@ -2220,7 +2220,7 @@ symfile.o: symfile.c $(defs_h) $(symtab_h) $(gdbtypes_h) $(gdbcore_h) \
$(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)
$(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) \

View File

@ -927,3 +927,18 @@ AC_DEFUN([AC_GNU_SOURCE],
AC_BEFORE([$0], [AC_TRY_RUN])dnl
AC_DEFINE([_GNU_SOURCE])
])
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))
])

23
gdb/aclocal.m4 vendored
View File

@ -1,6 +1,6 @@
dnl aclocal.m4 generated automatically by aclocal 1.4-p5
dnl aclocal.m4 generated automatically by aclocal 1.4
dnl Copyright (C) 1994, 1995-8, 1999, 2001 Free Software Foundation, Inc.
dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
@ -936,12 +936,27 @@ AC_BEFORE([$0], [AC_TRY_RUN])dnl
AC_DEFINE([_GNU_SOURCE])
])
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))
])
# Add --enable-maintainer-mode option to configure.
# From Jim Meyering
# serial 1
AC_DEFUN([AM_MAINTAINER_MODE],
AC_DEFUN(AM_MAINTAINER_MODE,
[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
dnl maintainer-mode is disabled by default
AC_ARG_ENABLE(maintainer-mode,
@ -958,7 +973,7 @@ AC_DEFUN([AM_MAINTAINER_MODE],
# Define a conditional.
AC_DEFUN([AM_CONDITIONAL],
AC_DEFUN(AM_CONDITIONAL,
[AC_SUBST($1_TRUE)
AC_SUBST($1_FALSE)
if $2; then

View File

@ -416,6 +416,9 @@
/* Name of this package. */
#undef PACKAGE
/* Global directory for separate debug files. */
#undef DEBUGDIR
/* Define to BFD's default architecture. */
#undef DEFAULT_BFD_ARCH

1172
gdb/configure vendored

File diff suppressed because it is too large Load Diff

View File

@ -47,6 +47,15 @@ ALL_LINGUAS=
CY_GNU_GETTEXT
AC_DEFINE(PACKAGE, "gdb", [Name of this package. ])
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,
[Global directory for separate debug files. ])
#AC_DEFINE_UNQUOTED(DEBUGDIR, "$debugdir"),
dnl List of object files added by configure.

View File

@ -380,6 +380,9 @@ extern void *address_to_host_pointer (CORE_ADDR addr);
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 *);

View File

@ -1,3 +1,7 @@
2003-01-23 Jim Blandy <jimb@redhat.com>
* gdb.texinfo (Separate Debug Files): New section.
2003-01-22 Daniel Jacobowitz <drow@mvista.com>
* gdb.texinfo (Maintenance Commands): Add "maint set profile"

View File

@ -9342,6 +9342,7 @@ program. To debug a core dump of a previous run, you must also tell
@menu
* Files:: Commands to specify files
* Separate Debug Files:: Debugging information in separate files
* Symbol Errors:: Errors reading symbol files
@end menu
@ -9789,6 +9790,190 @@ set @samp{solib-absolute-prefix} to a nonexistant directory to prevent
Display the current shared library search path.
@end table
@node Separate Debug Files
@section Debugging Information in Separate Files
@cindex separate debugging information files
@cindex debugging information in separate files
@cindex @file{.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 @code{.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
@kbd{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 the
complete code for a function that computes it:
@kindex @code{gnu_debuglink_crc32}
@smallexample
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 smallexample
@node Symbol Errors
@section Errors reading symbol files

View File

@ -333,6 +333,30 @@ allocate_objfile (bfd *abfd, int flags)
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 @@ unlink_objfile (struct objfile *objfile)
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

View File

@ -414,6 +414,15 @@ struct objfile
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;
};
@ -505,6 +514,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 *);
extern void unlink_objfile (struct objfile *);

View File

@ -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"
@ -105,6 +106,8 @@ static void add_symbol_file_command (char *, int);
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,6 +152,8 @@ static void set_ext_lang_command (char *args, int from_tty);
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,7 +893,12 @@ symbol_file_add_with_addrs_or_offsets (char *name, int from_tty,
{
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,6 +973,37 @@ symbol_file_add_with_addrs_or_offsets (char *name, int from_tty,
}
}
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,6 +1099,141 @@ symbol_file_clear (int from_tty)
#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,6 +2079,8 @@ reread_symbols (void)
needs to keep track of (such as _sigtramp, or whatever). */
TARGET_SYMFILE_POSTREAD (objfile);
reread_separate_symbols (objfile);
}
}
}
@ -1910,6 +2088,73 @@ reread_symbols (void)
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;
}
}
@ -3411,4 +3656,19 @@ Usage: set extension-language .foo bar",
"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);
}

View File

@ -2805,3 +2805,75 @@ xfullpath (const char *filename)
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;;
}