public inbox for gdb-patches@sourceware.org
 help / color / mirror / Atom feed
* [RFC PATCH 0/3] Support different overlay systems
@ 2022-05-09 21:51 Craig Blackmore
  2022-05-09 21:51 ` [RFC PATCH 1/3] gdb: Move overlay support to new file Craig Blackmore
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Craig Blackmore @ 2022-05-09 21:51 UTC (permalink / raw)
  To: gdb-patches

This patch series lays the groundwork for supporting a wider range of
overlay systems by creating a base gdb_overlay_manager class from which
new overlay managers can be implemented. This work builds on a prototype
written by Andrew Burgess.

GDB's existing overlay support works by placing overlays in sections and
using the LMA as unmapped address and VMA as mapped address. This
restricts overlays to having a one-to-one mapping between a fixed pair
of unmapped and mapped addresses. The motivation for these changes is
to support overlay systems such as the RISC-V overlay system
https://github.com/riscv-software-src/riscv-overlay/blob/master/docs/overlay-hld.adoc
that can dynamically map an overlay to any address within the overlay
area rather than being limited to a link-time defined address. In the
case of RISC-V, the same overlay could also be mapped to multiple
addresses at once.

The existing GDB overlay support has been moved to the
default_overlay_manager class, which is a sub-class of
gdb_overlay_manager. There should be no functional change to the
original overlay support.

This patch series includes a gdb_py_overlay_manager class which is
extendable via python code such that an overlay system could be shipped
with a supporting python script that contains all the internal knowledge
of the system and implements a set of hooks needed by GDB to debug such
a system.

There are a few changes that I am working on that are not yet included
in this patch series:
  
  GDB expects to be able to find symbol and line info whether it is
  using an unmapped or mapped address. However, for the kind of overlay
  system I want to support, mapped addresses are not associated with
  the symbol and line info for the overlay, so GDB must use the unmapped
  address to look up this information. The new function
  overlay_address_for_sal will be used to tell GDB which address to use
  for lookups.

  Breakpoint handling. When a breakpoint is created for an overlay, add
  a location for each address that the overlay is currently mapped to.
  When the overlay event breakpoint is hit, delete locations at which
  the overlay is no longer mapped and add newly mapped locations. 

  Now that we can support more overlay systems, this should be reflected
  in the GDB documentation. The new python interface also needs
  documenting.

I expect these changes to add to, rather than significantly modify, the
existing set of patches, so any feedback at this stage is welcome. I
will follow up and re-post with these additional changes later.

Craig Blackmore (3):
  gdb: Move overlay support to new file
  gdb: Add new overlay manager class
  gdb: Add support for writing overlay managers in python

 gdb/Makefile.in              |   3 +
 gdb/ax-gdb.c                 |   1 +
 gdb/block.c                  |   1 +
 gdb/blockframe.c             |   1 +
 gdb/breakpoint.c             |   4 +
 gdb/csky-tdep.c              |   5 +-
 gdb/elfread.c                |   1 +
 gdb/findvar.c                |   2 +-
 gdb/ft32-tdep.c              |   4 +-
 gdb/infcall.c                |   1 +
 gdb/infcmd.c                 |   1 +
 gdb/infrun.c                 |   1 +
 gdb/linespec.c               |   1 +
 gdb/m32r-tdep.c              |   5 +-
 gdb/moxie-tdep.c             |   5 +-
 gdb/objfiles.c               |   1 +
 gdb/overlay.c                | 998 +++++++++++++++++++++++++++++++++++
 gdb/overlay.h                | 146 +++++
 gdb/parse.c                  |   2 +-
 gdb/printcmd.c               |   3 +-
 gdb/probe.c                  |   1 +
 gdb/psymtab.c                |   1 +
 gdb/python/py-overlay.c      | 409 ++++++++++++++
 gdb/python/python-internal.h |   3 +
 gdb/python/python.c          |   4 +-
 gdb/symfile.c                | 714 +------------------------
 gdb/symfile.h                |  40 --
 gdb/symtab.c                 |   1 +
 gdb/target.c                 |   1 +
 gdb/z80-tdep.c               |   1 +
 30 files changed, 1595 insertions(+), 766 deletions(-)
 create mode 100644 gdb/overlay.c
 create mode 100644 gdb/overlay.h
 create mode 100644 gdb/python/py-overlay.c

-- 
2.17.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [RFC PATCH 1/3] gdb: Move overlay support to new file
  2022-05-09 21:51 [RFC PATCH 0/3] Support different overlay systems Craig Blackmore
@ 2022-05-09 21:51 ` Craig Blackmore
  2022-05-09 21:51 ` [RFC PATCH 2/3] gdb: Add new overlay manager class Craig Blackmore
  2022-05-09 21:51 ` [RFC PATCH 3/3] gdb: Add support for writing overlay managers in python Craig Blackmore
  2 siblings, 0 replies; 4+ messages in thread
From: Craig Blackmore @ 2022-05-09 21:51 UTC (permalink / raw)
  To: gdb-patches

I wanted to start extending GDB's overlay support to handle overlay
systems that do not fit within GDB's current model. In preparation for
this, it made sense to contain all the overlay related functions in
their own file rather than in the middle of symfile.c.

The overlay support originally resided in symfile.[hc] and has been
moved to overlay.[hc].

There should be no functional change after this commit.
---
 gdb/Makefile.in  |   2 +
 gdb/ax-gdb.c     |   1 +
 gdb/block.c      |   1 +
 gdb/blockframe.c |   1 +
 gdb/breakpoint.c |   1 +
 gdb/elfread.c    |   1 +
 gdb/findvar.c    |   2 +-
 gdb/infcall.c    |   1 +
 gdb/infcmd.c     |   1 +
 gdb/infrun.c     |   1 +
 gdb/linespec.c   |   1 +
 gdb/objfiles.c   |   1 +
 gdb/overlay.c    | 741 +++++++++++++++++++++++++++++++++++++++++++++++
 gdb/overlay.h    |  64 ++++
 gdb/parse.c      |   2 +-
 gdb/printcmd.c   |   3 +-
 gdb/probe.c      |   1 +
 gdb/psymtab.c    |   1 +
 gdb/symfile.c    | 714 +--------------------------------------------
 gdb/symfile.h    |  40 ---
 gdb/symtab.c     |   1 +
 gdb/target.c     |   1 +
 22 files changed, 825 insertions(+), 757 deletions(-)
 create mode 100644 gdb/overlay.c
 create mode 100644 gdb/overlay.h

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index 872fbe1f6df..d86ba85ccbc 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -1128,6 +1128,7 @@ COMMON_SFILES = \
 	opencl-lang.c \
 	osabi.c \
 	osdata.c \
+	overlay.c \
 	p-lang.c \
 	p-typeprint.c \
 	p-valprint.c \
@@ -1396,6 +1397,7 @@ HFILES_NO_SRCDIR = \
 	or1k-linux-tdep.h \
 	osabi.h \
 	osdata.h \
+	overlay.h \
 	p-lang.h \
 	parser-defs.h \
 	ppc-fbsd-tdep.h \
diff --git a/gdb/ax-gdb.c b/gdb/ax-gdb.c
index e2e311f9d74..a977a0415ad 100644
--- a/gdb/ax-gdb.c
+++ b/gdb/ax-gdb.c
@@ -20,6 +20,7 @@
 #include "defs.h"
 #include "symtab.h"
 #include "symfile.h"
+#include "overlay.h"
 #include "gdbtypes.h"
 #include "language.h"
 #include "value.h"
diff --git a/gdb/block.c b/gdb/block.c
index 3fe096db583..06cfcc4228b 100644
--- a/gdb/block.c
+++ b/gdb/block.c
@@ -21,6 +21,7 @@
 #include "block.h"
 #include "symtab.h"
 #include "symfile.h"
+#include "overlay.h"
 #include "gdbsupport/gdb_obstack.h"
 #include "cp-support.h"
 #include "addrmap.h"
diff --git a/gdb/blockframe.c b/gdb/blockframe.c
index df03901b6e7..81c22a3cab2 100644
--- a/gdb/blockframe.c
+++ b/gdb/blockframe.c
@@ -22,6 +22,7 @@
 #include "symtab.h"
 #include "bfd.h"
 #include "objfiles.h"
+#include "overlay.h"
 #include "frame.h"
 #include "gdbcore.h"
 #include "value.h"
diff --git a/gdb/breakpoint.c b/gdb/breakpoint.c
index 1a227e5d120..5aba0ddd289 100644
--- a/gdb/breakpoint.c
+++ b/gdb/breakpoint.c
@@ -40,6 +40,7 @@
 #include "filenames.h"
 #include "annotate.h"
 #include "symfile.h"
+#include "overlay.h"
 #include "objfiles.h"
 #include "source.h"
 #include "linespec.h"
diff --git a/gdb/elfread.c b/gdb/elfread.c
index b136c605b1a..10fb9a9768b 100644
--- a/gdb/elfread.c
+++ b/gdb/elfread.c
@@ -27,6 +27,7 @@
 #include "elf/mips.h"
 #include "symtab.h"
 #include "symfile.h"
+#include "overlay.h"
 #include "objfiles.h"
 #include "stabsread.h"
 #include "demangle.h"
diff --git a/gdb/findvar.c b/gdb/findvar.c
index ec21c82532b..0e95cfb5160 100644
--- a/gdb/findvar.c
+++ b/gdb/findvar.c
@@ -25,7 +25,7 @@
 #include "gdbcore.h"
 #include "inferior.h"
 #include "target.h"
-#include "symfile.h"		/* for overlay functions */
+#include "overlay.h"
 #include "regcache.h"
 #include "user-regs.h"
 #include "block.h"
diff --git a/gdb/infcall.c b/gdb/infcall.c
index 5365f97049c..b51a0526483 100644
--- a/gdb/infcall.c
+++ b/gdb/infcall.c
@@ -29,6 +29,7 @@
 #include "gdbcore.h"
 #include "language.h"
 #include "objfiles.h"
+#include "overlay.h"
 #include "gdbcmd.h"
 #include "command.h"
 #include "dummy-frame.h"
