From 32a0e54790b75f1da48593148e72d64f68f447aa Mon Sep 17 00:00:00 2001 From: Jan Kratochvil Date: Wed, 11 Nov 2009 05:04:34 +0000 Subject: [PATCH] gdb/ * symfile.c (separate_debug_file_exists): Change parameter parent_name to parent_objfile. New variables parent_stat and abfd_stat. Call strcmp and then bfd_stat functions to verify if NAME matches. (find_separate_debug_file): Update the passed parameter at caller. --- gdb/ChangeLog | 7 +++++++ gdb/symfile.c | 42 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 43 insertions(+), 6 deletions(-) diff --git a/gdb/ChangeLog b/gdb/ChangeLog index dbc39888bf..c969bd05ea 100644 --- a/gdb/ChangeLog +++ b/gdb/ChangeLog @@ -1,3 +1,10 @@ +2009-11-11 Jan Kratochvil + + * symfile.c (separate_debug_file_exists): Change parameter parent_name + to parent_objfile. New variables parent_stat and abfd_stat. Call + strcmp and then bfd_stat functions to verify if NAME matches. + (find_separate_debug_file): Update the passed parameter at caller. + 2009-11-11 Jan Kratochvil * objfiles.c (objfile_relocate): Update also the field psymtabs_addrmap. diff --git a/gdb/symfile.c b/gdb/symfile.c index d2f2834f7f..30ae0dfccc 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -1308,12 +1308,22 @@ get_debug_link_info (struct objfile *objfile, unsigned long *crc32_out) static int separate_debug_file_exists (const char *name, unsigned long crc, - const char *parent_name) + struct objfile *parent_objfile) { unsigned long file_crc = 0; bfd *abfd; gdb_byte buffer[8*1024]; int count; + struct stat parent_stat, abfd_stat; + + /* Find a separate debug info file as if symbols would be present in + PARENT_OBJFILE itself this function would not be called. .gnu_debuglink + section can contain just the basename of PARENT_OBJFILE without any + ".debug" suffix as "/usr/lib/debug/path/to/file" is a separate tree where + the separate debug infos with the same basename can exist. */ + + if (strcmp (name, parent_objfile->name) == 0) + return 0; if (remote_filename_p (name)) abfd = remote_bfd_open (name, gnutarget); @@ -1323,6 +1333,26 @@ separate_debug_file_exists (const char *name, unsigned long crc, if (!abfd) return 0; + /* Verify symlinks were not the cause of strcmp name difference above. + + Some operating systems, e.g. Windows, do not provide a meaningful + st_ino; they always set it to zero. (Windows does provide a + meaningful st_dev.) Do not indicate a duplicate library in that + case. While there is no guarantee that a system that provides + meaningful inode numbers will never set st_ino to zero, this is + merely an optimization, so we do not need to worry about false + negatives. */ + + if (bfd_stat (abfd, &abfd_stat) == 0 + && bfd_stat (parent_objfile->obfd, &parent_stat) == 0 + && abfd_stat.st_dev == parent_stat.st_dev + && abfd_stat.st_ino == parent_stat.st_ino + && abfd_stat.st_ino != 0) + { + bfd_close (abfd); + return 0; + } + while ((count = bfd_bread (buffer, sizeof (buffer), abfd)) > 0) file_crc = gnu_debuglink_crc32 (file_crc, buffer, count); @@ -1332,7 +1362,7 @@ separate_debug_file_exists (const char *name, unsigned long crc, { warning (_("the debug information found in \"%s\"" " does not match \"%s\" (CRC mismatch).\n"), - name, parent_name); + name, parent_objfile->name); return 0; } @@ -1422,7 +1452,7 @@ find_separate_debug_file (struct objfile *objfile) strcpy (debugfile, dir); strcat (debugfile, basename); - if (separate_debug_file_exists (debugfile, crc32, objfile->name)) + if (separate_debug_file_exists (debugfile, crc32, objfile)) goto cleanup_return_debugfile; /* Then try in the subdirectory named DEBUG_SUBDIRECTORY. */ @@ -1431,7 +1461,7 @@ find_separate_debug_file (struct objfile *objfile) strcat (debugfile, "/"); strcat (debugfile, basename); - if (separate_debug_file_exists (debugfile, crc32, objfile->name)) + if (separate_debug_file_exists (debugfile, crc32, objfile)) goto cleanup_return_debugfile; /* Then try in the global debugfile directories. @@ -1457,7 +1487,7 @@ find_separate_debug_file (struct objfile *objfile) strcat (debugfile, dir); strcat (debugfile, basename); - if (separate_debug_file_exists (debugfile, crc32, objfile->name)) + if (separate_debug_file_exists (debugfile, crc32, objfile)) goto cleanup_return_debugfile; /* If the file is in the sysroot, try using its base path in the @@ -1472,7 +1502,7 @@ find_separate_debug_file (struct objfile *objfile) strcat (debugfile, "/"); strcat (debugfile, basename); - if (separate_debug_file_exists (debugfile, crc32, objfile->name)) + if (separate_debug_file_exists (debugfile, crc32, objfile)) goto cleanup_return_debugfile; } -- 2.34.1