From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 89594 invoked by alias); 16 Jun 2015 09:42:56 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Received: (qmail 89446 invoked by uid 89); 16 Jun 2015 09:42:56 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-1.8 required=5.0 tests=AWL,BAYES_00,KAM_LAZY_DOMAIN_SECURITY,RP_MATCHES_RCVD,SPF_HELO_PASS autolearn=no version=3.3.2 X-HELO: mx1.redhat.com Received: from mx1.redhat.com (HELO mx1.redhat.com) (209.132.183.28) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES256-GCM-SHA384 encrypted) ESMTPS; Tue, 16 Jun 2015 09:42:54 +0000 Received: from int-mx14.intmail.prod.int.phx2.redhat.com (int-mx14.intmail.prod.int.phx2.redhat.com [10.5.11.27]) by mx1.redhat.com (Postfix) with ESMTPS id D4500B1F89; Tue, 16 Jun 2015 09:42:52 +0000 (UTC) Received: from blade.nx (ovpn-116-89.ams2.redhat.com [10.36.116.89]) by int-mx14.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t5G9gqY8017641; Tue, 16 Jun 2015 05:42:52 -0400 Received: from blade.nx (localhost [127.0.0.1]) by blade.nx (Postfix) with ESMTP id 81DD5262FFE; Tue, 16 Jun 2015 10:42:51 +0100 (BST) From: Gary Benson To: gdb-patches@sourceware.org Cc: =?UTF-8?q?C=C3=A9dric=20Buissart?= Subject: [PATCH 1/5] Introduce build_debug_file_name Date: Tue, 16 Jun 2015 09:42:00 -0000 Message-Id: <1434447768-17328-2-git-send-email-gbenson@redhat.com> In-Reply-To: <1434447768-17328-1-git-send-email-gbenson@redhat.com> References: <1434447768-17328-1-git-send-email-gbenson@redhat.com> X-IsSubscribed: yes X-SW-Source: 2015-06/txt/msg00340.txt.bz2 This commit introduces a new function build_debug_file_name which concatenates a series of filename components into a filename. find_separate_debug_file is updated to use build_debug_file_name. A later commit in this series will extend build_debug_file_name to correctly handle "target:" prefixes, so it is convenient to have filename building pulled out into one function. For now the only functional change here is that the original code sometimes generated filenames with repeated directory separators while the new code does not. gdb/ChangeLog: * gdb/symfile.c (build_debug_file_name): New function. (find_separate_debug_file): Use the above to build filenames. --- gdb/ChangeLog | 5 ++ gdb/symfile.c | 117 +++++++++++++++++++++++++++++++++++++++++--------------- 2 files changed, 90 insertions(+), 32 deletions(-) diff --git a/gdb/symfile.c b/gdb/symfile.c index 0c35ffa..799133a 100644 --- a/gdb/symfile.c +++ b/gdb/symfile.c @@ -1431,6 +1431,79 @@ separate_debug_file_exists (const char *name, unsigned long crc, return 1; } +/* 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. */ + +static char * +build_debug_file_name (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; + char *buf, *tmp; + int i; + + va_start (ap, first); + for (arg = first; arg; arg = va_arg (ap, const char *)) + last = arg; + va_end (ap); + + va_start (ap, first); + for (arg = first; arg; arg = va_arg (ap, const char *)) + { + if (arg == last) + tmp = xstrdup (arg); + else + { + int len; + + /* Strip leading separators from subdirectories. */ + if (arg != first) + { + while (*arg != '\0' && IS_DIR_SEPARATOR (*arg)) + arg++; + } + + /* Strip trailing separators. */ + len = strlen (arg); + + while (len > 0 && IS_DIR_SEPARATOR (arg[len - 1])) + len--; + + if (len > 0) + { + tmp = xmalloc (len + strlen (SLASH_STRING) + 1); + memcpy (tmp, arg, len); + strcpy (tmp + len, SLASH_STRING); + } + else + tmp = NULL; + } + + if (tmp != NULL) + { + VEC_safe_push (char_ptr, args, tmp); + bufsiz += strlen (tmp); + } + } + va_end (ap); + + bufsiz += 1; /* Terminator. */ + + buf = xmalloc (bufsiz); + buf[0] = '\0'; + for (i = 0; VEC_iterate (char_ptr, args, i, tmp); i++) + strcat (buf, tmp); + gdb_assert (bufsiz == strlen (buf) + 1); + + do_cleanups (back_to); + return buf; +} + char *debug_file_directory = NULL; static void show_debug_file_directory (struct ui_file *file, int from_tty, @@ -1461,38 +1534,22 @@ find_separate_debug_file (const char *dir, { char *debugdir; char *debugfile; - int i; VEC (char_ptr) *debugdir_vec; struct cleanup *back_to; int ix; - /* Set I to max (strlen (canon_dir), strlen (dir)). */ - i = strlen (dir); - if (canon_dir != NULL && strlen (canon_dir) > i) - i = strlen (canon_dir); - - debugfile = xmalloc (strlen (debug_file_directory) + 1 - + i - + strlen (DEBUG_SUBDIRECTORY) - + strlen ("/") - + strlen (debuglink) - + 1); - /* First try in the same directory as the original file. */ - strcpy (debugfile, dir); - strcat (debugfile, debuglink); - + debugfile = build_debug_file_name (dir, debuglink, NULL); if (separate_debug_file_exists (debugfile, crc32, objfile)) return debugfile; + xfree (debugfile); /* Then try in the subdirectory named DEBUG_SUBDIRECTORY. */ - strcpy (debugfile, dir); - strcat (debugfile, DEBUG_SUBDIRECTORY); - strcat (debugfile, "/"); - strcat (debugfile, debuglink); - + debugfile = build_debug_file_name (dir, DEBUG_SUBDIRECTORY, + debuglink, NULL); if (separate_debug_file_exists (debugfile, crc32, objfile)) return debugfile; + xfree (debugfile); /* Then try in the global debugfile directories. @@ -1504,16 +1561,14 @@ find_separate_debug_file (const char *dir, for (ix = 0; VEC_iterate (char_ptr, debugdir_vec, ix, debugdir); ++ix) { - strcpy (debugfile, debugdir); - strcat (debugfile, "/"); - strcat (debugfile, dir); - strcat (debugfile, debuglink); - + debugfile = build_debug_file_name (debugdir, dir, debuglink, + NULL); if (separate_debug_file_exists (debugfile, crc32, objfile)) { do_cleanups (back_to); return debugfile; } + xfree (debugfile); /* If the file is in the sysroot, try using its base path in the global debugfile directory. */ @@ -1522,21 +1577,19 @@ find_separate_debug_file (const char *dir, strlen (gdb_sysroot)) == 0 && IS_DIR_SEPARATOR (canon_dir[strlen (gdb_sysroot)])) { - strcpy (debugfile, debugdir); - strcat (debugfile, canon_dir + strlen (gdb_sysroot)); - strcat (debugfile, "/"); - strcat (debugfile, debuglink); - + debugfile = build_debug_file_name (debugdir, canon_dir + + strlen (gdb_sysroot), + debuglink, NULL); if (separate_debug_file_exists (debugfile, crc32, objfile)) { do_cleanups (back_to); return debugfile; } + xfree (debugfile); } } do_cleanups (back_to); - xfree (debugfile); return NULL; } -- 1.7.1