[PATCH 4/5] Add "target:" filename handling to find_separate_debug_file

Gary Benson
2015-06-16T09:48:00Z

This commit updates find_separate_debug_file to handle filenames
prefixed with "target:". The same-directory and DEBUG_SUBDIRECTORY
locations are checked with the prefix if supplied. The debugdir
location is checked both with and without the prefix if one is
supplied. This makes GDB able to fetch separate debug files from
remote targets and from inferiors in containers.

gdb/ChangeLog:

* gdb/symfile.c (build_debug_file_name): New argument "prefix".
(find_separate_debug_file): Separate TARGET_SYSROOT_PREFIX from
dir. In debugdir loop, also try location prepended with dir's
prefix if one was supplied.
---
gdb/ChangeLog | 7 +++++++
gdb/symfile.c | 47 +++++++++++++++++++++++++++++++++++++----------
2 files changed, 44 insertions(+), 10 deletions(-)

diff --git a/gdb/symfile.c b/gdb/symfile.c
index bae144e..0cc940a 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -1434,16 +1434,17 @@ separate_debug_file_exists (const char *name, unsigned long crc,
/* Build the filename of a separate debug file from an arbitrary
number of components. Returns an xmalloc'd string that must
be be freed by the caller. The final argument of this function
- must be NULL to mark the end the argument list. */
+ must be NULL to mark the end the argument list. PREFIX will
+ be prepended to the result with no directory separator. */

static char *
-build_debug_file_name (const char *first, ...)
+build_debug_file_name (const char *prefix, const char *first, ...)
{
va_list ap;
const char *arg, *last;
VEC (char_ptr) *args = NULL;
struct cleanup *back_to = make_cleanup_free_char_ptr_vec (args);
- int bufsiz = 0;
+ int bufsiz = strlen (prefix);
char *buf, *tmp;
int i;

@@ -1495,7 +1496,7 @@ build_debug_file_name (const char *first, ...)
bufsiz += 1; /* Terminator. */

buf = xmalloc (bufsiz);
- buf[0] = '\0';
+ strcpy (buf, prefix);
for (i = 0; VEC_iterate (char_ptr, args, i, tmp); i++)
strcat (buf, tmp);
gdb_assert (bufsiz == strlen (buf) + 1);
@@ -1537,15 +1538,25 @@ find_separate_debug_file (const char *dir,
struct cleanup *back_to;
int ix;
const char *altdir = NULL;
+ const char *no_prefix = "";
+ const char *dir_prefix = no_prefix;
+
+ /* Separate TARGET_SYSROOT_PREFIX from directory. */
+ if (is_target_filename (dir))
+ {
+ dir_prefix = TARGET_SYSROOT_PREFIX;
+ dir += strlen (dir_prefix);
+ }

/* First try in the same directory as the original file. */
- debugfile = build_debug_file_name (dir, debuglink, NULL);
+ debugfile = build_debug_file_name (dir_prefix, dir, debuglink, NULL);
if (separate_debug_file_exists (debugfile, crc32, objfile))
return debugfile;
xfree (debugfile);

/* Then try in the subdirectory named DEBUG_SUBDIRECTORY. */
- debugfile = build_debug_file_name (dir, DEBUG_SUBDIRECTORY,
+ debugfile = build_debug_file_name (dir_prefix, dir,
+ DEBUG_SUBDIRECTORY,
debuglink, NULL);
if (separate_debug_file_exists (debugfile, crc32, objfile))
return debugfile;
@@ -1575,8 +1586,24 @@ find_separate_debug_file (const char *dir,

for (ix = 0; VEC_iterate (char_ptr, debugdir_vec, ix, debugdir); ++ix)
{
- debugfile = build_debug_file_name (debugdir, dir, debuglink,
- NULL);
+ /* First try with TARGET_SYSROOT_PREFIX if that's how DIR was
+ supplied. */
+ if (dir_prefix != no_prefix)
+ {
+ debugfile = build_debug_file_name (dir_prefix, debugdir, dir,
+ debuglink, NULL);
+ if (separate_debug_file_exists (debugfile, crc32, objfile))
+ {
+ do_cleanups (back_to);
+ return debugfile;
+ }
+ xfree (debugfile);
+ }
+
+ /* Try the same location but without TARGET_SYSROOT_PREFIX
+ (i.e. on the local filesystem). */
+ debugfile = build_debug_file_name (no_prefix, debugdir, dir,
+ debuglink, NULL);
if (separate_debug_file_exists (debugfile, crc32, objfile))
{
do_cleanups (back_to);
@@ -1586,8 +1613,8 @@ find_separate_debug_file (const char *dir,

if (altdir != NULL)
{
- debugfile = build_debug_file_name (debugdir, altdir,
- debuglink, NULL);
+ debugfile = build_debug_file_name (no_prefix, debugdir,
+ altdir, debuglink, NULL);
if (separate_debug_file_exists (debugfile, crc32, objfile))
{
do_cleanups (back_to);
--
1.7.1