diff --git a/gdb/progspace.c b/gdb/progspace.c
index 2e0b6e4b825..b219acdf380 100644
--- a/gdb/progspace.c
+++ b/gdb/progspace.c
@@ -289,9 +289,12 @@ program_space::exec_entry_point_address () const
 
 /* See progspace.h.  */
 
-entry_point_info
+const entry_point_info &
 program_space::get_entry_point_info () const
 {
+  if (m_entry_point_info.has_value ())
+    return m_entry_point_info.value ();
+
   std::optional<CORE_ADDR> exec_entry_address
     = this->exec_entry_point_address_if_available ();
 
@@ -299,8 +302,9 @@ program_space::get_entry_point_info () const
   if (m_solib_ops != nullptr)
     inferior_entry_address = m_solib_ops->inferior_entry_point_address ();
 
-  return entry_point_info (std::move (inferior_entry_address),
-			   std::move (exec_entry_address));
+  m_entry_point_info.emplace (std::move (inferior_entry_address),
+			      std::move (exec_entry_address));
+  return m_entry_point_info.value ();
 }
 
 /* Implement the 'maint info entry-address' command.  */
@@ -538,11 +542,46 @@ program_space::clear_solib_cache ()
   deleted_solibs.clear ();
 }
 
+/* Clear cached entry point information in the program space of INF.  */
+
+static void
+clear_cached_entry_point_info_for_inferior (inferior *inf)
+{
+  inf->pspace->clear_cached_entry_point_info ();
+}
+
+/* Clear cached entry point information in the program space PSPACE.  */
+
+static void
+clear_cached_entry_point_info_for_pspace (program_space *pspace,
+					  bool /* reload */)
+{
+  pspace->clear_cached_entry_point_info ();
+}
+
+/* Clear cached entry point information in the program space of EXEC_INF.  */
+
+static void
+clear_cached_entry_point_info_after_exec (inferior *exec_inf,
+					  inferior */* follow_inf */)
+{
+  exec_inf->pspace->clear_cached_entry_point_info ();
+}
+
 /* See progspace.h.  */
 
 void
 initialize_progspace ()
 {
+  gdb::observers::inferior_created.attach
+    (clear_cached_entry_point_info_for_inferior, "program-space");
+  gdb::observers::inferior_exit.attach
+    (clear_cached_entry_point_info_for_inferior, "program-space");
+  gdb::observers::executable_changed.attach
+    (clear_cached_entry_point_info_for_pspace, "program-space");
+  gdb::observers::inferior_execd.attach
+    (clear_cached_entry_point_info_after_exec, "program-space");
+
   add_cmd ("program-spaces", class_maintenance,
 	   maintenance_info_program_spaces_command,
 	   _("Info about currently known program spaces."),
diff --git a/gdb/progspace.h b/gdb/progspace.h
index 69e70a1de6a..12bf116eb99 100644
--- a/gdb/progspace.h
+++ b/gdb/progspace.h
@@ -370,7 +370,13 @@ struct program_space
   /* Return information about the entry point in the main executable, and
      the entry point for the inferior, which might be different from the
      main executable.  */
-  entry_point_info get_entry_point_info () const;
+  const entry_point_info &get_entry_point_info () const;
+
+  /* Clear any cached entry point information.  */
+  void clear_cached_entry_point_info ()
+  {
+    m_entry_point_info.reset ();
+  }
 
   /* If there is a valid and known entry point in the main executable of
      this program space, return it.  Otherwise return an empty optional.  */
@@ -463,6 +469,9 @@ struct program_space
 
   /* See `exec_filename`.  */
   gdb::unique_xmalloc_ptr<char> m_exec_filename;
+
+  /* Cached entry point information.  See get_entry_point_info.  */
+  mutable std::optional<entry_point_info> m_entry_point_info;
 };
 
 /* The list of all program spaces.  There's always at least one.  */
