/* Handle shared libraries for GDB, the GNU Debugger.
- Copyright (C) 1990-2015 Free Software Foundation, Inc.
+ Copyright (C) 1990-2016 Free Software Foundation, Inc.
This file is part of GDB.
static const struct target_so_ops *
solib_ops (struct gdbarch *gdbarch)
{
- const struct target_so_ops **ops = gdbarch_data (gdbarch, solib_data);
+ const struct target_so_ops **ops
+ = (const struct target_so_ops **) gdbarch_data (gdbarch, solib_data);
return *ops;
}
void
set_solib_ops (struct gdbarch *gdbarch, const struct target_so_ops *new_ops)
{
- const struct target_so_ops **ops = gdbarch_data (gdbarch, solib_data);
+ const struct target_so_ops **ops
+ = (const struct target_so_ops **) gdbarch_data (gdbarch, solib_data);
*ops = new_ops;
}
# 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. If FD
+ is non-NULL, *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
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
- filesystem accessed by the target_fileio_* methods
- is the local filesystem then we strip the "target:"
- prefix now and work with the local filesystem. This
- ensures that the same search algorithm is used for
- all local files regardless of whether a "target:"
- prefix was used. */
- if (is_target_filename (sysroot) && target_filesystem_is_local ())
- sysroot += strlen (TARGET_SYSROOT_PREFIX);
-
- if (*sysroot == '\0')
- sysroot = NULL;
- }
-
- if (sysroot != NULL)
+ int prefix_len, orig_prefix_len;
+
+ /* If the absolute prefix starts with "target:" but the filesystem
+ accessed by the target_fileio_* methods is the local filesystem
+ then we strip the "target:" prefix now and work with the local
+ filesystem. This ensures that the same search algorithm is used
+ for all local files regardless of whether a "target:" prefix was
+ used. */
+ if (is_target_filename (sysroot) && target_filesystem_is_local ())
+ sysroot += strlen (TARGET_SYSROOT_PREFIX);
+
+ /* Strip any trailing slashes from the absolute prefix. */
+ prefix_len = orig_prefix_len = strlen (sysroot);
+
+ while (prefix_len > 0 && IS_DIR_SEPARATOR (sysroot[prefix_len - 1]))
+ prefix_len--;
+
+ if (prefix_len == 0)
+ sysroot = NULL;
+ else if (prefix_len != orig_prefix_len)
{
- int prefix_len = strlen (sysroot);
-
- /* Remove trailing slashes from absolute prefix. */
- while (prefix_len > 0
- && IS_DIR_SEPARATOR (sysroot[prefix_len - 1]))
- prefix_len--;
-
sysroot = savestring (sysroot, prefix_len);
make_cleanup (xfree, sysroot);
}
char *p;
/* Avoid clobbering our input. */
- p = alloca (strlen (in_pathname) + 1);
+ p = (char *) alloca (strlen (in_pathname) + 1);
strcpy (p, in_pathname);
in_pathname = p;
/* Handle files to be accessed via the target. */
if (is_target_filename (temp_pathname))
{
- *fd = -1;
+ if (fd != NULL)
+ *fd = -1;
do_cleanups (old_chain);
return temp_pathname;
}
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);
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,
O_RDONLY | O_BINARY, &temp_pathname);
- *fd = found_file;
+ if (fd == NULL)
+ {
+ if (found_file >= 0)
+ close (found_file);
+ }
+ else
+ *fd = found_file;
+
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. If FD is non-NULL, *FD is set to either -1 or an open
+ file handle for the main executable. */
+
+char *
+exec_file_find (char *in_pathname, int *fd)
+{
+ char *result;
+ const char *fskind = effective_target_file_system_kind ();
+
+ if (in_pathname == NULL)
+ return NULL;
+
+ if (*gdb_sysroot != '\0' && IS_TARGET_ABSOLUTE_PATH (fskind, in_pathname))
+ {
+ result = solib_find_1 (in_pathname, fd, 0);
+
+ if (result == NULL && fskind == file_system_kind_dos_based)
+ {
+ char *new_pathname;
+
+ new_pathname = (char *) alloca (strlen (in_pathname) + 5);
+ strcpy (new_pathname, in_pathname);
+ strcat (new_pathname, ".exe");
+
+ result = solib_find_1 (new_pathname, fd, 0);
+ }
+ }
+ else
+ {
+ /* It's possible we don't have a full path, but rather just a
+ filename. Some targets, such as HP-UX, don't provide the
+ full path, sigh.
+
+ Attempt to qualify the filename against the source path.
+ (If that fails, we'll just fall back on the original
+ filename. Not much more we can do...) */
+
+ if (!source_full_path_of (in_pathname, &result))
+ result = xstrdup (in_pathname);
+ if (fd != NULL)
+ *fd = -1;
+ }
+
+ 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. If FD is non-NULL, *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
+ = (char *) 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.
loaded. */
int
-solib_read_symbols (struct so_list *so, int flags)
+solib_read_symbols (struct so_list *so, symfile_add_flags flags)
{
if (so->symbols_loaded)
{
&& so->objfile->addr_low == so->addr_low)
break;
}
- if (so->objfile != NULL)
- break;
-
- sap = build_section_addr_info_from_section_table (so->sections,
- so->sections_end);
- so->objfile = symbol_file_add_from_bfd (so->abfd, so->so_name,
- flags, sap, OBJF_SHARED,
- NULL);
- so->objfile->addr_low = so->addr_low;
- free_section_addr_info (sap);
+ if (so->objfile == NULL)
+ {
+ sap = build_section_addr_info_from_section_table (so->sections,
+ so->sections_end);
+ so->objfile = symbol_file_add_from_bfd (so->abfd, so->so_name,
+ flags, sap, OBJF_SHARED,
+ NULL);
+ so->objfile->addr_low = so->addr_low;
+ free_section_addr_info (sap);
+ }
so->symbols_loaded = 1;
}
{
int any_matches = 0;
int loaded_any_symbols = 0;
- const int flags =
- SYMFILE_DEFER_BP_RESET | (from_tty ? SYMFILE_VERBOSE : 0);
+ symfile_add_flags add_flags = SYMFILE_DEFER_BP_RESET;
+
+ if (from_tty)
+ add_flags |= SYMFILE_VERBOSE;
for (gdb = so_list_head; gdb; gdb = gdb->next)
if (! pattern || re_exec (gdb->so_name))
printf_unfiltered (_("Symbols already loaded for %s\n"),
gdb->so_name);
}
- else if (solib_read_symbols (gdb, flags))
+ else if (solib_read_symbols (gdb, add_flags))
loaded_any_symbols = 1;
}
}
if (loaded_any_symbols)
{
- const struct target_so_ops *ops = solib_ops (target_gdbarch ());
-
/* Getting new symbols may change our opinion about what is
frameless. */
reinit_frame_cache ();
-
- ops->special_symbol_handling ();
}
}
}
if (nr_libs == 0)
{
if (pattern)
- ui_out_message (uiout, 0,
+ ui_out_message (uiout,
_("No shared libraries matched.\n"));
else
- ui_out_message (uiout, 0,
+ ui_out_message (uiout,
_("No shared libraries loaded at this time.\n"));
}
else
{
if (so_missing_debug_info)
- ui_out_message (uiout, 0,
+ ui_out_message (uiout,
_("(*): Shared library is missing "
"debugging information.\n"));
}
char *filename, *found_pathname = NULL;
bfd *abfd;
int was_loaded = so->symbols_loaded;
- const int flags =
- SYMFILE_DEFER_BP_RESET | (from_tty ? SYMFILE_VERBOSE : 0);
+ symfile_add_flags add_flags = SYMFILE_DEFER_BP_RESET;
+
+ if (from_tty)
+ add_flags |= SYMFILE_VERBOSE;
filename = tilde_expand (so->so_original_name);
make_cleanup (xfree, filename);
if (!got_error
&& (auto_solib_add || was_loaded || libpthread_solib_p (so)))
- solib_read_symbols (so, flags);
+ solib_read_symbols (so, add_flags);
}
}
structures that are now freed. Also, getting new symbols may
change our opinion about what is frameless. */
reinit_frame_cache ();
-
- ops->special_symbol_handling ();
}
/* Wrapper for reload_shared_libraries that replaces "remote:"
/* Handler for library-specific lookup of global symbol NAME in OBJFILE. Call
the library-specific handler if it is installed for the current target. */
-struct symbol *
+struct block_symbol
solib_global_lookup (struct objfile *objfile,
const char *name,
const domain_enum domain)
{
- const struct target_so_ops *ops = solib_ops (get_objfile_arch (objfile));
+ const struct target_so_ops *ops = solib_ops (target_gdbarch ());
if (ops->lookup_lib_global_symbol != NULL)
return ops->lookup_lib_global_symbol (objfile, name, domain);
- return NULL;
+ return (struct block_symbol) {NULL, NULL};
}
/* Lookup the value for a specific symbol from dynamic symbol table. Look
CORE_ADDR
gdb_bfd_lookup_symbol_from_symtab (bfd *abfd,
- int (*match_sym) (asymbol *, void *),
- void *data)
+ int (*match_sym) (const asymbol *,
+ const void *),
+ const void *data)
{
long storage_needed = bfd_get_symtab_upper_bound (abfd);
CORE_ADDR symaddr = 0;
static CORE_ADDR
bfd_lookup_symbol_from_dyn_symtab (bfd *abfd,
- int (*match_sym) (asymbol *, void *),
- void *data)
+ int (*match_sym) (const asymbol *,
+ const void *),
+ const void *data)
{
long storage_needed = bfd_get_dynamic_symtab_upper_bound (abfd);
CORE_ADDR symaddr = 0;
CORE_ADDR
gdb_bfd_lookup_symbol (bfd *abfd,
- int (*match_sym) (asymbol *, void *),
- void *data)
+ int (*match_sym) (const asymbol *, const void *),
+ const void *data)
{
CORE_ADDR symaddr = gdb_bfd_lookup_symbol_from_symtab (abfd, match_sym, data);
_("Load shared object library symbols for files matching REGEXP."));
add_info ("sharedlibrary", info_sharedlibrary_command,
_("Status of loaded shared object libraries."));
+ add_info_alias ("dll", "sharedlibrary", 1);
add_com ("nosharedlibrary", class_files, no_shared_libraries,
_("Unload all shared object library symbols."));