From patchwork Fri Aug 21 21:22:37 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Kratochvil X-Patchwork-Id: 8366 Received: (qmail 113471 invoked by alias); 21 Aug 2015 21:22:46 -0000 Mailing-List: contact gdb-patches-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Subscribe: List-Archive: List-Post: List-Help: , Sender: gdb-patches-owner@sourceware.org Delivered-To: mailing list gdb-patches@sourceware.org Received: (qmail 113459 invoked by uid 89); 21 Aug 2015 21:22:45 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.6 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; Fri, 21 Aug 2015 21:22:41 +0000 Received: from int-mx10.intmail.prod.int.phx2.redhat.com (int-mx10.intmail.prod.int.phx2.redhat.com [10.5.11.23]) by mx1.redhat.com (Postfix) with ESMTPS id 5FA7B92469 for ; Fri, 21 Aug 2015 21:22:39 +0000 (UTC) Received: from host1.jankratochvil.net (ovpn-116-22.ams2.redhat.com [10.36.116.22]) by int-mx10.intmail.prod.int.phx2.redhat.com (8.14.4/8.14.4) with ESMTP id t7LLMblI030433 for ; Fri, 21 Aug 2015 17:22:38 -0400 Subject: [PATCH v12 18/32] Refactor openp() to return file_location From: Jan Kratochvil To: gdb-patches@sourceware.org Date: Fri, 21 Aug 2015 23:22:37 +0200 Message-ID: <20150821212237.6673.80802.stgit@host1.jankratochvil.net> In-Reply-To: <20150821212006.6673.35100.stgit@host1.jankratochvil.net> References: <20150821212006.6673.35100.stgit@host1.jankratochvil.net> User-Agent: StGit/0.17.1-dirty MIME-Version: 1.0 X-IsSubscribed: yes Hi, openp() remains as a backward compatibility wrapper around renamed openp->openp_file(). Jan gdb/ChangeLog 2015-08-19 Jan Kratochvil * defs.h (enum openp_flags): Remove OPF_OPEN_RW_TMP, add OPF_BFD_CANONICAL. (openp_bfd, openp_file): Add prototypes. * exec.c (exec_file_attach): Replace openp by openp_bfd calls. * source.c (file_location_from_filename): Support OPF_BFD_CANONICAL. (openp, openp_bfd): New functions. (openp): Rename to ... (openp_file): ... here, return file_location, remove filename_opened parameter. --- 0 files changed diff --git a/gdb/defs.h b/gdb/defs.h index 8ee8b33..ac735c2 100644 --- a/gdb/defs.h +++ b/gdb/defs.h @@ -341,12 +341,20 @@ enum openp_flags /* Ask for bfd * to be returned in file_location. */ OPF_IS_BFD = (1 << 2), - /* Open the file in read/write mode if WRITE_FILES says so. */ - OPF_OPEN_RW_TMP = (1 << 3), + /* bfd_get_filename can be incorrect then, use only if you keep your + original filename separate from resulting bfd. + Returned file_location.filename is not canonicalized. */ + OPF_BFD_CANONICAL = (1 << 3), }; extern int openp (const char *, enum openp_flags, const char *, char **); +extern bfd *openp_bfd (const char *path, enum openp_flags opts, + const char *string); + +extern struct file_location openp_file (const char *path, enum openp_flags opts, + const char *string); + extern int source_full_path_of (const char *, char **); extern void mod_path (char *, char **); diff --git a/gdb/exec.c b/gdb/exec.c index e87d154..6dd2aa6 100644 --- a/gdb/exec.c +++ b/gdb/exec.c @@ -216,81 +216,32 @@ exec_file_attach (const char *filename, int from_tty) } else { - int load_via_target = 0; - char *scratch_pathname, *canonical_pathname; - int scratch_chan; struct target_section *sections = NULL, *sections_end = NULL; char **matching; - if (is_target_filename (filename)) - { - if (target_filesystem_is_local ()) - filename += strlen (TARGET_SYSROOT_PREFIX); - else - load_via_target = 1; - } - - if (load_via_target) + exec_bfd = openp_bfd (getenv ("PATH"), + OPF_TRY_CWD_FIRST | OPF_BFD_CANONICAL, filename); +#if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__) + if (exec_bfd == NULL) { - /* gdb_bfd_fopen does not support "target:" filenames. */ - if (write_files) - warning (_("writing into executable files is " - "not supported for %s sysroots"), - TARGET_SYSROOT_PREFIX); + char *exename = alloca (strlen (filename) + 5); - scratch_pathname = xstrdup (filename); - make_cleanup (xfree, scratch_pathname); - - scratch_chan = -1; - - canonical_pathname = scratch_pathname; + strcat (strcpy (exename, filename), ".exe"); + exec_bfd = openp_bfd (getenv ("PATH"), + OPF_TRY_CWD_FIRST | OPF_BFD_CANONICAL, exename); } - else - { - scratch_chan = openp (getenv ("PATH"), - OPF_TRY_CWD_FIRST | OPF_OPEN_RW_TMP, - filename, &scratch_pathname); -#if defined(__GO32__) || defined(_WIN32) || defined(__CYGWIN__) - if (scratch_chan < 0) - { - char *exename = alloca (strlen (filename) + 5); - - strcat (strcpy (exename, filename), ".exe"); - scratch_chan = openp (getenv ("PATH"), - OPF_TRY_CWD_FIRST | OPF_OPEN_RW_TMP, - exename, &scratch_pathname); - } #endif - if (scratch_chan < 0) - perror_with_name (filename); - - make_cleanup (xfree, scratch_pathname); - - /* gdb_bfd_open (and its variants) prefers canonicalized - pathname for better BFD caching. */ - canonical_pathname = gdb_realpath (scratch_pathname); - make_cleanup (xfree, canonical_pathname); - } - - if (write_files && !load_via_target) - exec_bfd = gdb_bfd_fopen (canonical_pathname, gnutarget, - FOPEN_RUB, scratch_chan); - else - exec_bfd = gdb_bfd_open (canonical_pathname, gnutarget, scratch_chan); - - if (!exec_bfd) - { - error (_("\"%s\": could not open as an executable file: %s."), - scratch_pathname, bfd_errmsg (bfd_get_error ())); - } + if (exec_bfd == NULL) + error (_("\"%s\": could not open as an executable file: %s."), + filename, bfd_errmsg (bfd_get_error ())); /* gdb_realpath_keepfile resolves symlinks on the local filesystem and so cannot be used for "target:" files. */ gdb_assert (exec_filename == NULL); - if (load_via_target) + if (is_target_filename (filename)) exec_filename = xstrdup (bfd_get_filename (exec_bfd)); else - exec_filename = gdb_realpath_keepfile (scratch_pathname); + exec_filename = gdb_realpath_keepfile (filename); if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching)) { @@ -298,7 +249,7 @@ exec_file_attach (const char *filename, int from_tty) it. */ exec_close (); error (_("\"%s\": not in executable format: %s"), - scratch_pathname, + filename, gdb_bfd_errmsg (bfd_get_error (), matching)); } @@ -308,7 +259,7 @@ exec_file_attach (const char *filename, int from_tty) it. */ exec_close (); error (_("\"%s\": can't find the file sections: %s"), - scratch_pathname, bfd_errmsg (bfd_get_error ())); + filename, bfd_errmsg (bfd_get_error ())); } exec_bfd_mtime = bfd_get_mtime (exec_bfd); diff --git a/gdb/source.c b/gdb/source.c index d06cc84..029c3b5 100644 --- a/gdb/source.c +++ b/gdb/source.c @@ -868,8 +868,21 @@ file_location_from_filename (const char *filename, enum openp_flags opts) { if (write_files) file.abfd = gdb_bfd_fopen (filename, gnutarget, FOPEN_RUB, file.fd); - else + else if ((opts & OPF_BFD_CANONICAL) == 0) file.abfd = gdb_bfd_open (filename, gnutarget, file.fd); + else + { + char *canonical; + + /* gdb_bfd_open (and its variants) prefers canonicalized + pathname for better BFD caching. */ + struct cleanup *canonical_cleanup; + + canonical = gdb_realpath (filename); + canonical_cleanup = make_cleanup (xfree, canonical); + file.abfd = gdb_bfd_open (canonical, gnutarget, file.fd); + do_cleanups (canonical_cleanup); + } if ((opts & OPF_IS_BFD) != 0) file.fd = -1; else @@ -944,35 +957,79 @@ filename_to_bfd (const char *filename) OPF_IS_BFD)); } -/* Open a file named STRING, searching path PATH (dir names sep by some char). - You cannot use this function to create files. - - OPTS specifies the function behaviour in specific cases. +/* Wrapper of openp_file returning filename string. - FILENAME_OPENED must be non-null. Set it to a newly allocated string naming - the actual file opened (this string will always start with a "/"). We - have to take special pains to avoid doubling the "/" between the directory - and the file, sigh! Emacs gets confuzzed by this when we print the - source file name!!! + FILENAME_OPENED must be non-null. It is set to + file_location.filename returned from openp_file. If a file is found, return the descriptor. Otherwise, return -1, with errno set for the last name we tried to open. */ -/* >>>> This should only allow files of certain types, - >>>> eg executable, non-directory. */ int openp (const char *path, enum openp_flags opts, const char *string, char **filename_opened) { + struct file_location file; + int retval; + + gdb_assert ((opts & OPF_IS_BFD) == 0); + + file = openp_file (path, opts, string); + gdb_assert (file.abfd == NULL); + if (file.fd == -1) + { + int save_errno = file.file_errno; + + gdb_assert (file.filename == NULL); + file_location_free (&file); + *filename_opened = NULL; + errno = save_errno; + return -1; + } + gdb_assert (file.filename != NULL); + *filename_opened = xstrdup (file.filename); + retval = file.fd; + file.fd = -1; + file_location_free (&file); + return retval; +} + +/* Wrapper of openp_file returning bfd *. See file_location_to_bfd how + the function behaves in the case of failure. */ + +bfd * +openp_bfd (const char *path, enum openp_flags opts, const char *string) +{ + gdb_assert ((opts & OPF_IS_BFD) == 0); + + return file_location_to_bfd (openp_file (path, opts | OPF_IS_BFD, string)); +} + +/* Open a file named STRING, searching path PATH (dir names sep by some char). + You cannot use this function to create files. + + OPTS specifies the function behaviour in specific cases. + + Call file_location_is_valid on returned file_location to check + whether this function has succeeded. */ + +/* >>>> This should only allow files of certain types, + >>>> eg executable, non-directory. */ + +struct file_location +openp_file (const char *path, enum openp_flags opts, const char *string) +{ int fd; char *filename; int alloclen; VEC (char_ptr) *dir_vec; struct cleanup *back_to; - int ix, mode; + int ix; char *dir; + struct file_location file; gdb_assert (string != NULL); + gdb_assert ((opts & (OPF_IS_BFD | OPF_BFD_CANONICAL)) != OPF_BFD_CANONICAL); /* A file with an empty name cannot possibly exist. Report a failure without further checking. @@ -983,16 +1040,13 @@ openp (const char *path, enum openp_flags opts, const char *string, when the debugger is started with an empty argument. */ if (string[0] == '\0') { - errno = ENOENT; - return -1; + file_location_enoent (&file); + return file; } if (!path) path = "."; - mode = (O_BINARY | (((opts & OPF_OPEN_RW_TMP) && write_files) - ? O_RDWR : O_RDONLY)); - if ((opts & OPF_TRY_CWD_FIRST) || IS_ABSOLUTE_PATH (string)) { int i; @@ -1001,20 +1055,19 @@ openp (const char *path, enum openp_flags opts, const char *string, { filename = alloca (strlen (string) + 1); strcpy (filename, string); - fd = gdb_open_cloexec (filename, mode, 0); - if (fd >= 0) - goto done; - } - else - { - filename = NULL; - fd = -1; + file = file_location_from_filename (filename, opts); + if (file_location_is_valid (&file)) + return file; + file_location_free (&file); } if (!(opts & OPF_SEARCH_IN_PATH)) for (i = 0; string[i]; i++) if (IS_DIR_SEPARATOR (string[i])) - goto done; + { + file_location_enoent (&file); + return file; + } } /* For dos paths, d:/foo -> /foo, and d:foo -> foo. */ @@ -1033,7 +1086,7 @@ openp (const char *path, enum openp_flags opts, const char *string, filename = alloca (alloclen); fd = -1; - dir_vec = dirnames_to_char_ptr_vec (path); + dir_vec = dirnames_to_char_ptr_vec_target_exc (path); back_to = make_cleanup_free_char_ptr_vec (dir_vec); for (ix = 0; VEC_iterate (char_ptr, dir_vec, ix, dir); ++ix) @@ -1097,23 +1150,22 @@ openp (const char *path, enum openp_flags opts, const char *string, strcat (filename + len, SLASH_STRING); strcat (filename, string); - if (is_regular_file (filename)) + if (is_target_filename (filename) || is_regular_file (filename)) { - fd = gdb_open_cloexec (filename, mode, 0); - if (fd >= 0) - break; + file = file_location_from_filename (filename, opts); + if (file_location_is_valid (&file)) + { + do_cleanups (back_to); + return file; + } + file_location_free (&file); } } do_cleanups (back_to); -done: - if (fd < 0) - *filename_opened = NULL; - else - *filename_opened = xstrdup (filename); - - return fd; + file_location_enoent (&file); + return file; }