diff --git a/gdb/infcmd.c b/gdb/infcmd.c
index 84eb6e5d79b..47662ec4420 100644
--- a/gdb/infcmd.c
+++ b/gdb/infcmd.c
@@ -28,6 +28,7 @@
 #include "value.h"
 #include "gdbcmd.h"
 #include "symfile.h"
+#include "overlay.h"
 #include "gdbcore.h"
 #include "target.h"
 #include "language.h"
diff --git a/gdb/infrun.c b/gdb/infrun.c
index c311240b78c..efcfe87ab2a 100644
--- a/gdb/infrun.c
+++ b/gdb/infrun.c
@@ -33,6 +33,7 @@
 #include "gdbthread.h"
 #include "annotate.h"
 #include "symfile.h"
+#include "overlay.h"
 #include "top.h"
 #include "inf-loop.h"
 #include "regcache.h"
diff --git a/gdb/linespec.c b/gdb/linespec.c
index ba89bd09b56..b2f3a206238 100644
--- a/gdb/linespec.c
+++ b/gdb/linespec.c
@@ -22,6 +22,7 @@
 #include "frame.h"
 #include "command.h"
 #include "symfile.h"
+#include "overlay.h"
 #include "objfiles.h"
 #include "source.h"
 #include "demangle.h"
diff --git a/gdb/objfiles.c b/gdb/objfiles.c
index 0c71e0bd6a9..6e4f79eae2b 100644
--- a/gdb/objfiles.c
+++ b/gdb/objfiles.c
@@ -26,6 +26,7 @@
 #include "bfd.h"		/* Binary File Description */
 #include "symtab.h"
 #include "symfile.h"
+#include "overlay.h"
 #include "objfiles.h"
 #include "gdb-stabs.h"
 #include "target.h"
