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:
parent
2e9d253267
commit
5b5d99cf4d
@ -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,
|
||||
|
@ -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) \
|
||||
|
@ -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
23
gdb/aclocal.m4
vendored
@ -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
|
||||
|
@ -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
1172
gdb/configure
vendored
File diff suppressed because it is too large
Load Diff
@ -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.
|
||||
|
||||
|
@ -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 *);
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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 *);
|
||||
|
260
gdb/symfile.c
260
gdb/symfile.c
@ -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);
|
||||
|
||||
}
|
||||
|
72
gdb/utils.c
72
gdb/utils.c
@ -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;;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user