diff --git a/gdb/exec.c b/gdb/exec.c
index efc504eca4..3d36a0ee61 100644
--- a/gdb/exec.c
+++ b/gdb/exec.c
@@ -46,6 +46,7 @@
 #include "solist.h"
 #include <algorithm>
 #include "gdbsupport/pathstuff.h"
+#include "cli/cli-style.h"
 
 void (*deprecated_file_changed_hook) (const char *);
 
@@ -82,6 +83,50 @@ struct exec_target final : public target_ops
 
 static exec_target exec_ops;
 
+/* How to handle a mismatch between the current exec file and the exec
+   file determined from target.  */
+
+static const char *const exec_file_mismatch_names[]
+  = {"reload", "warn", "off", NULL };
+enum exec_file_mismatch_mode
+  {
+    exec_file_mismatch_reload, exec_file_mismatch_warn, exec_file_mismatch_off
+  };
+static const char *exec_file_mismatch = exec_file_mismatch_names[0];
+static enum exec_file_mismatch_mode exec_file_mismatch_mode
+  = exec_file_mismatch_reload;
+
+/* Show command.  */
+static void
+show_exec_file_mismatch_command (struct ui_file *file, int from_tty,
+				 struct cmd_list_element *c, const char *value)
+{
+  fprintf_filtered (gdb_stdout,
+		    _("exec-file-mismatch handling is currently \"%s\".\n"),
+		    exec_file_mismatch_names[exec_file_mismatch_mode]);
+}
+
+/* Set command.  Change the setting for range checking.  */
+static void
+set_exec_file_mismatch_command (const char *ignore,
+				int from_tty, struct cmd_list_element *c)
+{
+  for (enum exec_file_mismatch_mode mode = exec_file_mismatch_reload;
+       ;
+       mode = static_cast<enum exec_file_mismatch_mode>(1 + (int) mode))
+    {
+      if (strcmp (exec_file_mismatch, exec_file_mismatch_names[mode]) == 0)
+	{
+	  exec_file_mismatch_mode = mode;
+	  return;
+	}
+      if (mode == exec_file_mismatch_off)
+	internal_error (__FILE__, __LINE__,
+			_("Unrecognized exec-file-mismatch setting: \"%s\""),
+			exec_file_mismatch);
+    }
+}
+
 /* Whether to open exec and core files read-only or read-write.  */
 
 bool write_files = false;
@@ -191,6 +236,61 @@ try_open_exec_file (const char *exec_file_host, struct inferior *inf,
 
 /* See gdbcore.h.  */
 
+void
+validate_exec_file (int from_tty)
+{
+  /* If user asked to ignore the mismatch, do nothing.  */
+  if (exec_file_mismatch_mode == exec_file_mismatch_off)
+    return;
+
+  const char *current_exec_file = get_exec_file (0);
+  struct inferior *inf = current_inferior ();
+  /* Try to determine a filename from the process itself.  */
+  const char *pid_exec_file = target_pid_to_exec_file (inf->pid);
+
+  /* If wee cannot validate the exec file, return.  */
+  if (current_exec_file == NULL || pid_exec_file == NULL)
+    return;
+
+  std::string exec_file_target (pid_exec_file);
+
+  /* In case the exec file is not local, exec_file_target has to point at
+     the target file system.  */
+  if (is_target_filename (current_exec_file) && !target_filesystem_is_local ())
+    exec_file_target = TARGET_SYSROOT_PREFIX + exec_file_target;
+
+  if (exec_file_target != current_exec_file)
+    {
+      warning
+	(_("Mismatch between current exec-file %ps\n"
+	   "and automatically determined exec-file %ps\n"
+	   "exec-file-mismatch handling is currently \"%s\""),
+	 styled_string (file_name_style.style (), current_exec_file),
+	 styled_string (file_name_style.style (), exec_file_target.c_str ()),
+	 exec_file_mismatch_names[exec_file_mismatch_mode]);
+      if (exec_file_mismatch_mode == exec_file_mismatch_reload)
+	{
+	  symfile_add_flags add_flags = SYMFILE_MAINLINE;
+	  if (from_tty)
+	    add_flags |= SYMFILE_VERBOSE;
+	  try
+	    {
+	      symbol_file_add_main (exec_file_target.c_str (), add_flags);
+	      exec_file_attach (exec_file_target.c_str (), from_tty);
+	    }
+	  catch (gdb_exception_error &err)
+	    {
+	      warning (_("reloading %ps %s"),
+		       styled_string (file_name_style.style (),
+				      exec_file_target.c_str ()),
+		       err.message != NULL ? err.what () : "error");
+	    }
+	}
+    }
+}
+
+/* See gdbcore.h.  */
+
 void
 exec_file_locate_attach (int pid, int defer_bp_reset, int from_tty)
 {
@@ -331,8 +431,9 @@ exec_file_attach (const char *filename, int from_tty)
 
       if (!exec_bfd)
 	{
-	  error (_("\"%s\": could not open as an executable file: %s."),
-		 scratch_pathname, bfd_errmsg (bfd_get_error ()));
+	  error (_("\"%ps\": could not open as an executable file: %s."),
+		 styled_string (file_name_style.style (), scratch_pathname),
+		 bfd_errmsg (bfd_get_error ()));
 	}
 
       /* gdb_realpath_keepfile resolves symlinks on the local
@@ -348,8 +449,8 @@ exec_file_attach (const char *filename, int from_tty)
 	  /* 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,
+	  error (_("\"%ps\": not in executable format: %s"),
+		 styled_string (file_name_style.style (), scratch_pathname),
 		 gdb_bfd_errmsg (bfd_get_error (), matching).c_str ());
 	}
 
@@ -358,8 +459,9 @@ exec_file_attach (const char *filename, int from_tty)
 	  /* 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 ()));
+	  error (_("\"%ps\": can't find the file sections: %s"),
+		 styled_string (file_name_style.style (), scratch_pathname),
+		 bfd_errmsg (bfd_get_error ()));
 	}
 
       exec_bfd_mtime = bfd_get_mtime (exec_bfd);
@@ -879,7 +981,9 @@ print_section_info (struct target_section_table *t, bfd *abfd)
   /* FIXME: 16 is not wide enough when gdbarch_addr_bit > 64.  */
   int wid = gdbarch_addr_bit (gdbarch) <= 32 ? 8 : 16;
 
-  printf_filtered ("\t`%s', ", bfd_get_filename (abfd));
+  printf_filtered ("\t`%ps', ",
+		   styled_string (file_name_style.style (),
+				  bfd_get_filename (abfd)));
   wrap_here ("        ");
   printf_filtered (_("file type %s.\n"), bfd_get_target (abfd));
   if (abfd == exec_bfd)
@@ -906,8 +1010,9 @@ print_section_info (struct target_section_table *t, bfd *abfd)
 	    }
 	}
       if (p == t->sections_end)
