void exec_file_attach (char *filename, int from_tty) { /* Remove any previous exec file. */ exec_close (); /* Now open and digest the file the user requested, if any. */ if (!filename) { if (from_tty) printf_unfiltered (_("No executable file now.\n")); set_gdbarch_from_file (NULL); } else { struct cleanup *cleanups; char *scratch_pathname, *canonical_pathname; int scratch_chan; struct target_section *sections = NULL, *sections_end = NULL; char **matching; scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, &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, exename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, &scratch_pathname); } #endif if (scratch_chan < 0) perror_with_name (filename); cleanups = 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) 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 ())); } gdb_assert (exec_filename == NULL); exec_filename = gdb_realpath_keepfile (scratch_pathname); if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); error (_("\"%s\": not in executable format: %s"), scratch_pathname, gdb_bfd_errmsg (bfd_get_error (), matching)); } if (build_section_table (exec_bfd, §ions, §ions_end)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); error (_("\"%s\": can't find the file sections: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } exec_bfd_mtime = bfd_get_mtime (exec_bfd); validate_files (); set_gdbarch_from_file (exec_bfd); /* Add the executable's sections to the current address spaces' list of sections. This possibly pushes the exec_ops target. */ add_target_sections (&exec_bfd, sections, sections_end); xfree (sections); /* Tell display code (if any) about the changed file name. */ if (deprecated_exec_file_display_hook) (*deprecated_exec_file_display_hook) (filename); do_cleanups (cleanups); } bfd_cache_close_all (); observer_notify_executable_changed (); }
void exec_file_attach (const char *filename, int from_tty) { struct cleanup *cleanups; /* First, acquire a reference to the current exec_bfd. We release this at the end of the function; but acquiring it now lets the BFD cache return it if this call refers to the same file. */ gdb_bfd_ref (exec_bfd); cleanups = make_cleanup_bfd_unref (exec_bfd); /* Remove any previous exec file. */ exec_close (); /* Now open and digest the file the user requested, if any. */ if (!filename) { if (from_tty) printf_unfiltered (_("No executable file now.\n")); set_gdbarch_from_file (NULL); } 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) { /* 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); scratch_pathname = xstrdup (filename); make_cleanup (xfree, scratch_pathname); scratch_chan = -1; canonical_pathname = scratch_pathname; } else { scratch_chan = openp (getenv ("PATH"), OPF_TRY_CWD_FIRST, filename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, &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, exename, write_files ? O_RDWR | O_BINARY : O_RDONLY | O_BINARY, &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 ())); } /* 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) exec_filename = xstrdup (bfd_get_filename (exec_bfd)); else exec_filename = gdb_realpath_keepfile (scratch_pathname); if (!bfd_check_format_matches (exec_bfd, bfd_object, &matching)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); error (_("\"%s\": not in executable format: %s"), scratch_pathname, gdb_bfd_errmsg (bfd_get_error (), matching)); } if (build_section_table (exec_bfd, §ions, §ions_end)) { /* Make sure to close exec_bfd, or else "run" might try to use it. */ exec_close (); error (_("\"%s\": can't find the file sections: %s"), scratch_pathname, bfd_errmsg (bfd_get_error ())); } exec_bfd_mtime = bfd_get_mtime (exec_bfd); validate_files (); set_gdbarch_from_file (exec_bfd); /* Add the executable's sections to the current address spaces' list of sections. This possibly pushes the exec_ops target. */ add_target_sections (&exec_bfd, sections, sections_end); xfree (sections); /* Tell display code (if any) about the changed file name. */ if (deprecated_exec_file_display_hook) (*deprecated_exec_file_display_hook) (filename); } do_cleanups (cleanups); bfd_cache_close_all (); observer_notify_executable_changed (); }