diff --git a/gdb/overlay.c b/gdb/overlay.c
new file mode 100644
index 00000000000..88dd1419f35
--- /dev/null
+++ b/gdb/overlay.c
@@ -0,0 +1,741 @@
+/* Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "arch-utils.h"
+#include "gdbcmd.h"
+#include "gdbcore.h"
+#include "objfiles.h"
+#include "overlay.h"
+
+static void overlay_invalidate_all (void);
+
+static void simple_free_overlay_table (void);
+
+static void read_target_long_array (CORE_ADDR, unsigned int *, int, int,
+				    enum bfd_endian);
+
+static int simple_read_overlay_table (void);
+
+static int simple_overlay_update_1 (struct obj_section *);
+
+/* OVERLAYS:
+   The following code implements an abstraction for debugging overlay sections.
+
+   The target model is as follows:
+   1) The gnu linker will permit multiple sections to be mapped into the
+   same VMA, each with its own unique LMA (or load address).
+   2) It is assumed that some runtime mechanism exists for mapping the
+   sections, one by one, from the load address into the VMA address.
+   3) This code provides a mechanism for gdb to keep track of which
+   sections should be considered to be mapped from the VMA to the LMA.
+   This information is used for symbol lookup, and memory read/write.
+   For instance, if a section has been mapped then its contents
+   should be read from the VMA, otherwise from the LMA.
+
+   Two levels of debugger support for overlays are available.  One is
+   "manual", in which the debugger relies on the user to tell it which
+   overlays are currently mapped.  This level of support is
+   implemented entirely in the core debugger, and the information about
+   whether a section is mapped is kept in the objfile->obj_section table.
+
+   The second level of support is "automatic", and is only available if
+   the target-specific code provides functionality to read the target's
+   overlay mapping table, and translate its contents for the debugger
+   (by updating the mapped state information in the obj_section tables).
+
+   The interface is as follows:
+   User commands:
+   overlay map <name>   -- tell gdb to consider this section mapped
+   overlay unmap <name> -- tell gdb to consider this section unmapped
+   overlay list         -- list the sections that GDB thinks are mapped
+   overlay read-target  -- get the target's state of what's mapped
+   overlay off/manual/auto -- set overlay debugging state
+   Functional interface:
+   find_pc_mapped_section(pc):    if the pc is in the range of a mapped
+   section, return that section.
+   find_pc_overlay(pc):       find any overlay section that contains
+   the pc, either in its VMA or its LMA
+   section_is_mapped(sect):       true if overlay is marked as mapped
+   section_is_overlay(sect):      true if section's VMA != LMA
+   pc_in_mapped_range(pc,sec):    true if pc belongs to section's VMA
+   pc_in_unmapped_range(...):     true if pc belongs to section's LMA
+   sections_overlap(sec1, sec2):  true if mapped sec1 and sec2 ranges overlap
+   overlay_mapped_address(...):   map an address from section's LMA to VMA
+   overlay_unmapped_address(...): map an address from section's VMA to LMA
+   symbol_overlayed_address(...): Return a "current" address for symbol:
+   either in VMA or LMA depending on whether
+   the symbol's section is currently mapped.  */
+
+/* Overlay debugging state: */
+
+enum overlay_debugging_state overlay_debugging = ovly_off;
+int overlay_cache_invalid = 0;	/* True if need to refresh mapped state.  */
+
+/* Function: section_is_overlay (SECTION)
+   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)
+{
+  if (overlay_debugging && section)
+    {
+      asection *bfd_section = section->the_bfd_section;
+
+      if (bfd_section_lma (bfd_section) != 0
+	  && bfd_section_lma (bfd_section) != bfd_section_vma (bfd_section))
+	return 1;
+    }
+
+  return 0;
+}
+
+/* Function: overlay_invalidate_all (void)
+   Invalidate the mapped state of all overlay sections (mark it as stale).  */
+
+static void
+overlay_invalidate_all (void)
+{
+  struct obj_section *sect;
+
+  for (objfile *objfile : current_program_space->objfiles ())
+    ALL_OBJFILE_OSECTIONS (objfile, sect)
+      if (section_is_overlay (sect))
+	sect->ovly_mapped = -1;
+}
+
+/* Function: section_is_mapped (SECTION)
+   Returns true if section is an overlay, and is currently mapped.
+
+   Access to the ovly_mapped flag is restricted to this function, so
+   that we can do automatic update.  If the global flag
+   OVERLAY_CACHE_INVALID is set (by wait_for_inferior), then call
+   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)
+{
+  struct gdbarch *gdbarch;
+
+  if (osect == 0 || !section_is_overlay (osect))
+    return 0;
+
+  switch (overlay_debugging)
+    {
+    default:
+    case ovly_off:
+      return 0;			/* 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).  */
+      gdbarch = osect->objfile->arch ();
+      if (gdbarch_overlay_update_p (gdbarch))
+	{
+	  if (overlay_cache_invalid)
+	    {
+	      overlay_invalidate_all ();
+	      overlay_cache_invalid = 0;
+	    }
+	  if (osect->ovly_mapped == -1)
+	    gdbarch_overlay_update (gdbarch, osect);
+	}
+      /* fall thru */
+    case ovly_on:		/* overlay debugging manual */
+      return osect->ovly_mapped == 1;
+    }
+}
+
+/* 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)
+{
+  if (section_is_overlay (section))
+    {
+      asection *bfd_section = section->the_bfd_section;
+
+      /* We assume the LMA is relocated by the same offset as the VMA.  */
+      bfd_vma size = bfd_section_size (bfd_section);
+      CORE_ADDR offset = section->offset ();
+
+      if (bfd_section_lma (bfd_section) + offset <= pc
+	  && pc < bfd_section_lma (bfd_section) + offset + size)
+	return 1;
+    }
+
+  return 0;
+}
+
+/* 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)
+{
+  if (section_is_overlay (section))
+    {
+      if (section->addr () <= pc
+	  && pc < section->endaddr ())
+	return 1;
+    }
+
+  return 0;
+}
+
+/* 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)
+{
+  CORE_ADDR a_start = a->addr ();
+  CORE_ADDR a_end = a->endaddr ();
+  CORE_ADDR b_start = b->addr ();
+  CORE_ADDR b_end = b->endaddr ();
+
+  return (a_start < b_end && b_start < a_end);
+}
+
+/* Function: overlay_unmapped_address (PC, SECTION)
+   Returns the address corresponding to PC in the unmapped (load) range.
+   May be the same as PC.  */
+
+CORE_ADDR
+overlay_unmapped_address (CORE_ADDR pc, struct obj_section *section)
+{
+  if (section_is_overlay (section) && pc_in_mapped_range (pc, section))
+    {
+      asection *bfd_section = section->the_bfd_section;
+
+      return (pc + bfd_section_lma (bfd_section)
+	      - bfd_section_vma (bfd_section));
+    }
+
+  return pc;
+}
+
+/* Function: overlay_mapped_address (PC, SECTION)
+   Returns the address corresponding to PC in the mapped (runtime) range.
+   May be the same as PC.  */
+
+CORE_ADDR
+overlay_mapped_address (CORE_ADDR pc, struct obj_section *section)
+{
+  if (section_is_overlay (section) && pc_in_unmapped_range (pc, section))
+    {
+      asection *bfd_section = section->the_bfd_section;
+
+      return (pc + bfd_section_vma (bfd_section)
+	      - bfd_section_lma (bfd_section));
+    }
+
+  return pc;
+}
+
+/* Function: symbol_overlayed_address
+   Return one of two addresses (relative to the VMA or to the LMA),
+   depending on whether the section is mapped or not.  */
+
+CORE_ADDR
+symbol_overlayed_address (CORE_ADDR address, struct obj_section *section)
+{
+  if (overlay_debugging)
+    {
+      /* If the symbol has no section, just return its regular address.  */
+      if (section == 0)
+	return address;
+      /* If the symbol's section is not an overlay, just return its
+	 address.  */
+      if (!section_is_overlay (section))
+	return address;
+      /* If the symbol's section is mapped, just return its address.  */
+      if (section_is_mapped (section))
+	return address;
+      /*
+       * HOWEVER: if the symbol is in an overlay section which is NOT mapped,
+       * then return its LOADED address rather than its vma address!!
+       */
+      return overlay_unmapped_address (address, section);
+    }
+  return address;
+}
+
+/* Function: find_pc_overlay (PC)
+   Return the best-match overlay section for PC:
+   If PC matches a mapped overlay section's VMA, return that section.
+   Else if PC matches an unmapped section's VMA, return that section.
+   Else if PC matches an unmapped section's LMA, return that section.  */
+
+struct obj_section *
+find_pc_overlay (CORE_ADDR pc)
+{
+  struct obj_section *osect, *best_match = NULL;
+
+  if (overlay_debugging)
+    {
+      for (objfile *objfile : current_program_space->objfiles ())
+	ALL_OBJFILE_OSECTIONS (objfile, osect)
+	  if (section_is_overlay (osect))
+	    {
+	      if (pc_in_mapped_range (pc, osect))
+		{
+		  if (section_is_mapped (osect))
+		    return osect;
+		  else
+		    best_match = osect;
+		}
+	      else if (pc_in_unmapped_range (pc, osect))
+		best_match = osect;
+	    }
+    }
+  return best_match;
+}
+
+/* Function: find_pc_mapped_section (PC)
+   If PC falls into the VMA address range of an overlay section that is
+   currently marked as MAPPED, return that section.  Else return NULL.  */
+
+struct obj_section *
+find_pc_mapped_section (CORE_ADDR pc)
+{
+  struct obj_section *osect;
+
+  if (overlay_debugging)
+    {
+      for (objfile *objfile : current_program_space->objfiles ())
+	ALL_OBJFILE_OSECTIONS (objfile, osect)
+	  if (pc_in_mapped_range (pc, osect) && section_is_mapped (osect))
+	    return osect;
+    }
+
+  return NULL;
+}
+
+/* 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)
+{
+  int nmapped = 0;
+  struct obj_section *osect;
+
+  if (overlay_debugging)
+    {
+      for (objfile *objfile : current_program_space->objfiles ())
+	ALL_OBJFILE_OSECTIONS (objfile, osect)
+	  if (section_is_mapped (osect))
+	    {
+	      struct gdbarch *gdbarch = objfile->arch ();
+	      const char *name;
+	      bfd_vma lma, vma;
+	      int size;
+
+	      vma = bfd_section_vma (osect->the_bfd_section);
+	      lma = bfd_section_lma (osect->the_bfd_section);
+	      size = bfd_section_size (osect->the_bfd_section);
+	      name = bfd_section_name (osect->the_bfd_section);
+
+	      gdb_printf ("Section %s, loaded at ", name);
+	      gdb_puts (paddress (gdbarch, lma));
+	      gdb_puts (" - ");
+	      gdb_puts (paddress (gdbarch, lma + size));
+	      gdb_printf (", mapped at ");
+	      gdb_puts (paddress (gdbarch, vma));
+	      gdb_puts (" - ");
+	      gdb_puts (paddress (gdbarch, vma + size));
+	      gdb_puts ("\n");
+
+	      nmapped++;
+	    }
+    }
+  if (nmapped == 0)
+    gdb_printf (_("No sections are mapped.\n"));
+}
+
+/* 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)
+{
+  struct obj_section *sec, *sec2;
+
+  if (!overlay_debugging)
+    error (_("Overlay debugging not enabled.  Use "
+	     "either the 'overlay auto' or\n"
+	     "the 'overlay manual' command."));
+
+  if (args == 0 || *args == 0)
+    error (_("Argument required: name of an overlay section"));
+
+  /* First, find a section matching the user supplied argument.  */
+  for (objfile *obj_file : current_program_space->objfiles ())
+    ALL_OBJFILE_OSECTIONS (obj_file, sec)
+      if (!strcmp (bfd_section_name (sec->the_bfd_section), args))
+	{
+	  /* Now, check to see if the section is an overlay.  */
+	  if (!section_is_overlay (sec))
+	    continue;		/* not an overlay section */
+
+	  /* Mark the overlay as "mapped".  */
+	  sec->ovly_mapped = 1;
+
+	  /* Next, make a pass and unmap any sections that are
+	     overlapped by this new section: */
+	  for (objfile *objfile2 : current_program_space->objfiles ())
+	    ALL_OBJFILE_OSECTIONS (objfile2, sec2)
+	      if (sec2->ovly_mapped && sec != sec2 && sections_overlap (sec,
+									sec2))
+		{
+		  if (info_verbose)
+		    gdb_printf (_("Note: section %s unmapped by overlap\n"),
+				bfd_section_name (sec2->the_bfd_section));
+		  sec2->ovly_mapped = 0; /* sec2 overlaps sec: unmap sec2.  */
+		}
+	  return;
+	}
+  error (_("No overlay section called %s"), args);
+}
+
+/* Function: unmap_overlay_command
+   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)
+{
+  struct obj_section *sec = NULL;
+
+  if (!overlay_debugging)
+    error (_("Overlay debugging not enabled.  "
+	     "Use either the 'overlay auto' or\n"
+	     "the 'overlay manual' command."));
+
+  if (args == 0 || *args == 0)
+    error (_("Argument required: name of an overlay section"));
+
+  /* First, find a section matching the user supplied argument.  */
+  for (objfile *objfile : current_program_space->objfiles ())
+    ALL_OBJFILE_OSECTIONS (objfile, sec)
+      if (!strcmp (bfd_section_name (sec->the_bfd_section), args))
+	{
+	  if (!sec->ovly_mapped)
+	    error (_("Section %s is not mapped"), args);
+	  sec->ovly_mapped = 0;
+	  return;
+	}
+  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)
+{
+  struct gdbarch *gdbarch = get_current_arch ();
+
+  if (gdbarch_overlay_update_p (gdbarch))
+    gdbarch_overlay_update (gdbarch, NULL);
+  else
+    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
+   minimal overlay manager supplied as an example by Cygnus.  The
+   entry point is via a function pointer "gdbarch_overlay_update",
+   so targets that use a different runtime overlay manager can
+   substitute their own overlay_update function and take over the
+   function pointer.
+
+   The overlay_update function pokes around in the target's data structures
+   to see what overlays are mapped, and updates GDB's overlay mapping with
+   this information.
+
+   In this simple implementation, the target data structures are as follows:
+   unsigned _novlys;            /# number of overlay sections #/
+   unsigned _ovly_table[_novlys][4] = {
+   {VMA, OSIZE, LMA, MAPPED},    /# one entry per overlay section #/
+   {..., ...,  ..., ...},
+   }
+   unsigned _novly_regions;     /# number of overlay regions #/
+   unsigned _ovly_region_table[_novly_regions][3] = {
+   {VMA, OSIZE, MAPPED_TO_LMA},  /# one entry per overlay region #/
+   {..., ...,  ...},
+   }
+   These functions will attempt to update GDB's mappedness state in the
+   symbol section table, based on the target's mappedness state.
+
+   To do this, we keep a cached copy of the target's _ovly_table, and
+   attempt to detect when the cached copy is invalidated.  The main
+   entry point is "simple_overlay_update(SECT), which looks up SECT in
+   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)
+{
+  xfree (cache_ovly_table);
+  cache_novlys = 0;
+  cache_ovly_table = NULL;
+  cache_ovly_table_base = 0;
+}
+
+/* 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)
+{
+  /* FIXME (alloca): Not safe if array is very large.  */
+  gdb_byte *buf = (gdb_byte *) alloca (len * size);
+  int i;
+
+  read_memory (memaddr, buf, len * size);
+  for (i = 0; i < len; i++)
+    myaddr[i] = extract_unsigned_integer (size * i + buf, size, byte_order);
+}
+
+/* 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)
+{
+  struct bound_minimal_symbol novlys_msym;
+  struct bound_minimal_symbol ovly_table_msym;
+  struct gdbarch *gdbarch;
+  int word_size;
+  enum bfd_endian byte_order;
+
+  simple_free_overlay_table ();
+  novlys_msym = lookup_minimal_symbol ("_novlys", NULL, NULL);
+  if (! novlys_msym.minsym)
+    {
+      error (_("Error reading inferior's overlay table: "
+	     "couldn't find `_novlys' variable\n"
+	     "in inferior.  Use `overlay manual' mode."));
+      return 0;
+    }
+
+  ovly_table_msym = lookup_bound_minimal_symbol ("_ovly_table");
+  if (! ovly_table_msym.minsym)
+    {
+      error (_("Error reading inferior's overlay table: couldn't find "
+	     "`_ovly_table' array\n"
+	     "in inferior.  Use `overlay manual' mode."));
+      return 0;
+    }
+
+  gdbarch = ovly_table_msym.objfile->arch ();
+  word_size = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
+  byte_order = gdbarch_byte_order (gdbarch);
+
+  cache_novlys = read_memory_integer (novlys_msym.value_address (),
+				      4, byte_order);
+  cache_ovly_table
+    = (unsigned int (*)[4]) xmalloc (cache_novlys * sizeof (*cache_ovly_table));
+  cache_ovly_table_base = ovly_table_msym.value_address ();
+  read_target_long_array (cache_ovly_table_base,
+			  (unsigned int *) cache_ovly_table,
+			  cache_novlys * 4, word_size, byte_order);
+
+  return 1;			/* SUCCESS */
+}
+
+/* Function: simple_overlay_update_1
+   A helper function for simple_overlay_update.  Assuming a cached copy
+   of _ovly_table exists, look through it to find an entry whose vma,
+   lma and size match those of OSECT.  Re-read the entry and make sure
+   it still matches OSECT (else the table may no longer be valid).
+   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 i;
+  asection *bsect = osect->the_bfd_section;
+  struct gdbarch *gdbarch = osect->objfile->arch ();
+  int word_size = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
+  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
+
+  for (i = 0; i < cache_novlys; i++)
+    if (cache_ovly_table[i][VMA] == bfd_section_vma (bsect)
+	&& cache_ovly_table[i][LMA] == bfd_section_lma (bsect))
+      {
+	read_target_long_array (cache_ovly_table_base + i * word_size,
+				(unsigned int *) cache_ovly_table[i],
+				4, word_size, byte_order);
+	if (cache_ovly_table[i][VMA] == bfd_section_vma (bsect)
+	    && cache_ovly_table[i][LMA] == bfd_section_lma (bsect))
+	  {
+	    osect->ovly_mapped = cache_ovly_table[i][MAPPED];
+	    return 1;
+	  }
+	else	/* Warning!  Warning!  Target's ovly table has changed!  */
+	  return 0;
+      }
+  return 0;
+}
+
+/* Function: simple_overlay_update
+   If OSECT is NULL, then update all sections' mapped state
+   (after re-reading the entire target _ovly_table).
+   If OSECT is non-NULL, then try to find a matching entry in the
+   cached ovly_table and update only OSECT's mapped state.
+   If a cached entry can't be found or the cache isn't valid, then
+   re-read the entire cache, and go ahead and update all sections.  */
+
+void
+simple_overlay_update (struct obj_section *osect)
+{
+  /* Were we given an osect to look up?  NULL means do all of them.  */
+  if (osect)
+    /* Have we got a cached copy of the target's overlay table?  */
+    if (cache_ovly_table != NULL)
+      {
+	/* Does its cached location match what's currently in the
+	   symtab?  */
+	struct bound_minimal_symbol minsym
+	  = lookup_minimal_symbol ("_ovly_table", NULL, NULL);
+
+	if (minsym.minsym == NULL)
+	  error (_("Error reading inferior's overlay table: couldn't "
+		   "find `_ovly_table' array\n"
+		   "in inferior.  Use `overlay manual' mode."));
+
+	if (cache_ovly_table_base == minsym.value_address ())
+	  /* Then go ahead and try to look up this single section in
+	     the cache.  */
+	  if (simple_overlay_update_1 (osect))
+	    /* Found it!  We're done.  */
+	    return;
+      }
+
+  /* Cached table no good: need to read the entire table anew.
+     Or else we want all the sections, in which case it's actually
+     more efficient to read the whole table in one block anyway.  */
+
+  if (! simple_read_overlay_table ())
+    return;
+
+  /* Now may as well update all sections, even if only one was requested.  */
+  for (objfile *objfile : current_program_space->objfiles ())
+    ALL_OBJFILE_OSECTIONS (objfile, osect)
+      if (section_is_overlay (osect))
+	{
+	  int i;
+	  asection *bsect = osect->the_bfd_section;
+
+	  for (i = 0; i < cache_novlys; i++)
+	    if (cache_ovly_table[i][VMA] == bfd_section_vma (bsect)
+		&& cache_ovly_table[i][LMA] == bfd_section_lma (bsect))
+	      { /* obj_section matches i'th entry in ovly_table.  */
+		osect->ovly_mapped = cache_ovly_table[i][MAPPED];
+		break;		/* finished with inner for loop: break out.  */
+	      }
+	}
+}
+
+void _initialize_overlay ();
+void
+_initialize_overlay ()
+{
+  cmd_list_element *overlay_cmd
+    = add_basic_prefix_cmd ("overlay", class_support,
+			    _("Commands for debugging overlays."), &overlaylist,
+			    0, &cmdlist);
+
+  add_com_alias ("ovly", overlay_cmd, class_support, 1);
+  add_com_alias ("ov", overlay_cmd, class_support, 1);
+
+  add_cmd ("map-overlay", class_support, map_overlay_command,
+	   _("Assert that an overlay section is mapped."), &overlaylist);
+
+  add_cmd ("unmap-overlay", class_support, unmap_overlay_command,
+	   _("Assert that an overlay section is unmapped."), &overlaylist);
+
+  add_cmd ("list-overlays", class_support, list_overlays_command,
+	   _("List mappings of overlay sections."), &overlaylist);
+
+  add_cmd ("manual", class_support, overlay_manual_command,
+	   _("Enable overlay debugging."), &overlaylist);
+  add_cmd ("off", class_support, overlay_off_command,
+	   _("Disable overlay debugging."), &overlaylist);
+  add_cmd ("auto", class_support, overlay_auto_command,
+	   _("Enable automatic overlay debugging."), &overlaylist);
+  add_cmd ("load-target", class_support, overlay_load_command,
+	   _("Read the overlay mapping state from the target."), &overlaylist);
+}
diff --git a/gdb/overlay.h b/gdb/overlay.h
new file mode 100644
index 00000000000..8e747153fd8
--- /dev/null
+++ b/gdb/overlay.h
@@ -0,0 +1,64 @@
+/* Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+/* Data structures and function declarations to aid GDB in managing
+   overlays.  */
+
+#if !defined (OVERLAY_H)
+#define OVERLAY_H 1
+
+/* Utility functions for overlay sections: */
+extern enum overlay_debugging_state
+{
+  ovly_off,
+  ovly_on,
+  ovly_auto
+} overlay_debugging;
+extern int overlay_cache_invalid;
+
+/* Return the "mapped" overlay section containing the PC.  */
+extern struct obj_section *find_pc_mapped_section (CORE_ADDR);
+
+/* Return any overlay section containing the PC (even in its LMA
+   region).  */
+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 *);
+
+/* Return true if the overlay section is currently "mapped".  */
+extern int 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 *);
+
+/* Return true if pc belongs to section's LMA.  */
+extern CORE_ADDR 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 *);
+
+/* Map an address from a section's VMA to its LMA.  */
+extern CORE_ADDR overlay_unmapped_address (CORE_ADDR, struct obj_section *);
+
+/* Convert an address in an overlay section (force into VMA range).  */
+extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, struct obj_section *);
+
+/* Default overlay update function.  */
+extern void simple_overlay_update (struct obj_section *);
+
+#endif /* !defined OVERLAY_H */
diff --git a/gdb/parse.c b/gdb/parse.c
index 73669923890..03da8649e0b 100644
--- a/gdb/parse.c
+++ b/gdb/parse.c
@@ -41,7 +41,7 @@
 #include "language.h"
 #include "parser-defs.h"
 #include "gdbcmd.h"
