public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
From: Craig Blackmore <craig.blackmore@embecosm.com>
To: gdb-patches@sourceware.org
Subject: [RFC PATCH 2/3] gdb: Add new overlay manager class
Date: Mon,  9 May 2022 22:51:23 +0100	[thread overview]
Message-ID: <20220509215124.27095-3-craig.blackmore@embecosm.com> (raw)
In-Reply-To: <20220509215124.27095-1-craig.blackmore@embecosm.com>

Adds base class gdb_overlay_manager which can be implemented for
different overlay systems.

The existing overlay support has been moved within
default_overlay_manager. There should be no functional change to this
existing support.

New function overlay_manager_register is used to register an overlay
manager. There can only be one registered overlay manager at any time.

The default overlay manager is registered at GDB startup to preserve
existing behaviour so that users of the existing overlay support are not
forced to start registering the overlay manager themselves.

simple_overlay_update has been renamed to default_overlay_update which
calls the overlay_update function supplied with the current registered
overlay manager.

New function handle_overlay_bp_event defers to the overlay manager to
possibly perform some actions each time the overlay event breakpoint is
hit, such as reading the current overlay state from the target.

New function overlay_address_for_sal returns an address to use for
symbol and line lookup and can be used (for example) for overlay systems
where the mapped address is not associated with the symbol and line info
for the corresponding overlay. This patch series does not call it, but
it will be used in later commits.
---
 gdb/breakpoint.c |   3 +
 gdb/csky-tdep.c  |   5 +-
 gdb/ft32-tdep.c  |   4 +-
 gdb/m32r-tdep.c  |   5 +-
 gdb/moxie-tdep.c |   5 +-
 gdb/overlay.c    | 453 +++++++++++++++++++++++++++++++++++++----------
 gdb/overlay.h    |  92 +++++++++-
 gdb/z80-tdep.c   |   1 +
 8 files changed, 457 insertions(+), 111 deletions(-)

diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 5aba0ddd289..a84ce718650 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -5773,6 +5773,9 @@ bpstat_run_callbacks (bpstat *bs_head)
 	case bp_gnu_ifunc_resolver_return:
 	  gnu_ifunc_resolver_return_stop (b);
 	  break;
+	case bp_overlay_event:
+	  handle_overlay_bp_event ();
+	  break;
 	}
     }
 }
diff --git a/gdb/csky-tdep.c b/gdb/csky-tdep.c
index 105f5fccd12..77a8d1535b5 100644
--- a/gdb/csky-tdep.c
+++ b/gdb/csky-tdep.c
@@ -29,6 +29,7 @@
 #include "language.h"
 #include "gdbcore.h"
 #include "symfile.h"
+#include "overlay.h"
 #include "objfiles.h"
 #include "gdbtypes.h"
 #include "target.h"
@@ -2222,8 +2223,8 @@ csky_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Hook in ABI-specific overrides, if they have been registered.  */
   gdbarch_init_osabi (info, gdbarch);
 
-  /* Support simple overlay manager.  */
-  set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
+  /* Support default overlay manager.  */
+  set_gdbarch_overlay_update (gdbarch, default_overlay_update);
   set_gdbarch_char_signed (gdbarch, 0);
   return gdbarch;
 }
diff --git a/gdb/ft32-tdep.c b/gdb/ft32-tdep.c
index f77e313e0dd..624fc10cffa 100644
--- a/gdb/ft32-tdep.c
+++ b/gdb/ft32-tdep.c
@@ -607,8 +607,8 @@ ft32_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Hook in the default unwinders.  */
   frame_unwind_append_unwinder (gdbarch, &ft32_frame_unwind);
 
-  /* Support simple overlay manager.  */
-  set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
+  /* Support default overlay manager.  */
+  set_gdbarch_overlay_update (gdbarch, default_overlay_update);
 
   set_gdbarch_address_class_type_flags (gdbarch, ft32_address_class_type_flags);
   set_gdbarch_address_class_name_to_type_flags
diff --git a/gdb/m32r-tdep.c b/gdb/m32r-tdep.c
index 3ad4c8de6bf..e3214b376fd 100644
--- a/gdb/m32r-tdep.c
+++ b/gdb/m32r-tdep.c
@@ -28,6 +28,7 @@
 #include "value.h"
 #include "inferior.h"
 #include "symfile.h"
