+ *fd = found_file;
+ return temp_pathname;
+}
+
+/* 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.
+
+ PATHNAME must be malloc'ed by the caller. If successful, the new BFD's
+ name will point to it. If unsuccessful, PATHNAME will be freed and the
+ FD will be closed (unless FD was -1). */
+
+bfd *
+solib_bfd_fopen (char *pathname, int fd)
+{
+ bfd *abfd;
+
+ if (remote_filename_p (pathname))
+ {
+ gdb_assert (fd == -1);
+ abfd = remote_bfd_open (pathname, gnutarget);
+ }
+ else
+ {
+ abfd = bfd_fopen (pathname, gnutarget, FOPEN_RB, fd);
+
+ if (abfd)
+ bfd_set_cacheable (abfd, 1);
+ else if (fd != -1)
+ close (fd);
+ }
+
+ if (!abfd)
+ {
+ make_cleanup (xfree, pathname);
+ error (_("Could not open `%s' as an executable file: %s"),
+ pathname, bfd_errmsg (bfd_get_error ()));
+ }
+
+ return abfd;
+}
+
+/* Find shared library PATHNAME and open a BFD for it. */
+
+bfd *
+solib_bfd_open (char *pathname)
+{
+ char *found_pathname;
+ int found_file;
+ bfd *abfd;
+ const struct bfd_arch_info *b;
+
+ /* Search for shared library file. */
+ found_pathname = solib_find (pathname, &found_file);
+ if (found_pathname == NULL)
+ perror_with_name (pathname);
+
+ /* Open bfd for shared library. */
+ abfd = solib_bfd_fopen (found_pathname, found_file);
+
+ /* Check bfd format. */
+ if (!bfd_check_format (abfd, bfd_object))
+ {
+ bfd_close (abfd);
+ make_cleanup (xfree, found_pathname);
+ error (_("`%s': not in executable format: %s"),
+ found_pathname, bfd_errmsg (bfd_get_error ()));
+ }
+
+ /* Check bfd arch. */
+ b = gdbarch_bfd_arch_info (target_gdbarch);
+ if (!b->compatible (b, bfd_get_arch_info (abfd)))
+ warning (_("`%s': Shared library architecture %s is not compatible "
+ "with target architecture %s."), found_pathname,
+ bfd_get_arch_info (abfd)->printable_name, b->printable_name);
+
+ return abfd;