-#include "symfile.h"		/* for overlay functions */
+#include "overlay.h"
 #include "inferior.h"
 #include "target-float.h"
 #include "block.h"
diff --git a/gdb/printcmd.c b/gdb/printcmd.c
index f4f64b669bc..1bd7ac63ff2 100644
--- a/gdb/printcmd.c
+++ b/gdb/printcmd.c
@@ -33,8 +33,7 @@
 #include "gdb-demangle.h"
 #include "valprint.h"
 #include "annotate.h"
-#include "symfile.h"		/* for overlay functions */
-#include "objfiles.h"		/* ditto */
+#include "overlay.h"
 #include "completer.h"		/* for completion functions */
 #include "ui-out.h"
 #include "block.h"
diff --git a/gdb/probe.c b/gdb/probe.c
index f0a40f5face..987c7cf3b95 100644
--- a/gdb/probe.c
+++ b/gdb/probe.c
@@ -23,6 +23,7 @@
 #include "cli/cli-cmds.h"
 #include "cli/cli-utils.h"
 #include "objfiles.h"
+#include "overlay.h"
 #include "symtab.h"
 #include "progspace.h"
 #include "filenames.h"
diff --git a/gdb/psymtab.c b/gdb/psymtab.c
index 5d9949bca1d..226f9d9b445 100644
--- a/gdb/psymtab.c
+++ b/gdb/psymtab.c
@@ -20,6 +20,7 @@
 #include "defs.h"
 #include "symtab.h"
 #include "objfiles.h"
+#include "overlay.h"
 #include "psympriv.h"
 #include "block.h"
 #include "filenames.h"
diff --git a/gdb/symfile.c b/gdb/symfile.c
index 6f546f5b059..893f5a4f350 100644
--- a/gdb/symfile.c
+++ b/gdb/symfile.c
@@ -29,6 +29,7 @@
 #include "target.h"
 #include "value.h"
 #include "symfile.h"
+#include "overlay.h"
 #include "objfiles.h"
 #include "source.h"
 #include "gdbcmd.h"