+#include "overlay.h"
 #include "objfiles.h"
 #include "osabi.h"
 #include "language.h"
@@ -906,8 +907,8 @@ m32r_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Hook in the default unwinders.  */
   frame_unwind_append_unwinder (gdbarch, &m32r_frame_unwind);
 
-  /* Support simple overlay manager.  */
-  set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
+  /* Support default overlay manager.  */
+  set_gdbarch_overlay_update (gdbarch, default_overlay_update);
 
   return gdbarch;
 }
diff --git a/gdb/moxie-tdep.c b/gdb/moxie-tdep.c
index f5cf501cea0..0d2113210b5 100644
--- a/gdb/moxie-tdep.c
+++ b/gdb/moxie-tdep.c
@@ -28,6 +28,7 @@
 #include "value.h"
 #include "inferior.h"
 #include "symfile.h"
+#include "overlay.h"
 #include "objfiles.h"
 #include "osabi.h"
 #include "language.h"
@@ -1093,8 +1094,8 @@ moxie_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
   /* Single stepping.  */
   set_gdbarch_software_single_step (gdbarch, moxie_software_single_step);
 
-  /* Support simple overlay manager.  */
-  set_gdbarch_overlay_update (gdbarch, simple_overlay_update);
+  /* Support default overlay manager.  */
+  set_gdbarch_overlay_update (gdbarch, default_overlay_update);
 
   /* Support reverse debugging.  */
   set_gdbarch_process_record (gdbarch, moxie_process_record);
diff --git a/gdb/overlay.c b/gdb/overlay.c
index 88dd1419f35..64172cfa941 100644
--- a/gdb/overlay.c
+++ b/gdb/overlay.c
@@ -22,19 +22,193 @@
 #include "objfiles.h"
 #include "overlay.h"
 
-static void overlay_invalidate_all (void);
+unsigned int debug_overlay;
 
-static void simple_free_overlay_table (void);
+/* The one registered overlay manager.  */
 
-static void read_target_long_array (CORE_ADDR, unsigned int *, int, int,
-				    enum bfd_endian);
+std::unique_ptr<gdb_overlay_manager> registered_overlay_manager = nullptr;
 
-static int simple_read_overlay_table (void);
+/* See overlay.h.  */
 
