[PATCH 2/7] Introduce exec_file_find

Gary Benson
2015-04-01T11:22:37Z

This commit adds a new function, exec_file_find, which computes the
full pathname of the main executable in much the same way solib_find
does for pathnames of shared libraries. The bulk of the existing
solib_find was moved into a new static function solib_find_1, with
exec_file_find and solib_find being small wrappers for solib_find_1.

gdb/ChangeLog:

* solist.h (exec_file_find): New declaration.
* solib.c (solib_find_1): New function, factored out from...
(solib_find): ...here.
(exec_file_find): New function.
---
gdb/ChangeLog | 7 +++
gdb/solib.c | 147 ++++++++++++++++++++++++++++++++++++++------------------
gdb/solist.h | 3 +
3 files changed, 110 insertions(+), 47 deletions(-)

diff --git a/gdb/solib.c b/gdb/solib.c
index 359a208..eaeb772 100644
--- a/gdb/solib.c
+++ b/gdb/solib.c
@@ -112,13 +112,13 @@ show_solib_search_path (struct ui_file *file, int from_tty,
# define DOS_BASED_FILE_SYSTEM 0
#endif

-/* Returns the full pathname of the shared library file, or NULL if
- not found. (The pathname is malloc'ed; it needs to be freed by the
- caller.) *FD is set to either -1 or an open file handle for the
- library.
+/* Return the full pathname of a binary file (the main executable
+ or a shared library file), or NULL if not found. The returned
+ pathname is malloc'ed and must be freed by the caller. *FD is
+ set to either -1 or an open file handle for the binary file.

Global variable GDB_SYSROOT is used as a prefix directory
- to search for shared libraries if they have an absolute path.
+ to search for binary files if they have an absolute path.
If GDB_SYSROOT starts with "target:" and target filesystem
is the local filesystem then the "target:" prefix will be
stripped before the search starts. This ensures that the
@@ -128,58 +128,36 @@ show_solib_search_path (struct ui_file *file, int from_tty,
Global variable SOLIB_SEARCH_PATH is used as a prefix directory
(or set of directories, as in LD_LIBRARY_PATH) to search for all
shared libraries if not found in either the sysroot (if set) or
- the local filesystem.
+ the local filesystem. SOLIB_SEARCH_PATH is not used when searching
+ for the main executable.

Search algorithm:
* If a sysroot is set and path is absolute:
* Search for sysroot/path.
* else
* Look for it literally (unmodified).
- * Look in SOLIB_SEARCH_PATH.
- * If available, use target defined search function.
+ * If IS_SOLIB is non-zero:
+ * Look in SOLIB_SEARCH_PATH.
+ * If available, use target defined search function.
* If NO sysroot is set, perform the following two searches:
* Look in inferior's $PATH.
- * Look in inferior's $LD_LIBRARY_PATH.
+ * If IS_SOLIB is non-zero:
+ * Look in inferior's $LD_LIBRARY_PATH.
*
* The last check avoids doing this search when targetting remote
* machines since a sysroot will almost always be set.
*/

-char *
-solib_find (char *in_pathname, int *fd)
+static char *
+solib_find_1 (char *in_pathname, int *fd, int is_solib)
{
const struct target_so_ops *ops = solib_ops (target_gdbarch ());
int found_file = -1;
char *temp_pathname = NULL;
- const char *solib_symbols_extension
- = gdbarch_solib_symbols_extension (target_gdbarch ());
const char *fskind = effective_target_file_system_kind ();
struct cleanup *old_chain = make_cleanup (null_cleanup, NULL);
char *sysroot = gdb_sysroot;

- /* If solib_symbols_extension is set, replace the file's
- extension. */
- if (solib_symbols_extension)
- {
- char *p = in_pathname + strlen (in_pathname);
-
- while (p > in_pathname && *p != '.')
- p--;
-
- if (*p == '.')
- {
- char *new_pathname;
-
- new_pathname = alloca (p - in_pathname + 1
- + strlen (solib_symbols_extension) + 1);
- memcpy (new_pathname, in_pathname, p - in_pathname + 1);
- strcpy (new_pathname + (p - in_pathname) + 1,
- solib_symbols_extension);
-
- in_pathname = new_pathname;
- }
- }
-
if (sysroot != NULL)
{
/* If the absolute prefix starts with "target:" but the
@@ -351,23 +329,26 @@ solib_find (char *in_pathname, int *fd)
in_pathname++;
}

- /* If not found, search the solib_search_path (if any). */
- if (found_file < 0 && solib_search_path != NULL)
+ /* If not found, and we're looking for a solib, search the
+ solib_search_path (if any). */
+ if (is_solib && found_file < 0 && solib_search_path != NULL)
found_file = openp (solib_search_path,
OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH,
in_pathname, O_RDONLY | O_BINARY, &temp_pathname);

- /* If not found, next search the solib_search_path (if any) for the basename
- only (ignoring the path). This is to allow reading solibs from a path
- that differs from the opened path. */
- if (found_file < 0 && solib_search_path != NULL)
+ /* If not found, and we're looking for a solib, next search the
+ solib_search_path (if any) for the basename only (ignoring the
+ path). This is to allow reading solibs from a path that differs
+ from the opened path. */
+ if (is_solib && found_file < 0 && solib_search_path != NULL)
found_file = openp (solib_search_path,
OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH,
target_lbasename (fskind, in_pathname),
O_RDONLY | O_BINARY, &temp_pathname);

- /* If not found, try to use target supplied solib search method. */
- if (found_file < 0 && ops->find_and_open_solib)
+ /* If not found, and we're looking for a solib, try to use target
+ supplied solib search method. */
+ if (is_solib && found_file < 0 && ops->find_and_open_solib)
found_file = ops->find_and_open_solib (in_pathname, O_RDONLY | O_BINARY,
&temp_pathname);

@@ -378,9 +359,9 @@ solib_find (char *in_pathname, int *fd)
OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, in_pathname,
O_RDONLY | O_BINARY, &temp_pathname);

- /* If not found, next search the inferior's $LD_LIBRARY_PATH
- environment variable. */
- if (found_file < 0 && sysroot == NULL)
+ /* If not found, and we're looking for a solib, next search the
+ inferior's $LD_LIBRARY_PATH environment variable. */
+ if (is_solib && found_file < 0 && sysroot == NULL)
found_file = openp (get_in_environ (current_inferior ()->environment,
"LD_LIBRARY_PATH"),
OPF_TRY_CWD_FIRST | OPF_RETURN_REALPATH, in_pathname,
@@ -390,6 +371,78 @@ solib_find (char *in_pathname, int *fd)
return temp_pathname;
}

+/* Return the full pathname of the main executable, or NULL if not
+ found. The returned pathname is malloc'ed and must be freed by
+ the caller. *FD is set to either -1 or an open file handle for
+ the main executable.
+
+ The search algorithm used is described in solib_find_1's comment
+ above. */
+
+char *
+exec_file_find (char *in_pathname, int *fd)
+{
+ char *result = solib_find_1 (in_pathname, fd, 0);
+
+ if (result == NULL)
+ {
+ const char *fskind = effective_target_file_system_kind ();
+
+ if (fskind == file_system_kind_dos_based)
+ {
+ char *new_pathname;
+
+ new_pathname = alloca (strlen (in_pathname) + 5);
+ strcpy (new_pathname, in_pathname);
+ strcat (new_pathname, ".exe");
+
+ result = solib_find_1 (new_pathname, fd, 0);
+ }
+ }
+
+ return result;
+}
+
+/* Return the full pathname of a shared library file, or NULL if not
+ found. The returned pathname is malloc'ed and must be freed by
+ the caller. *FD is set to either -1 or an open file handle for
+ the shared library.
+
+ The search algorithm used is described in solib_find_1's comment
+ above. */
+
+char *
+solib_find (char *in_pathname, int *fd)
+{
+ const char *solib_symbols_extension
+ = gdbarch_solib_symbols_extension (target_gdbarch ());
+
+ /* If solib_symbols_extension is set, replace the file's
+ extension. */
+ if (solib_symbols_extension != NULL)
+ {
+ char *p = in_pathname + strlen (in_pathname);
+
+ while (p > in_pathname && *p != '.')
+ p--;
+
+ if (*p == '.')
+ {
+ char *new_pathname;
+
+ new_pathname = alloca (p - in_pathname + 1
+ + strlen (solib_symbols_extension) + 1);
+ memcpy (new_pathname, in_pathname, p - in_pathname + 1);
+ strcpy (new_pathname + (p - in_pathname) + 1,
+ solib_symbols_extension);
+
+ in_pathname = new_pathname;
+ }
+ }
+
+ return solib_find_1 (in_pathname, fd, 1);
+}
+
/* Open and return a BFD for the shared library PATHNAME. If FD is not -1,
it is used as file handle to open the file. Throws an error if the file
could not be opened. Handles both local and remote file access.
diff --git a/gdb/solist.h b/gdb/solist.h
index 148bec1..7021f5c 100644
--- a/gdb/solist.h
+++ b/gdb/solist.h
@@ -176,6 +176,9 @@ void free_so (struct so_list *so);
/* Return address of first so_list entry in master shared object list. */
struct so_list *master_so_list (void);

+/* Find main executable binary file. */
+extern char *exec_file_find (char *in_pathname, int *fd);
+
/* Find shared library binary file. */
extern char *solib_find (char *in_pathname, int *fd);

--
1.7.1