@@ -100,17 +101,6 @@ static void symbol_file_add_main_1 (const char *args, symfile_add_flags add_flag
 
 static const struct sym_fns *find_sym_fns (bfd *);
 
-static void overlay_invalidate_all (void);
-
-static void simple_free_overlay_table (void);
-
-static void read_target_long_array (CORE_ADDR, unsigned int *, int, int,
-				    enum bfd_endian);
-
-static int simple_read_overlay_table (void);
-
-static int simple_overlay_update_1 (struct obj_section *);
-
 static void symfile_find_segment_sections (struct objfile *objfile);
 
 /* List of all available sym_fns.  On gdb startup, each object file reader
@@ -2880,682 +2870,6 @@ clear_symtab_users (symfile_add_flags add_flags)
   if ((add_flags & SYMFILE_DEFER_BP_RESET) == 0)
     breakpoint_re_set ();
 }
-\f
-/* OVERLAYS:
-   The following code implements an abstraction for debugging overlay sections.
-
-   The target model is as follows:
-   1) The gnu linker will permit multiple sections to be mapped into the
-   same VMA, each with its own unique LMA (or load address).
-   2) It is assumed that some runtime mechanism exists for mapping the
-   sections, one by one, from the load address into the VMA address.
-   3) This code provides a mechanism for gdb to keep track of which
-   sections should be considered to be mapped from the VMA to the LMA.
-   This information is used for symbol lookup, and memory read/write.
-   For instance, if a section has been mapped then its contents
-   should be read from the VMA, otherwise from the LMA.
-
-   Two levels of debugger support for overlays are available.  One is
-   "manual", in which the debugger relies on the user to tell it which
-   overlays are currently mapped.  This level of support is
-   implemented entirely in the core debugger, and the information about
-   whether a section is mapped is kept in the objfile->obj_section table.
-
-   The second level of support is "automatic", and is only available if
-   the target-specific code provides functionality to read the target's
-   overlay mapping table, and translate its contents for the debugger
-   (by updating the mapped state information in the obj_section tables).
-
-   The interface is as follows:
-   User commands:
-   overlay map <name>   -- tell gdb to consider this section mapped
-   overlay unmap <name> -- tell gdb to consider this section unmapped
-   overlay list         -- list the sections that GDB thinks are mapped
-   overlay read-target  -- get the target's state of what's mapped
-   overlay off/manual/auto -- set overlay debugging state
-   Functional interface:
-   find_pc_mapped_section(pc):    if the pc is in the range of a mapped
-   section, return that section.
-   find_pc_overlay(pc):       find any overlay section that contains
-   the pc, either in its VMA or its LMA
-   section_is_mapped(sect):       true if overlay is marked as mapped
-   section_is_overlay(sect):      true if section's VMA != LMA
-   pc_in_mapped_range(pc,sec):    true if pc belongs to section's VMA
-   pc_in_unmapped_range(...):     true if pc belongs to section's LMA
-   sections_overlap(sec1, sec2):  true if mapped sec1 and sec2 ranges overlap
-   overlay_mapped_address(...):   map an address from section's LMA to VMA
-   overlay_unmapped_address(...): map an address from section's VMA to LMA
-   symbol_overlayed_address(...): Return a "current" address for symbol:
-   either in VMA or LMA depending on whether
-   the symbol's section is currently mapped.  */
-
-/* Overlay debugging state: */
-
-enum overlay_debugging_state overlay_debugging = ovly_off;
-int overlay_cache_invalid = 0;	/* True if need to refresh mapped state.  */
-
-/* Function: section_is_overlay (SECTION)
-   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)
-{
-  if (overlay_debugging && section)
-    {
-      asection *bfd_section = section->the_bfd_section;
-
-      if (bfd_section_lma (bfd_section) != 0
-	  && bfd_section_lma (bfd_section) != bfd_section_vma (bfd_section))
-	return 1;
-    }
-
-  return 0;
-}
-
-/* Function: overlay_invalidate_all (void)
-   Invalidate the mapped state of all overlay sections (mark it as stale).  */
-
-static void
-overlay_invalidate_all (void)
-{
-  struct obj_section *sect;
-
-  for (objfile *objfile : current_program_space->objfiles ())
-    ALL_OBJFILE_OSECTIONS (objfile, sect)
-      if (section_is_overlay (sect))
-	sect->ovly_mapped = -1;
-}
-
-/* Function: section_is_mapped (SECTION)
-   Returns true if section is an overlay, and is currently mapped.
-
-   Access to the ovly_mapped flag is restricted to this function, so
-   that we can do automatic update.  If the global flag
-   OVERLAY_CACHE_INVALID is set (by wait_for_inferior), then call
-   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)
-{
-  struct gdbarch *gdbarch;
-
-  if (osect == 0 || !section_is_overlay (osect))
-    return 0;
-
-  switch (overlay_debugging)
-    {
-    default:
-    case ovly_off:
-      return 0;			/* 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).  */
-      gdbarch = osect->objfile->arch ();
-      if (gdbarch_overlay_update_p (gdbarch))
-	{
-	  if (overlay_cache_invalid)
-	    {
-	      overlay_invalidate_all ();
-	      overlay_cache_invalid = 0;
-	    }
-	  if (osect->ovly_mapped == -1)
-	    gdbarch_overlay_update (gdbarch, osect);
-	}
-      /* fall thru */
-    case ovly_on:		/* overlay debugging manual */
-      return osect->ovly_mapped == 1;
-    }
-}
-
-/* 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)
-{
-  if (section_is_overlay (section))
-    {
-      asection *bfd_section = section->the_bfd_section;
-
-      /* We assume the LMA is relocated by the same offset as the VMA.  */
-      bfd_vma size = bfd_section_size (bfd_section);
-      CORE_ADDR offset = section->offset ();
-
-      if (bfd_section_lma (bfd_section) + offset <= pc
-	  && pc < bfd_section_lma (bfd_section) + offset + size)
-	return 1;
-    }
-
-  return 0;
-}
-
-/* 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)
-{
-  if (section_is_overlay (section))
-    {
-      if (section->addr () <= pc
-	  && pc < section->endaddr ())
-	return 1;
-    }
-
-  return 0;
-}
-
-/* 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)
-{
-  CORE_ADDR a_start = a->addr ();
-  CORE_ADDR a_end = a->endaddr ();
-  CORE_ADDR b_start = b->addr ();
-  CORE_ADDR b_end = b->endaddr ();
-
-  return (a_start < b_end && b_start < a_end);
-}
-
-/* Function: overlay_unmapped_address (PC, SECTION)
-   Returns the address corresponding to PC in the unmapped (load) range.
-   May be the same as PC.  */
-
-CORE_ADDR
-overlay_unmapped_address (CORE_ADDR pc, struct obj_section *section)
-{
-  if (section_is_overlay (section) && pc_in_mapped_range (pc, section))
-    {
-      asection *bfd_section = section->the_bfd_section;
-
-      return (pc + bfd_section_lma (bfd_section)
-	      - bfd_section_vma (bfd_section));
-    }
-
-  return pc;
-}
-
-/* Function: overlay_mapped_address (PC, SECTION)
-   Returns the address corresponding to PC in the mapped (runtime) range.
-   May be the same as PC.  */
-
-CORE_ADDR
-overlay_mapped_address (CORE_ADDR pc, struct obj_section *section)
-{
-  if (section_is_overlay (section) && pc_in_unmapped_range (pc, section))
-    {
-      asection *bfd_section = section->the_bfd_section;
-
-      return (pc + bfd_section_vma (bfd_section)
-	      - bfd_section_lma (bfd_section));
-    }
-
-  return pc;
-}
-
-/* Function: symbol_overlayed_address
-   Return one of two addresses (relative to the VMA or to the LMA),
-   depending on whether the section is mapped or not.  */
-
-CORE_ADDR
-symbol_overlayed_address (CORE_ADDR address, struct obj_section *section)
-{
-  if (overlay_debugging)
-    {
-      /* If the symbol has no section, just return its regular address.  */
-      if (section == 0)
-	return address;
-      /* If the symbol's section is not an overlay, just return its
-	 address.  */
-      if (!section_is_overlay (section))
-	return address;
-      /* If the symbol's section is mapped, just return its address.  */
-      if (section_is_mapped (section))
-	return address;
-      /*
-       * HOWEVER: if the symbol is in an overlay section which is NOT mapped,
-       * then return its LOADED address rather than its vma address!!
-       */
-      return overlay_unmapped_address (address, section);
-    }
-  return address;
-}
-
-/* Function: find_pc_overlay (PC)
-   Return the best-match overlay section for PC:
-   If PC matches a mapped overlay section's VMA, return that section.
-   Else if PC matches an unmapped section's VMA, return that section.
-   Else if PC matches an unmapped section's LMA, return that section.  */
-
-struct obj_section *
-find_pc_overlay (CORE_ADDR pc)
-{
-  struct obj_section *osect, *best_match = NULL;
-
-  if (overlay_debugging)
-    {
-      for (objfile *objfile : current_program_space->objfiles ())
-	ALL_OBJFILE_OSECTIONS (objfile, osect)
-	  if (section_is_overlay (osect))
-	    {
-	      if (pc_in_mapped_range (pc, osect))
-		{
-		  if (section_is_mapped (osect))
-		    return osect;
-		  else
-		    best_match = osect;
-		}
-	      else if (pc_in_unmapped_range (pc, osect))
-		best_match = osect;
-	    }
-    }
-  return best_match;
-}
-
-/* Function: find_pc_mapped_section (PC)
-   If PC falls into the VMA address range of an overlay section that is
-   currently marked as MAPPED, return that section.  Else return NULL.  */
-
-struct obj_section *
-find_pc_mapped_section (CORE_ADDR pc)
-{
-  struct obj_section *osect;
-
-  if (overlay_debugging)
-    {
-      for (objfile *objfile : current_program_space->objfiles ())
-	ALL_OBJFILE_OSECTIONS (objfile, osect)
-	  if (pc_in_mapped_range (pc, osect) && section_is_mapped (osect))
-	    return osect;
-    }
-
-  return NULL;
-}
-
-/* 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)
-{
-  int nmapped = 0;
-  struct obj_section *osect;
-
-  if (overlay_debugging)
-    {
-      for (objfile *objfile : current_program_space->objfiles ())
-	ALL_OBJFILE_OSECTIONS (objfile, osect)
-	  if (section_is_mapped (osect))
-	    {
-	      struct gdbarch *gdbarch = objfile->arch ();
-	      const char *name;
-	      bfd_vma lma, vma;
-	      int size;
-
-	      vma = bfd_section_vma (osect->the_bfd_section);
-	      lma = bfd_section_lma (osect->the_bfd_section);
-	      size = bfd_section_size (osect->the_bfd_section);
-	      name = bfd_section_name (osect->the_bfd_section);
-
-	      gdb_printf ("Section %s, loaded at ", name);
-	      gdb_puts (paddress (gdbarch, lma));
-	      gdb_puts (" - ");
-	      gdb_puts (paddress (gdbarch, lma + size));
-	      gdb_printf (", mapped at ");
-	      gdb_puts (paddress (gdbarch, vma));
-	      gdb_puts (" - ");
-	      gdb_puts (paddress (gdbarch, vma + size));
-	      gdb_puts ("\n");
-
-	      nmapped++;
-	    }
-    }
-  if (nmapped == 0)
-    gdb_printf (_("No sections are mapped.\n"));
-}
-
-/* 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)
-{
-  struct obj_section *sec, *sec2;
-
-  if (!overlay_debugging)
-    error (_("Overlay debugging not enabled.  Use "
-	     "either the 'overlay auto' or\n"
-	     "the 'overlay manual' command."));
-
-  if (args == 0 || *args == 0)
-    error (_("Argument required: name of an overlay section"));
-
-  /* First, find a section matching the user supplied argument.  */
-  for (objfile *obj_file : current_program_space->objfiles ())
-    ALL_OBJFILE_OSECTIONS (obj_file, sec)
-      if (!strcmp (bfd_section_name (sec->the_bfd_section), args))
-	{
-	  /* Now, check to see if the section is an overlay.  */
-	  if (!section_is_overlay (sec))
-	    continue;		/* not an overlay section */
-
-	  /* Mark the overlay as "mapped".  */
-	  sec->ovly_mapped = 1;
-
-	  /* Next, make a pass and unmap any sections that are
-	     overlapped by this new section: */
-	  for (objfile *objfile2 : current_program_space->objfiles ())
-	    ALL_OBJFILE_OSECTIONS (objfile2, sec2)
-	      if (sec2->ovly_mapped && sec != sec2 && sections_overlap (sec,
-									sec2))
-		{
-		  if (info_verbose)
-		    gdb_printf (_("Note: section %s unmapped by overlap\n"),
-				bfd_section_name (sec2->the_bfd_section));
-		  sec2->ovly_mapped = 0; /* sec2 overlaps sec: unmap sec2.  */
-		}
-	  return;
-	}
-  error (_("No overlay section called %s"), args);
-}
-
-/* Function: unmap_overlay_command
-   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)
-{
-  struct obj_section *sec = NULL;
-
-  if (!overlay_debugging)
-    error (_("Overlay debugging not enabled.  "
-	     "Use either the 'overlay auto' or\n"
-	     "the 'overlay manual' command."));
-
-  if (args == 0 || *args == 0)
-    error (_("Argument required: name of an overlay section"));
-
-  /* First, find a section matching the user supplied argument.  */
-  for (objfile *objfile : current_program_space->objfiles ())
-    ALL_OBJFILE_OSECTIONS (objfile, sec)
-      if (!strcmp (bfd_section_name (sec->the_bfd_section), args))
-	{
-	  if (!sec->ovly_mapped)
-	    error (_("Section %s is not mapped"), args);
-	  sec->ovly_mapped = 0;
-	  return;
-	}
-  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)
-{
-  struct gdbarch *gdbarch = get_current_arch ();
-
-  if (gdbarch_overlay_update_p (gdbarch))
-    gdbarch_overlay_update (gdbarch, NULL);
-  else
-    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
-   minimal overlay manager supplied as an example by Cygnus.  The
-   entry point is via a function pointer "gdbarch_overlay_update",
-   so targets that use a different runtime overlay manager can
-   substitute their own overlay_update function and take over the
-   function pointer.
-
-   The overlay_update function pokes around in the target's data structures
-   to see what overlays are mapped, and updates GDB's overlay mapping with
-   this information.
-
-   In this simple implementation, the target data structures are as follows:
-   unsigned _novlys;            /# number of overlay sections #/
-   unsigned _ovly_table[_novlys][4] = {
-   {VMA, OSIZE, LMA, MAPPED},    /# one entry per overlay section #/
-   {..., ...,  ..., ...},
-   }
-   unsigned _novly_regions;     /# number of overlay regions #/
-   unsigned _ovly_region_table[_novly_regions][3] = {
-   {VMA, OSIZE, MAPPED_TO_LMA},  /# one entry per overlay region #/
-   {..., ...,  ...},
-   }
-   These functions will attempt to update GDB's mappedness state in the
-   symbol section table, based on the target's mappedness state.
-
-   To do this, we keep a cached copy of the target's _ovly_table, and
-   attempt to detect when the cached copy is invalidated.  The main
-   entry point is "simple_overlay_update(SECT), which looks up SECT in
-   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)
-{
-  xfree (cache_ovly_table);
-  cache_novlys = 0;
-  cache_ovly_table = NULL;
-  cache_ovly_table_base = 0;
-}
-
-/* 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)
-{
-  /* FIXME (alloca): Not safe if array is very large.  */
-  gdb_byte *buf = (gdb_byte *) alloca (len * size);
-  int i;
-
-  read_memory (memaddr, buf, len * size);
-  for (i = 0; i < len; i++)
-    myaddr[i] = extract_unsigned_integer (size * i + buf, size, byte_order);
-}
-
-/* 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)
-{
-  struct bound_minimal_symbol novlys_msym;
-  struct bound_minimal_symbol ovly_table_msym;
-  struct gdbarch *gdbarch;
-  int word_size;
-  enum bfd_endian byte_order;
-
-  simple_free_overlay_table ();
-  novlys_msym = lookup_minimal_symbol ("_novlys", NULL, NULL);
-  if (! novlys_msym.minsym)
-    {
-      error (_("Error reading inferior's overlay table: "
-	     "couldn't find `_novlys' variable\n"
-	     "in inferior.  Use `overlay manual' mode."));
-      return 0;
-    }
-
-  ovly_table_msym = lookup_bound_minimal_symbol ("_ovly_table");
-  if (! ovly_table_msym.minsym)
-    {
-      error (_("Error reading inferior's overlay table: couldn't find "
-	     "`_ovly_table' array\n"
-	     "in inferior.  Use `overlay manual' mode."));
-      return 0;
-    }
-
-  gdbarch = ovly_table_msym.objfile->arch ();
-  word_size = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
-  byte_order = gdbarch_byte_order (gdbarch);
-
-  cache_novlys = read_memory_integer (novlys_msym.value_address (),
-				      4, byte_order);
-  cache_ovly_table
-    = (unsigned int (*)[4]) xmalloc (cache_novlys * sizeof (*cache_ovly_table));
-  cache_ovly_table_base = ovly_table_msym.value_address ();
-  read_target_long_array (cache_ovly_table_base,
-			  (unsigned int *) cache_ovly_table,
-			  cache_novlys * 4, word_size, byte_order);
-
-  return 1;			/* SUCCESS */
-}
-
-/* Function: simple_overlay_update_1
-   A helper function for simple_overlay_update.  Assuming a cached copy
-   of _ovly_table exists, look through it to find an entry whose vma,
-   lma and size match those of OSECT.  Re-read the entry and make sure
-   it still matches OSECT (else the table may no longer be valid).
-   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 i;
-  asection *bsect = osect->the_bfd_section;
-  struct gdbarch *gdbarch = osect->objfile->arch ();
-  int word_size = gdbarch_long_bit (gdbarch) / TARGET_CHAR_BIT;
-  enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
-
-  for (i = 0; i < cache_novlys; i++)
-    if (cache_ovly_table[i][VMA] == bfd_section_vma (bsect)
-	&& cache_ovly_table[i][LMA] == bfd_section_lma (bsect))
-      {
-	read_target_long_array (cache_ovly_table_base + i * word_size,
-				(unsigned int *) cache_ovly_table[i],
-				4, word_size, byte_order);
-	if (cache_ovly_table[i][VMA] == bfd_section_vma (bsect)
-	    && cache_ovly_table[i][LMA] == bfd_section_lma (bsect))
-	  {
-	    osect->ovly_mapped = cache_ovly_table[i][MAPPED];
-	    return 1;
-	  }
-	else	/* Warning!  Warning!  Target's ovly table has changed!  */
-	  return 0;
-      }
-  return 0;
-}
-
-/* Function: simple_overlay_update
-   If OSECT is NULL, then update all sections' mapped state
-   (after re-reading the entire target _ovly_table).
-   If OSECT is non-NULL, then try to find a matching entry in the
-   cached ovly_table and update only OSECT's mapped state.
-   If a cached entry can't be found or the cache isn't valid, then
-   re-read the entire cache, and go ahead and update all sections.  */
-
-void
-simple_overlay_update (struct obj_section *osect)
-{
-  /* Were we given an osect to look up?  NULL means do all of them.  */
-  if (osect)
-    /* Have we got a cached copy of the target's overlay table?  */
-    if (cache_ovly_table != NULL)
-      {
-	/* Does its cached location match what's currently in the
-	   symtab?  */
-	struct bound_minimal_symbol minsym
-	  = lookup_minimal_symbol ("_ovly_table", NULL, NULL);
-
-	if (minsym.minsym == NULL)
-	  error (_("Error reading inferior's overlay table: couldn't "
-		   "find `_ovly_table' array\n"
-		   "in inferior.  Use `overlay manual' mode."));
-	
-	if (cache_ovly_table_base == minsym.value_address ())
-	  /* Then go ahead and try to look up this single section in
-	     the cache.  */
-	  if (simple_overlay_update_1 (osect))
-	    /* Found it!  We're done.  */
-	    return;
-      }
-
-  /* Cached table no good: need to read the entire table anew.
-     Or else we want all the sections, in which case it's actually
-     more efficient to read the whole table in one block anyway.  */
-
-  if (! simple_read_overlay_table ())
-    return;
-
-  /* Now may as well update all sections, even if only one was requested.  */
-  for (objfile *objfile : current_program_space->objfiles ())
-    ALL_OBJFILE_OSECTIONS (objfile, osect)
-      if (section_is_overlay (osect))
-	{
-	  int i;
-	  asection *bsect = osect->the_bfd_section;
-
-	  for (i = 0; i < cache_novlys; i++)
-	    if (cache_ovly_table[i][VMA] == bfd_section_vma (bsect)
-		&& cache_ovly_table[i][LMA] == bfd_section_lma (bsect))
-	      { /* obj_section matches i'th entry in ovly_table.  */
-		osect->ovly_mapped = cache_ovly_table[i][MAPPED];
-		break;		/* finished with inner for loop: break out.  */
-	      }
-	}
-}
 
 /* Default implementation for sym_relocate.  */
 