-static int simple_overlay_update_1 (struct obj_section *);
+void
+overlay_manager_register (std::unique_ptr <gdb_overlay_manager> mgr)
+{
+  registered_overlay_manager = std::move (mgr);
+}
+
+void
+handle_overlay_bp_event ()
+{
+  if (registered_overlay_manager != nullptr)
+    {
+      target_terminal::scoped_restore_terminal_state term_state;
+      target_terminal::ours_for_output ();
+
+      registered_overlay_manager->handle_overlay_bp_event ();
+    }
+}
+
+/* The following functions defer to the registered overlay manager, if there is
+   one, otherwise return a sensible default assuming no overlay debugging.  */
+
+bool
+pc_in_unmapped_range (CORE_ADDR pc, struct obj_section *section)
+{
+  if (registered_overlay_manager != nullptr)
+    return registered_overlay_manager->pc_in_unmapped_range (pc, section);
+
+  return false;
+}
+
+bool
+pc_in_mapped_range (CORE_ADDR pc, struct obj_section *section)
+{
+  if (registered_overlay_manager != nullptr)
+    return registered_overlay_manager->pc_in_mapped_range (pc, section);
+
+  return false;
+}
+
+CORE_ADDR
+overlay_unmapped_address (CORE_ADDR pc, struct obj_section *section)
+{
+  if (registered_overlay_manager != nullptr)
+    return registered_overlay_manager->overlay_unmapped_address (pc, section);
+
+  return pc;
+}
+
+CORE_ADDR
+overlay_mapped_address (CORE_ADDR pc, struct obj_section *section)
+{
+  if (registered_overlay_manager != nullptr)
+    return registered_overlay_manager->overlay_mapped_address (pc, section);
+
+  return pc;
+}
+
+CORE_ADDR
+symbol_overlayed_address (CORE_ADDR pc, struct obj_section *section)
+{
+  if (registered_overlay_manager != nullptr)
+    return registered_overlay_manager->symbol_overlayed_address (pc, section);
+
+  return pc;
+}
+
+struct obj_section *
+find_pc_mapped_section (CORE_ADDR pc)
+{
+  if (registered_overlay_manager != nullptr)
+    return registered_overlay_manager->find_pc_mapped_section (pc);
+
+  return nullptr;
+}
+
+struct obj_section *
+find_pc_overlay (CORE_ADDR pc)
+{
+  if (registered_overlay_manager != nullptr)
+    return registered_overlay_manager->find_pc_overlay (pc);
+
+  return nullptr;
+}
+
+bool
+section_is_overlay (struct obj_section *section)
+{
+  if (registered_overlay_manager != nullptr)
+    return registered_overlay_manager->section_is_overlay (section);
+
+  return false;
+}
+
+bool
+section_is_mapped (struct obj_section *section)
+{
+  if (registered_overlay_manager != nullptr)
+    return registered_overlay_manager->section_is_mapped (section);
+
+  return false;
+}
+
+static void
+list_overlays_command (const char *args, int from_tty)
+{
+  if (registered_overlay_manager != nullptr)
+    return registered_overlay_manager->list_overlays_command (args, from_tty);
+  error (_("No overlay manager registered"));
+}
+
+static void
+map_overlay_command (const char *args, int from_tty)
+{
+  if (registered_overlay_manager != nullptr)
+    return registered_overlay_manager->map_overlay_command (args, from_tty);
+  error (_("No overlay manager registered"));
+}
+
+static void
+unmap_overlay_command (const char *args, int from_tty)
+{
+  if (registered_overlay_manager != nullptr)
+    return registered_overlay_manager->unmap_overlay_command (args, from_tty);
+  error (_("No overlay manager registered"));
+}
+
+/* Function: overlay_auto_command
+   A utility command to turn on overlay debugging.
+   Possibly this should be done via a set/show command.  */
+
+static void
+overlay_auto_command (const char *args, int from_tty)
+{
+  overlay_debugging = ovly_auto;
+  enable_overlay_breakpoints ();
+  if (info_verbose)
+    gdb_printf (_("Automatic overlay debugging enabled."));
+}
 
-/* OVERLAYS:
-   The following code implements an abstraction for debugging overlay sections.
+/* Function: overlay_manual_command
+   A utility command to turn on overlay debugging.
+   Possibly this should be done via a set/show command.  */
+
+static void
+overlay_manual_command (const char *args, int from_tty)
+{
+  overlay_debugging = ovly_on;
+  disable_overlay_breakpoints ();
+  if (info_verbose)
+    gdb_printf (_("Overlay debugging enabled."));
+}
+
+/* Function: overlay_off_command
+   A utility command to turn on overlay debugging.
+   Possibly this should be done via a set/show command.  */
+
+static void
+overlay_off_command (const char *args, int from_tty)
+{
+  overlay_debugging = ovly_off;
+  disable_overlay_breakpoints ();
+  if (info_verbose)
+    gdb_printf (_("Overlay debugging disabled."));
+}
+
+static void
+overlay_load_command (const char *args, int from_tty)
+{
+  if (registered_overlay_manager != nullptr)
+    return registered_overlay_manager->overlay_load_command (args, from_tty);
+
+  error (_("No overlay manager registered"));
+}
+
+/* Command list chain containing all defined "overlay" subcommands.  */
+static struct cmd_list_element *overlaylist;
+
+/* The following code implements GDB's default abstraction for debugging overlay
+   sections.
 
    The target model is as follows:
    1) The gnu linker will permit multiple sections to be mapped into the
@@ -81,6 +255,83 @@ static int simple_overlay_update_1 (struct obj_section *);
    either in VMA or LMA depending on whether
    the symbol's section is currently mapped.  */
 