-	warning (_("Cannot find section for the entry point of %s."),
-		 bfd_get_filename (abfd));
+	warning (_("Cannot find section for the entry point of %ps."),
+		 styled_string (file_name_style.style (),
+				bfd_get_filename (abfd)));
 
       entry_point = gdbarch_addr_bits_remove (gdbarch, 
 					      bfd_get_start_address (abfd) 
@@ -934,7 +1039,9 @@ print_section_info (struct target_section_table *t, bfd *abfd)
 			 hex_string_custom (psect->filepos, 8));
       printf_filtered (" is %s", bfd_section_name (psect));
       if (pbfd != abfd)
-	printf_filtered (" in %s", bfd_get_filename (pbfd));
+	printf_filtered (" in %ps",
+			 styled_string (file_name_style.style (),
+					bfd_get_filename (pbfd)));
       printf_filtered ("\n");
     }
 }
@@ -1070,5 +1177,22 @@ Show writing into executable and core files."), NULL,
 			   show_write_files,
 			   &setlist, &showlist);
 
+  add_setshow_enum_cmd ("exec-file-mismatch", class_support,
+			exec_file_mismatch_names,
+			&exec_file_mismatch,
+			_("\
+Set exec-file-mismatch handling (reload|warn|off)."),
+			_("\
+Show exec-file-mismatch handling (reload|warn|off)."),
+			_("\
+Specifies how to handle a mismatch between the current exec-file\n\
+and the exec-file automatically determined when attaching to a process:\n\n\
+ reload - warn the user, reload the automatically determined exec-file.\n\
+ warn   - warn the user, but do not change the exec-file.\n\
+ off    - do not check for mismatch."),
+			set_exec_file_mismatch_command,
+			show_exec_file_mismatch_command,
+			&setlist, &showlist);
+
   add_target (exec_target_info, exec_target_open, filename_completer);
 }
diff --git a/gdb/gdbcore.h b/gdb/gdbcore.h
index cac91c097b..5ff5e9e5ab 100644
--- a/gdb/gdbcore.h
+++ b/gdb/gdbcore.h
@@ -157,6 +157,11 @@ extern void exec_file_locate_attach (int pid, int defer_bp_reset, int from_tty);
 
 extern void validate_files (void);
 
+/* Give the user a message if the current exec file does not match the exec
+   file determined from the target.  In case of mismatch, ask the user
+   if the exec file determined from target must be loaded.  */
+extern void validate_exec_file (int from_tty);
+
 /* The current default bfd target.  */
 
 extern char *gnutarget;
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index af66eaffd8..df4478a26a 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -2782,6 +2782,9 @@ attach_command (const char *args, int from_tty)
 	target_stop (ptid_t (inferior_ptid.pid ()));
     }
 
+  /* Check for exec file mismatch, and let the user solve it.  */
+  validate_exec_file (from_tty);
+
   mode = async_exec ? ATTACH_POST_WAIT_RESUME : ATTACH_POST_WAIT_STOP;
 
   /* Some system don't generate traps when attaching to inferior.
diff --git a/gdb/remote.c b/gdb/remote.c
index 3c544502a8..6894a2b074 100644
--- a/gdb/remote.c
+++ b/gdb/remote.c
@@ -2378,6 +2378,9 @@ remote_target::remote_add_inferior (bool fake_pid_p, int pid, int attached,
   if (try_open_exec && get_exec_file (0) == NULL)
     exec_file_locate_attach (pid, 0, 1);
 
+  /* Check for exec file mismatch, and let the user solve it.  */
+  validate_exec_file (1);
+
   return inf;
 }
 