@@ -3870,32 +3184,6 @@ When OFFSET is provided, FILE must also be provided.  FILE can be provided\n\
 on its own."), &cmdlist);
   set_cmd_completer (c, filename_completer);
 
-  cmd_list_element *overlay_cmd
-    = add_basic_prefix_cmd ("overlay", class_support,
-			    _("Commands for debugging overlays."), &overlaylist,
-			    0, &cmdlist);
-
-  add_com_alias ("ovly", overlay_cmd, class_support, 1);
-  add_com_alias ("ov", overlay_cmd, class_support, 1);
-
-  add_cmd ("map-overlay", class_support, map_overlay_command,
-	   _("Assert that an overlay section is mapped."), &overlaylist);
-
-  add_cmd ("unmap-overlay", class_support, unmap_overlay_command,
-	   _("Assert that an overlay section is unmapped."), &overlaylist);
-
-  add_cmd ("list-overlays", class_support, list_overlays_command,
-	   _("List mappings of overlay sections."), &overlaylist);
-
-  add_cmd ("manual", class_support, overlay_manual_command,
-	   _("Enable overlay debugging."), &overlaylist);
-  add_cmd ("off", class_support, overlay_off_command,
-	   _("Disable overlay debugging."), &overlaylist);
-  add_cmd ("auto", class_support, overlay_auto_command,
-	   _("Enable automatic overlay debugging."), &overlaylist);
-  add_cmd ("load-target", class_support, overlay_load_command,
-	   _("Read the overlay mapping state from the target."), &overlaylist);
-
   /* Filename extension to source language lookup table: */
   add_setshow_string_noescape_cmd ("extension-language", class_files,
 				   &ext_args, _("\
diff --git a/gdb/symfile.h b/gdb/symfile.h
index f44dfa060a0..bf618141170 100644
--- a/gdb/symfile.h
+++ b/gdb/symfile.h
@@ -263,43 +263,6 @@ extern int get_section_index (struct objfile *, const char *);
 
 extern int print_symbol_loading_p (int from_tty, int mainline, int full);
 
-/* Utility functions for overlay sections: */
-extern enum overlay_debugging_state
-{
-  ovly_off,
-  ovly_on,
-  ovly_auto
-} overlay_debugging;
-extern int overlay_cache_invalid;
-
-/* Return the "mapped" overlay section containing the PC.  */
-extern struct obj_section *find_pc_mapped_section (CORE_ADDR);
-
-/* Return any overlay section containing the PC (even in its LMA
-   region).  */
-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 *);
-
-/* Return true if the overlay section is currently "mapped".  */
-extern int 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 *);
-
-/* Return true if pc belongs to section's LMA.  */
-extern CORE_ADDR 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 *);
-
-/* Map an address from a section's VMA to its LMA.  */
-extern CORE_ADDR overlay_unmapped_address (CORE_ADDR, struct obj_section *);
-
-/* Convert an address in an overlay section (force into VMA range).  */
-extern CORE_ADDR symbol_overlayed_address (CORE_ADDR, struct obj_section *);
-
 /* Load symbols from a file.  */
 extern void symbol_file_add_main (const char *args,
 				  symfile_add_flags add_flags);