+/* Default overlay manager class.  */
+
+class default_overlay_manager : public gdb_overlay_manager
+{
+public:
+
+  /* Constructor.  */
+  default_overlay_manager ()
+    : gdb_overlay_manager ()
+  { /* Nothing.  */ }
+
+  /* Destructor.  */
+  ~default_overlay_manager ()
+  { /* Nothing.  */ }
+
+  /* Overlay handling methods which this class overrides.  */
+
+  bool pc_in_mapped_range (CORE_ADDR pc, struct obj_section *section) override;
+
+  bool pc_in_unmapped_range (CORE_ADDR pc,
+			     struct obj_section *section) override;
+
+  CORE_ADDR overlay_mapped_address (CORE_ADDR pc,
+				    struct obj_section *section) override;
+
+  CORE_ADDR overlay_unmapped_address (CORE_ADDR pc,
+				      struct obj_section *section) override;
+
+  CORE_ADDR symbol_overlayed_address (CORE_ADDR addr,
+				      struct obj_section *section) override;
+
+  struct obj_section *find_pc_mapped_section (CORE_ADDR pc) override;
+
+  struct obj_section *find_pc_overlay (CORE_ADDR pc) override;
+
+  bool section_is_overlay (struct obj_section *section) override;
+
+  bool section_is_mapped (struct obj_section *section) override;
+
+  void list_overlays_command (const char *args, int from_tty) override;
+
+  void map_overlay_command (const char *args, int from_tty) override;
+
+  void unmap_overlay_command (const char *args, int from_tty) override;
+
+  void overlay_load_command (const char *args, int from_tty) override;
+
+  void overlay_update (struct obj_section *osect) override;
+
+private:
+
+  /* Cached, dynamically allocated copies of the target data structures: */
+  unsigned (*cache_ovly_table)[4] = 0;
+  unsigned cache_novlys = 0;
+  CORE_ADDR cache_ovly_table_base = 0;
+  enum ovly_index
+    {
+      VMA, OSIZE, LMA, MAPPED
+    };
+
+  void overlay_invalidate_all ();
+
+  int sections_overlap (struct obj_section *a, struct obj_section *b);
+
+  void simple_free_overlay_table ();
+
+  void read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr,
+				      int len, int size,
+				      enum bfd_endian byte_order);
+
+  int simple_read_overlay_table ();
+
+  int simple_overlay_update_1 (struct obj_section *osect);
+
+  void simple_overlay_update (struct obj_section *osect);
+};
+
 /* Overlay debugging state: */
 
 enum overlay_debugging_state overlay_debugging = ovly_off;
@@ -90,8 +341,8 @@ int overlay_cache_invalid = 0;	/* True if need to refresh mapped state.  */
    Returns true if SECTION has VMA not equal to LMA, ie.
    SECTION is loaded at an address different from where it will "run".  */
 
-int
-section_is_overlay (struct obj_section *section)
+bool
+default_overlay_manager::section_is_overlay (struct obj_section *section)
 {
   if (overlay_debugging && section)
     {
@@ -99,17 +350,17 @@ section_is_overlay (struct obj_section *section)
 
       if (bfd_section_lma (bfd_section) != 0
 	  && bfd_section_lma (bfd_section) != bfd_section_vma (bfd_section))
-	return 1;
+	return true;
     }
 
-  return 0;
+  return false;
 }
 
 /* Function: overlay_invalidate_all (void)
    Invalidate the mapped state of all overlay sections (mark it as stale).  */
 