@@ -307,9 +270,6 @@ extern void symbol_file_add_main (const char *args,
 /* Clear GDB symbol tables.  */
 extern void symbol_file_clear (int from_tty);
 
-/* Default overlay update function.  */
-extern void simple_overlay_update (struct obj_section *);
-
 extern bfd_byte *symfile_relocate_debug_section (struct objfile *, asection *,
 						 bfd_byte *);
 
diff --git a/gdb/symtab.c b/gdb/symtab.c
index a75492603b8..1df11ebd700 100644
--- a/gdb/symtab.c
+++ b/gdb/symtab.c
@@ -25,6 +25,7 @@
 #include "target.h"
 #include "value.h"
 #include "symfile.h"
+#include "overlay.h"
 #include "objfiles.h"
 #include "gdbcmd.h"
 #include "gdbsupport/gdb_regex.h"
diff --git a/gdb/target.c b/gdb/target.c
index f33bf345cfa..7e0f088f651 100644
--- a/gdb/target.c
+++ b/gdb/target.c
@@ -29,6 +29,7 @@
 #include "observable.h"
 #include "bfd.h"
 #include "symfile.h"
+#include "overlay.h"
 #include "objfiles.h"
 #include "dcache.h"
 #include <signal.h>
-- 
2.17.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [RFC PATCH 2/3] gdb: Add new overlay manager class
  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
  2022-05-09 21:51 ` [RFC PATCH 3/3] gdb: Add support for writing overlay managers in python Craig Blackmore
  2 siblings, 0 replies; 4+ messages in thread
From: Craig Blackmore @ 2022-05-09 21:51 UTC (permalink / raw)
  To: gdb-patches

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


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [RFC PATCH 3/3] gdb: Add support for writing overlay managers in python
  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 ` [RFC PATCH 2/3] gdb: Add new overlay manager class Craig Blackmore
@ 2022-05-09 21:51 ` Craig Blackmore
  2 siblings, 0 replies; 4+ messages in thread
From: Craig Blackmore @ 2022-05-09 21:51 UTC (permalink / raw)
  To: gdb-patches

Adds gdb_py_overlay_manager class which overrides most of the
public gdb_overlay_manager methods, deferring to python code to
implement them.

This allows the overlay manager support to be written in a python script
which implements the required hooks and likely contains internal details
of a specific overlay system. The script can then be shipped alongside
the overlay system.

GDB python has no concept of obj_section, therefore, it is not currently
possible to support python overlay managers that need to manipulate
sections.
---
 gdb/Makefile.in              |   1 +
 gdb/python/py-overlay.c      | 409 +++++++++++++++++++++++++++++++++++
 gdb/python/python-internal.h |   3 +
 gdb/python/python.c          |   4 +-
 4 files changed, 416 insertions(+), 1 deletion(-)
 create mode 100644 gdb/python/py-overlay.c

diff --git a/gdb/Makefile.in b/gdb/Makefile.in
index d86ba85ccbc..2662958d017 100644
--- a/gdb/Makefile.in
+++ b/gdb/Makefile.in
@@ -412,6 +412,7 @@ SUBDIR_PYTHON_SRCS = \
 	python/py-micmd.c \
 	python/py-newobjfileevent.c \
 	python/py-objfile.c \
+	python/py-overlay.c \
 	python/py-param.c \
 	python/py-prettyprint.c \
 	python/py-progspace.c \
diff --git a/gdb/python/py-overlay.c b/gdb/python/py-overlay.c
new file mode 100644
index 00000000000..5ad7dbcab63
--- /dev/null
+++ b/gdb/python/py-overlay.c
@@ -0,0 +1,409 @@
+/* Python interface to overlay manager
+
+   Copyright (C) 2022 Free Software Foundation, Inc.
+
+   This file is part of GDB.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
+
+#include "defs.h"
+#include "python-internal.h"
+#include "python.h"
+#include "overlay.h"
+
+/* Constants for method names defined on a Python class.  */
+#define PC_IN_UNMAPPED_RANGE_METHOD "pc_in_unmapped_range"
+#define PC_IN_MAPPED_RANGE_METHOD "pc_in_mapped_range"
+#define OVERLAY_UNMAPPED_ADDRESS_METHOD "overlay_unmapped_address"
+#define OVERLAY_MAPPED_ADDRESS_METHOD "overlay_mapped_address"
+#define SYMBOL_OVERLAYED_ADDRESS_METHOD "symbol_overlayed_address"
+#define HANDLE_OVERLAY_BP_EVENT_METHOD "handle_overlay_bp_event"
+#define OVERLAY_UPDATE_METHOD "overlay_update"
+#define OVERLAY_ADDRESS_FOR_SAL_METHOD "overlay_address_for_sal"
+#define LIST_OVERLAYS_COMMAND_METHOD "list_overlays_command"
+#define MAP_OVERLAY_COMMAND_METHOD "map_overlay_command"
+#define UNMAP_OVERLAY_COMMAND_METHOD "unmap_overlay_command"
+
+/* Declare.  */
+struct gdbpy_ovly_mgr_object;
+
+/* An implementation of an overlay manager that delegates out to Python
+   code that the user can easily override.  */
+
+class gdb_py_overlay_manager : public gdb_overlay_manager
+{
+public:
+  /* Constructor.  */
+  gdb_py_overlay_manager (gdbpy_ovly_mgr_object *obj)
+    : gdb_overlay_manager (),
+      m_obj (obj)
+  {
+    Py_INCREF (m_obj);
+  }
+
+  /* Destructor.  */
+  ~gdb_py_overlay_manager ()
+  {
+    gdb_assert (gdb_python_initialized);
+    gdbpy_enter enter_py;
+
+    Py_DECREF (m_obj);
+  }
+
+private:
+
+  /* Generic method for calling a python method which is expected to take a
+     CORE_ADDR.  If the method is implemented return its result, else raise an
+     error.
+  */
+
+  PyObject *
+  call_python (CORE_ADDR addr, const char *method_name)
+  {
+    gdb_assert (gdb_python_initialized);
+    gdbpy_enter enter_py;
+
+    PyObject *obj = (PyObject *) m_obj;
+
+    /* If this method is not implemented, return addr.  */
+    PyObject *match_method_name
+      = PyUnicode_FromString (method_name);
+    if (!PyObject_HasAttr ((PyObject *) obj, match_method_name))
+      error (_("could not find method %s"), method_name);
+
+    gdbpy_ref<> addr_arg (gdb_py_object_from_ulongest (addr));
+    if (addr_arg == nullptr)
+      {
+	gdbpy_print_stack ();
+	error (_("failed to convert addr to pass to %s"), method_name);
+      }
+
+    gdbpy_ref<> result (PyObject_CallMethodObjArgs (obj, match_method_name,
+						    addr_arg.get (), NULL));
+    if (result == NULL)
+      {
+	gdbpy_print_stack ();
+	error (_("missing result object from %s"), method_name);
+      }
+
+    if (result == Py_None)
+      {
+	gdbpy_print_stack ();
+	error (_("%s returned None"), method_name);
+      }
+
+    return result.get ();
+  }
+
+  /* Generic method for calling a python method which is expected to take a
+     CORE_ADDR and return a bool.
+  */
+
+  bool
+  call_python_bool (CORE_ADDR addr, const char *method_name)
+  {
+    PyObject *result = call_python (addr, method_name);
+
+    return PyObject_IsTrue (result);
+  }
+
+  /* Generic method for calling a python method which is expected to take a
+     CORE_ADDR and return a CORE_ADDR.
+  */
+
+  CORE_ADDR
+  call_python_addr (CORE_ADDR addr, const char *method_name)
+  {
+    PyObject *result = call_python (addr, method_name);
+
+    if (get_addr_from_python (result, &addr) != 0)
+      {
+	gdbpy_print_stack ();
+	error (_("failed to convert address returned by %s"), method_name);
+      }
+
+    return addr;
+  }
+
+  /* Generic method for calling a python method, if implemented, which is
+     expected to take no arguments and return void.  Raise an error if the
+     method is not implemented.  */
+
+  void
+  call_python_void (const char *method_name)
+  {
+    gdb_assert (gdb_python_initialized);
+    gdbpy_enter enter_py;
+
+    PyObject *obj = (PyObject *) m_obj;
+
+    /* If this method is not implemented, return.  */
+    if (!PyObject_HasAttrString (obj, method_name))
+      error (_("could not find method %s"), method_name);
+
+    gdbpy_ref<> result (PyObject_CallMethod (obj, method_name, NULL));
+
+    if (result == NULL)
+      {
+	gdbpy_print_stack ();
+	error (_("missing result object from %s"), method_name);
+      }
+  }
+
+  /* Return the result of calling HANDLE_OVERLAY_BP_EVENT_METHOD.  */
+
+  void
+  handle_overlay_bp_event () override
+  {
+    call_python_void (HANDLE_OVERLAY_BP_EVENT_METHOD);
+  }
+
+  /* Return result of calling PC_IN_UNMAPPED_RANGE_METHOD.
+
+     We cannot pass section to PC_IN_UNMAPPED_RANGE_METHOD because GDB's python
+     support currently has no concept of obj_section.  If an overlay manager
+     needed to access sections then obj_section would first need to be
+     supported.  */
+
+  bool
+  pc_in_unmapped_range (CORE_ADDR addr,
+			ATTRIBUTE_UNUSED struct obj_section *section) override
+  {
+    return call_python_bool (addr, PC_IN_UNMAPPED_RANGE_METHOD);
+  }
+
+  /* Return result of calling PC_IN_MAPPED_RANGE_METHOD.
+
+     See pc_in_unmapped_range above regarding unused section parameter.  */
+
+  bool
+  pc_in_mapped_range (CORE_ADDR addr,
+		      ATTRIBUTE_UNUSED struct obj_section *section) override
+  {
+    return call_python_bool (addr, PC_IN_MAPPED_RANGE_METHOD);
+  }
+
+  /* Return result of calling OVERLAY_UNMAPPED_ADDRESS_METHOD.
+
+     See pc_in_unmapped_range above regarding unused section parameter.  */
+
+  CORE_ADDR
+  overlay_unmapped_address (CORE_ADDR addr,
+			    ATTRIBUTE_UNUSED struct obj_section *section)
+			   override
+  {
+    return call_python_addr (addr, OVERLAY_UNMAPPED_ADDRESS_METHOD);
+  }
+
+  /* Return result of calling OVERLAY_MAPPED_ADDRESS_METHOD.
+
+     See pc_in_unmapped_range above regarding unused section parameter.  */
+
+  CORE_ADDR
+  overlay_mapped_address (CORE_ADDR addr,
+			  ATTRIBUTE_UNUSED struct obj_section *section)
+			 override
+  {
+    return call_python_addr (addr, OVERLAY_MAPPED_ADDRESS_METHOD);
+  }
+
+  /* Return result of calling SYMBOL_OVERLAYED_ADDRESS_METHOD.
+
+     See pc_in_unmapped_range above regarding unused section parameter.  */
+
+  CORE_ADDR
+  symbol_overlayed_address (CORE_ADDR addr,
+			    ATTRIBUTE_UNUSED struct obj_section *section)
+			   override
+  {
+    return call_python_addr (addr, SYMBOL_OVERLAYED_ADDRESS_METHOD);
+  }
+
+  /* Return result of calling OVERLAY_UPDATE_METHOD.
+
+     See pc_in_unmapped_range above regarding unused section parameter.  */
+
+  void
+  overlay_update (ATTRIBUTE_UNUSED obj_section *) override
+  {
+    call_python_void (OVERLAY_UPDATE_METHOD);
+  }
+
+  /* Return result of calling OVERLAY_ADDRESS_FOR_SAL_METHOD.  */
+
+  CORE_ADDR
+  overlay_address_for_sal (CORE_ADDR addr) override
+  {
+    return call_python_addr (addr, OVERLAY_ADDRESS_FOR_SAL_METHOD);
+  }
+
+  /* Since GDB python has no concept of sections, we cannot currently support
+     python overlay managers that need to deal with overlay sections.  The
+     following methods are not required for non-section based managers so they
+     simply return nullptr or false.
+  */
+
+  struct obj_section *
+  find_pc_mapped_section (CORE_ADDR) override
+  {
+    return nullptr;
+  }
+
+  struct obj_section *
+  find_pc_overlay (CORE_ADDR) override
+  {
+    return nullptr;
+  }
+
+  bool
+  section_is_overlay (ATTRIBUTE_UNUSED struct obj_section *) override
+  {
+    return false;
+  }
+
+  bool
+  section_is_mapped (ATTRIBUTE_UNUSED struct obj_section *) override
+  {
+    return false;
+  }
+
+  void list_overlays_command (const char *args, int from_tty) override
+  {
+    call_python_void (LIST_OVERLAYS_COMMAND_METHOD);
+  }
+
+  void map_overlay_command (const char *args, int from_tty) override
+  {
+    call_python_void (MAP_OVERLAY_COMMAND_METHOD);
+  }
+
+  void unmap_overlay_command (const char *args, int from_tty) override
+  {
+    call_python_void (UNMAP_OVERLAY_COMMAND_METHOD);
+  }
+
+  void overlay_load_command (const char *args, int from_tty) override
+  {
+    overlay_update (nullptr);
+  }
+
+  /* The Python object associated with this overlay manager.  */
+  gdbpy_ovly_mgr_object *m_obj;
+};
+
+/* Wrapper around a Python object, provides a mechanism to find the overlay
+   manager object from the Python object.  */
+
+struct gdbpy_ovly_mgr_object {
+  /* Python boilerplate, must come first.  */
+  PyObject_HEAD
+
+  /* Point at the actual overlay manager we created when this Python object
+     was created.  This object is owned by the generic overlay management
+     code within GDB.  */
+  gdb_py_overlay_manager *manager;
+};
+
+/* Initializer for OverlayManager object, it takes no parameters.  */
+
+static int
+ovlpy_init (PyObject *self, PyObject *args, PyObject *kwargs)
+{
+  gdbpy_ovly_mgr_object *obj = (gdbpy_ovly_mgr_object *) self;
+  std::unique_ptr <gdb_py_overlay_manager> mgr
+    (new gdb_py_overlay_manager (obj));
+  obj->manager = mgr.get ();
+  overlay_manager_register (std::move (mgr));
+  return 0;
+}
+
+/* Deallocate OverlayManager object.  */
+
+static void
+ovlpy_dealloc (PyObject *self)
+{
+  /* TODO: Should ensure that this object is no longer registered as the
+     overlay manager for GDB otherwise bad things will happen.  */
+
+  /* Set this pointer to null not because we have to, but to protect
+     against any uses after we deallocate.  */
+  gdbpy_ovly_mgr_object *obj = (gdbpy_ovly_mgr_object *) self;
+  obj->manager = nullptr;
+
+  /* Now ask Python to free this object.  */
+  Py_TYPE (self)->tp_free (self);
+}
+
+void
+gdbpy_finalize_overlay (void)
+{
+  overlay_manager_register (nullptr);
+}
+
+/* Structure defining an OverlayManager object type.  */
+
+PyTypeObject overlay_manager_object_type =
+{
+  PyVarObject_HEAD_INIT (NULL, 0)
+  "gdb.OverlayManager",		  /*tp_name*/
+  sizeof (gdbpy_ovly_mgr_object), /*tp_basicsize*/
+  0,				  /*tp_itemsize*/
+  ovlpy_dealloc,		  /*tp_dealloc*/
+  0,				  /*tp_print*/
+  0,				  /*tp_getattr*/
+  0,				  /*tp_setattr*/
+  0,				  /*tp_compare*/
+  0,				  /*tp_repr*/
+  0,				  /*tp_as_number*/
+  0,				  /*tp_as_sequence*/
+  0,				  /*tp_as_mapping*/
+  0,				  /*tp_hash */
+  0,				  /*tp_call*/
+  0,				  /*tp_str*/
+  0,				  /*tp_getattro*/
+  0,				  /*tp_setattro */
+  0,				  /*tp_as_buffer*/
+  Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,  /*tp_flags*/
+  "GDB overlay manager object",	  /* tp_doc */
+  0,				  /* tp_traverse */
+  0,				  /* tp_clear */
+  0,				  /* tp_richcompare */
+  0,				  /* tp_weaklistoffset */
+  0,				  /* tp_iter */
+  0,				  /* tp_iternext */
+  0,				  /* tp_methods */
+  0,				  /* tp_members */
+  0,				  /* tp_getset */
+  0,				  /* tp_base */
+  0,				  /* tp_dict */
+  0,				  /* tp_descr_get */
+  0,				  /* tp_descr_set */
+  0,				  /* tp_dictoffset */
+  ovlpy_init,			  /* tp_init */
+  0,				  /* tp_alloc */
+};
+
+/* Initialize the Python overlay code.  */
+int
+gdbpy_initialize_overlay (void)
+{
+  overlay_manager_object_type.tp_new = PyType_GenericNew;
+  if (PyType_Ready (&overlay_manager_object_type) < 0)
+    return -1;
+
+  if (gdb_pymodule_addobject (gdb_module, "OverlayManager",
+			      (PyObject *) &overlay_manager_object_type) < 0)
+    return -1;
+  return 0;
+}
diff --git a/gdb/python/python-internal.h b/gdb/python/python-internal.h
index d947b96033b..e898017690c 100644
--- a/gdb/python/python-internal.h
+++ b/gdb/python/python-internal.h
@@ -540,6 +540,9 @@ int gdbpy_initialize_connection ()
 int gdbpy_initialize_micommands (void)
   CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
 void gdbpy_finalize_micommands ();
+int gdbpy_initialize_overlay (void)
+  CPYCHECKER_NEGATIVE_RESULT_SETS_EXCEPTION;
+void gdbpy_finalize_overlay (void);
 
 /* A wrapper for PyErr_Fetch that handles reference counting for the
    caller.  */
diff --git a/gdb/python/python.c b/gdb/python/python.c
index 7a9c8c1b66e..f2e03a5769e 100644
--- a/gdb/python/python.c
+++ b/gdb/python/python.c
@@ -1892,6 +1892,7 @@ finalize_python (void *ignore)
   gdbpy_enter::finalize ();
 
   gdbpy_finalize_micommands ();
+  gdbpy_finalize_overlay ();
 
   Py_Finalize ();
 
@@ -2072,7 +2073,8 @@ do_start_initialization ()
       || gdbpy_initialize_membuf () < 0
       || gdbpy_initialize_connection () < 0
       || gdbpy_initialize_tui () < 0
-      || gdbpy_initialize_micommands () < 0)
+      || gdbpy_initialize_micommands () < 0
+      || gdbpy_initialize_overlay () < 0)
     return false;
 
 #define GDB_PY_DEFINE_EVENT_TYPE(name, py_name, doc, base)	\
-- 
2.17.1


^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2022-05-09 21:52 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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 ` [RFC PATCH 2/3] gdb: Add new overlay manager class Craig Blackmore
2022-05-09 21:51 ` [RFC PATCH 3/3] gdb: Add support for writing overlay managers in python Craig Blackmore

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).