-static void
-overlay_invalidate_all (void)
+void
+default_overlay_manager::overlay_invalidate_all (void)
 {
   struct obj_section *sect;
 
@@ -128,19 +379,19 @@ overlay_invalidate_all (void)
    overlay_invalidate_all.  If the mapped state of the particular
    section is stale, then call TARGET_OVERLAY_UPDATE to refresh it.  */
 
-int
-section_is_mapped (struct obj_section *osect)
+bool
+default_overlay_manager::section_is_mapped (struct obj_section *osect)
 {
   struct gdbarch *gdbarch;
 
   if (osect == 0 || !section_is_overlay (osect))
-    return 0;
+    return false;
 
   switch (overlay_debugging)
     {
     default:
     case ovly_off:
-      return 0;			/* overlay debugging off */
+      return false;			/* overlay debugging off */
     case ovly_auto:		/* overlay debugging automatic */
       /* Unles there is a gdbarch_overlay_update function,
 	 there's really nothing useful to do here (can't really go auto).  */
@@ -164,8 +415,9 @@ section_is_mapped (struct obj_section *osect)
 /* Function: pc_in_unmapped_range
    If PC falls into the lma range of SECTION, return true, else false.  */
 
-CORE_ADDR
-pc_in_unmapped_range (CORE_ADDR pc, struct obj_section *section)
+bool
+default_overlay_manager::pc_in_unmapped_range (CORE_ADDR pc,
+					       struct obj_section *section)
 {
   if (section_is_overlay (section))
     {
@@ -186,8 +438,9 @@ pc_in_unmapped_range (CORE_ADDR pc, struct obj_section *section)
 /* Function: pc_in_mapped_range
    If PC falls into the vma range of SECTION, return true, else false.  */
 
-CORE_ADDR
-pc_in_mapped_range (CORE_ADDR pc, struct obj_section *section)
+bool
+default_overlay_manager::pc_in_mapped_range (CORE_ADDR pc,
+					     struct obj_section *section)
 {
   if (section_is_overlay (section))
     {
@@ -202,8 +455,9 @@ pc_in_mapped_range (CORE_ADDR pc, struct obj_section *section)
 /* Return true if the mapped ranges of sections A and B overlap, false
    otherwise.  */
 
-static int
-sections_overlap (struct obj_section *a, struct obj_section *b)
+int
+default_overlay_manager::sections_overlap (struct obj_section *a,
+					   struct obj_section *b)
 {
   CORE_ADDR a_start = a->addr ();
   CORE_ADDR a_end = a->endaddr ();
@@ -218,7 +472,8 @@ sections_overlap (struct obj_section *a, struct obj_section *b)
    May be the same as PC.  */
 
 CORE_ADDR
-overlay_unmapped_address (CORE_ADDR pc, struct obj_section *section)
+default_overlay_manager::overlay_unmapped_address (CORE_ADDR pc,
+						   struct obj_section *section)
 {
   if (section_is_overlay (section) && pc_in_mapped_range (pc, section))
     {
@@ -236,7 +491,8 @@ overlay_unmapped_address (CORE_ADDR pc, struct obj_section *section)
    May be the same as PC.  */
 
 CORE_ADDR
-overlay_mapped_address (CORE_ADDR pc, struct obj_section *section)
+default_overlay_manager::overlay_mapped_address (CORE_ADDR pc,
+						 struct obj_section *section)
 {
   if (section_is_overlay (section) && pc_in_unmapped_range (pc, section))
     {
@@ -254,7 +510,8 @@ overlay_mapped_address (CORE_ADDR pc, struct obj_section *section)
    depending on whether the section is mapped or not.  */
 
 CORE_ADDR
-symbol_overlayed_address (CORE_ADDR address, struct obj_section *section)
+default_overlay_manager::symbol_overlayed_address (CORE_ADDR address,
+						   struct obj_section *section)
 {
   if (overlay_debugging)
     {
@@ -284,7 +541,7 @@ symbol_overlayed_address (CORE_ADDR address, struct obj_section *section)
    Else if PC matches an unmapped section's LMA, return that section.  */
 
 struct obj_section *
-find_pc_overlay (CORE_ADDR pc)
+default_overlay_manager::find_pc_overlay (CORE_ADDR pc)
 {
   struct obj_section *osect, *best_match = NULL;
 
@@ -313,7 +570,7 @@ find_pc_overlay (CORE_ADDR pc)
    currently marked as MAPPED, return that section.  Else return NULL.  */
 
 struct obj_section *
-find_pc_mapped_section (CORE_ADDR pc)
+default_overlay_manager::find_pc_mapped_section (CORE_ADDR pc)
 {
   struct obj_section *osect;
 
@@ -331,8 +588,9 @@ find_pc_mapped_section (CORE_ADDR pc)
 /* Function: list_overlays_command
    Print a list of mapped sections and their PC ranges.  */
 
-static void
-list_overlays_command (const char *args, int from_tty)
+void
+default_overlay_manager::list_overlays_command (const char *args,
+						int from_tty)
 {
   int nmapped = 0;
   struct obj_section *osect;
@@ -373,8 +631,9 @@ list_overlays_command (const char *args, int from_tty)
 /* Function: map_overlay_command
    Mark the named section as mapped (ie. residing at its VMA address).  */
 
-static void
-map_overlay_command (const char *args, int from_tty)
+void
+default_overlay_manager::map_overlay_command (const char *args,
+					      int from_tty)
 {
   struct obj_section *sec, *sec2;
 
@@ -419,8 +678,9 @@ map_overlay_command (const char *args, int from_tty)
    Mark the overlay section as unmapped
    (ie. resident in its LMA address range, rather than the VMA range).  */
 
-static void
-unmap_overlay_command (const char *args, int from_tty)
+void
+default_overlay_manager::unmap_overlay_command (const char *args,
+						int from_tty)
 {
   struct obj_section *sec = NULL;
 
@@ -445,47 +705,9 @@ unmap_overlay_command (const char *args, int from_tty)
   error (_("No overlay section called %s"), args);
 }
 
-/* Function: overlay_auto_command
-   A utility command to turn on overlay debugging.
-   Possibly this should be done via a set/show command.  */
-
-static void
-overlay_auto_command (const char *args, int from_tty)
-{
-  overlay_debugging = ovly_auto;
-  enable_overlay_breakpoints ();
-  if (info_verbose)
-    gdb_printf (_("Automatic overlay debugging enabled."));
-}
-
-/* Function: overlay_manual_command
-   A utility command to turn on overlay debugging.
-   Possibly this should be done via a set/show command.  */
-
-static void
-overlay_manual_command (const char *args, int from_tty)
-{
-  overlay_debugging = ovly_on;
-  disable_overlay_breakpoints ();
-  if (info_verbose)
-    gdb_printf (_("Overlay debugging enabled."));
-}
-
-/* Function: overlay_off_command
-   A utility command to turn on overlay debugging.
-   Possibly this should be done via a set/show command.  */
-
-static void
-overlay_off_command (const char *args, int from_tty)
-{
-  overlay_debugging = ovly_off;
-  disable_overlay_breakpoints ();
-  if (info_verbose)
-    gdb_printf (_("Overlay debugging disabled."));
-}
-
-static void
-overlay_load_command (const char *args, int from_tty)
+void
+default_overlay_manager::overlay_load_command (const char *args,
+					       int from_tty)
 {
   struct gdbarch *gdbarch = get_current_arch ();
 
@@ -495,9 +717,6 @@ overlay_load_command (const char *args, int from_tty)
     error (_("This target does not know how to read its overlay state."));
 }
 
-/* Command list chain containing all defined "overlay" subcommands.  */
-static struct cmd_list_element *overlaylist;
-
 /* Target Overlays for the "Simplest" overlay manager:
 
    This is GDB's default target overlay layer.  It works with the
@@ -531,19 +750,10 @@ static struct cmd_list_element *overlaylist;
    the cached table and re-reads only the entry for that section from
    the target (whenever possible).  */
 
-/* Cached, dynamically allocated copies of the target data structures: */
-static unsigned (*cache_ovly_table)[4] = 0;
-static unsigned cache_novlys = 0;
-static CORE_ADDR cache_ovly_table_base = 0;
-enum ovly_index
-  {
-    VMA, OSIZE, LMA, MAPPED
-  };
-
 /* Throw away the cached copy of _ovly_table.  */
 
-static void
-simple_free_overlay_table (void)
+void
+default_overlay_manager::simple_free_overlay_table (void)
 {
   xfree (cache_ovly_table);
   cache_novlys = 0;
@@ -554,9 +764,11 @@ simple_free_overlay_table (void)
 /* Read an array of ints of size SIZE from the target into a local buffer.
    Convert to host order.  int LEN is number of ints.  */
 
-static void
-read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr,
-			int len, int size, enum bfd_endian byte_order)
+void
+default_overlay_manager::read_target_long_array (CORE_ADDR memaddr,
+						 unsigned int *myaddr, int len,
+						 int size,
+						 enum bfd_endian byte_order)
 {
   /* FIXME (alloca): Not safe if array is very large.  */
   gdb_byte *buf = (gdb_byte *) alloca (len * size);
@@ -570,8 +782,8 @@ read_target_long_array (CORE_ADDR memaddr, unsigned int *myaddr,
 /* Find and grab a copy of the target _ovly_table
    (and _novlys, which is needed for the table's size).  */
 
-static int
-simple_read_overlay_table (void)
+int
+default_overlay_manager::simple_read_overlay_table (void)
 {
   struct bound_minimal_symbol novlys_msym;
   struct bound_minimal_symbol ovly_table_msym;
@@ -622,8 +834,8 @@ simple_read_overlay_table (void)
    Set OSECT's mapped state to match the entry.  Return: 1 for
    success, 0 for failure.  */
 
-static int
-simple_overlay_update_1 (struct obj_section *osect)
+int
+default_overlay_manager::simple_overlay_update_1 (struct obj_section *osect)
 {
   int i;
   asection *bsect = osect->the_bfd_section;
@@ -659,7 +871,7 @@ simple_overlay_update_1 (struct obj_section *osect)
    re-read the entire cache, and go ahead and update all sections.  */
 
 void
-simple_overlay_update (struct obj_section *osect)
+default_overlay_manager::simple_overlay_update (struct obj_section *osect)
 {
   /* Were we given an osect to look up?  NULL means do all of them.  */
   if (osect)
@@ -709,6 +921,37 @@ simple_overlay_update (struct obj_section *osect)
 	}
 }
 
+void
+default_overlay_manager::overlay_update (struct obj_section *osect)
+{
+  return simple_overlay_update (osect);
+}
+
+void
+default_overlay_update (struct obj_section *osect)
+{
+  if (registered_overlay_manager != nullptr)
+    return registered_overlay_manager->overlay_update (osect);
+}
+
+CORE_ADDR
+overlay_address_for_sal (CORE_ADDR addr)
+{
+  if (registered_overlay_manager != nullptr)
+    return registered_overlay_manager->overlay_address_for_sal (addr);
+
+  return addr;
+}
+
+/* Handle 'show debug overlay'.  */
+
+static void
+show_debug_overlay (struct ui_file *file, int from_tty,
+       struct cmd_list_element *c, const char *value)
+{
+  gdb_printf (file, _("Overlay debugging is %s.\n"), value);
+}
+
 void _initialize_overlay ();
 void
 _initialize_overlay ()
@@ -738,4 +981,18 @@ _initialize_overlay ()
 	   _("Enable automatic overlay debugging."), &overlaylist);
   add_cmd ("load-target", class_support, overlay_load_command,
 	   _("Read the overlay mapping state from the target."), &overlaylist);
+
+  add_setshow_zuinteger_cmd ("overlay", class_maintenance, &debug_overlay, _("\
+Set overlay management debugging."), _("\
+Show overlay management debugging."), _("\
+When non-zero, overlay management debugging is enabled."),
+			     NULL,
+			     show_debug_overlay,
+			     &setdebuglist, &showdebuglist);
+
+  /* Instantiate the default overlay manager.  This preserves historical
+     behaviour so that users of GDB's default overlay support are not forced to
+     register the default overlay manager themselves.  */
+  std::unique_ptr <gdb_overlay_manager> mgr (new default_overlay_manager ());
+  overlay_manager_register (std::move (mgr));
 }
diff --git a/gdb/overlay.h b/gdb/overlay.h
index 8e747153fd8..a8939ce1e97 100644
--- a/gdb/overlay.h
+++ b/gdb/overlay.h
@@ -21,6 +21,71 @@
 #if !defined (OVERLAY_H)
 #define OVERLAY_H 1
 
+extern unsigned int debug_overlay;
+
+class gdb_overlay_manager
+{
+public:
+
+  /* Constructor.  */
+  gdb_overlay_manager ()
+  { /* Nothing.  */ }
+
+  /* Destructor.  */
+  virtual ~gdb_overlay_manager ()
+  { /* Nothing.  */ }
+
+  /* Overlay handling methods to be overridden by subclasses.  */
+
+  virtual void handle_overlay_bp_event ()
+  { /* Nothing.  */ };
+
+  virtual bool pc_in_mapped_range (CORE_ADDR pc,
+				   struct obj_section *section) = 0;
+
+  virtual bool pc_in_unmapped_range (CORE_ADDR pc,
+				     struct obj_section *section) = 0;
+
+  virtual CORE_ADDR overlay_mapped_address (CORE_ADDR pc,
+					    struct obj_section *section) = 0;
+
+  virtual CORE_ADDR overlay_unmapped_address (CORE_ADDR pc,
+					      struct obj_section *section) = 0;
+
+  virtual CORE_ADDR symbol_overlayed_address (CORE_ADDR addr,
+					      struct obj_section *section) = 0;
+
+  virtual struct obj_section *find_pc_mapped_section (CORE_ADDR pc) = 0;
+
+  virtual struct obj_section *find_pc_overlay (CORE_ADDR pc) = 0;
+
+  virtual bool section_is_overlay (struct obj_section *section) = 0;
+
+  virtual bool section_is_mapped (struct obj_section *section) = 0;
+
+  virtual void list_overlays_command (const char *args, int from_tty) = 0;
+
+  virtual void map_overlay_command (const char *args, int from_tty) = 0;
+
+  virtual void unmap_overlay_command (const char *args, int from_tty) = 0;
+
+  virtual void overlay_load_command (const char *args, int from_tty) = 0;
+
+  virtual void overlay_update (struct obj_section *osect)
+  { /* Nothing.  */ }
+
+  virtual CORE_ADDR overlay_address_for_sal (CORE_ADDR addr)
+  { return addr; }
+};
+
+
+/* Register an overlay manager.  There can only be one overlay manager in use
+   at a time.  Registering a new overlay manager will destroy any existing
+   overlay manager.  */
+
+extern void overlay_manager_register
+  (std::unique_ptr <gdb_overlay_manager> mgr);
+
 /* Utility functions for overlay sections: */
 extern enum overlay_debugging_state
 {
@@ -38,16 +103,16 @@ extern struct obj_section *find_pc_mapped_section (CORE_ADDR);
 extern struct obj_section *find_pc_overlay (CORE_ADDR);
 
 /* Return true if the section is an overlay.  */
-extern int section_is_overlay (struct obj_section *);
+extern bool section_is_overlay (struct obj_section *);
 
 /* Return true if the overlay section is currently "mapped".  */
-extern int section_is_mapped (struct obj_section *);
+extern bool section_is_mapped (struct obj_section *);
 
 /* Return true if pc belongs to section's VMA.  */
-extern CORE_ADDR pc_in_mapped_range (CORE_ADDR, struct obj_section *);
+extern bool pc_in_mapped_range (CORE_ADDR, struct obj_section *);
 
 /* Return true if pc belongs to section's LMA.  */
-extern CORE_ADDR pc_in_unmapped_range (CORE_ADDR, struct obj_section *);
+extern bool pc_in_unmapped_range (CORE_ADDR, struct obj_section *);
 
 /* Map an address from a section's LMA to its VMA.  */
 extern CORE_ADDR overlay_mapped_address (CORE_ADDR, struct obj_section *);
@@ -59,6 +124,23 @@ extern CORE_ADDR overlay_unmapped_address (CORE_ADDR, struct obj_section *);
 extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, struct obj_section *);
 
 /* Default overlay update function.  */
-extern void simple_overlay_update (struct obj_section *);
+extern void default_overlay_update (struct obj_section *);
+
+/* Return an address that should be used for looking up symbol and line info
+   relating to addr.
+
+   For overlay systems where mapped addresses may not be associated with the
+   corresponding overlay's symbol and line info, this function can be used to
+   return an address that GDB should use to look up this information.  */
+
+extern CORE_ADDR overlay_address_for_sal (CORE_ADDR);
+
+/* Call this when the inferior hits the overlay event breakpoint.  Ensure
+   that GDB has claimed the terminal before this is called.  At the moment
+   this assumes that the current inferior/thread is the one that hit the
+   event breakpoint, don't know if this is a good assumption, or if we
+   should pass in the thread in which the breakpoint was hit.  */
+
+extern void handle_overlay_bp_event (void);
 
 #endif /* !defined OVERLAY_H */
diff --git a/gdb/z80-tdep.c b/gdb/z80-tdep.c
index c2d906d1402..71158e46103 100644
--- a/gdb/z80-tdep.c
+++ b/gdb/z80-tdep.c
@@ -30,6 +30,7 @@
 #include "inferior.h"
 #include "objfiles.h"
 #include "symfile.h"
+#include "overlay.h"
 #include "gdbarch.h"
 
 #include "z80-tdep.h"
-- 
2.17.1


  parent reply	other threads:[~2022-05-09 21:52 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-09 21:51 [RFC PATCH 0/3] Support different overlay systems Craig Blackmore
2022-05-09 21:51 ` [RFC PATCH 1/3] gdb: Move overlay support to new file Craig Blackmore
2022-05-09 21:51 ` Craig Blackmore [this message]
2022-05-09 21:51 ` [RFC PATCH 3/3] gdb: Add support for writing overlay managers in python Craig Blackmore

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20220509215124.27095-3-craig.blackmore@embecosm.com \
    --to=craig.blackmore@embecosm.com \
    --cc=gdb-patches@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).