gdb: make find_memory_region_ftype a function_view

Make it a function_view and remove the `void *` parameter.  Convert the
callers (in gcore.c) to use lambda functions that capture `obfd`.

The target_debug_print_find_memory_region_ftype debug printer isn't
terribly useful, but I don't see a good way to print a function_view
with what we have right now.

Since find_memory_region_ftype needs to be seen by both gdbarch.h and
target.h, I chose to move the typedef to a new file
(find-memory-region.h), that is included by both.

Change-Id: I9d24d31da31e5fe0439124cec1a9757ad226b222
Approved-By: Tom Tromey <tom@tromey.com>
This commit is contained in:
Simon Marchi 2026-03-14 15:06:01 -04:00
parent ebec91612c
commit 695fd5ec12
21 changed files with 125 additions and 120 deletions

View file

@ -1455,6 +1455,7 @@ HFILES_NO_SRCDIR = \
f-exp.h \
filename-seen-cache.h \
filesystem.h \
find-memory-region.h \
finish-thread-state.h \
f-lang.h \
frame-base.h \

View file

@ -212,24 +212,6 @@ extern int print_address_symbolic (struct gdbarch *, CORE_ADDR,
extern void print_address (struct gdbarch *, CORE_ADDR, struct ui_file *);
extern const char *pc_prefix (CORE_ADDR);
/* From exec.c */
/* Process memory area starting at ADDR with length SIZE. Area is readable iff
READ is true, writable if WRITE is true, executable if EXEC is true. Area
is possibly changed against its original file based copy if MODIFIED is true.
MEMORY_TAGGED is true if the memory region contains memory tags, false
otherwise.
DATA is passed without changes from a caller.
Return true on success, false otherwise. */
typedef bool (*find_memory_region_ftype) (CORE_ADDR addr, unsigned long size,
bool read, bool write, bool exec,
bool modified, bool memory_tagged,
void *data);
/* * Possible lvalue types. Like enum language, this should be in
value.h, but needs to be here for the same reason. */

View file

@ -77,7 +77,7 @@ struct exec_target final : public target_ops
bool has_memory () override;
gdb::unique_xmalloc_ptr<char> make_corefile_notes (bfd *, int *) override;
bool find_memory_regions (find_memory_region_ftype func, void *data) override;
bool find_memory_regions (find_memory_region_ftype func) override;
};
static exec_target exec_ops;
@ -1071,9 +1071,9 @@ exec_target::make_corefile_notes (bfd *obfd, int *note_size)
}
bool
exec_target::find_memory_regions (find_memory_region_ftype func, void *data)
exec_target::find_memory_regions (find_memory_region_ftype func)
{
return objfile_find_memory_regions (this, func, data);
return objfile_find_memory_regions (this, func);
}
INIT_GDB_FILE (exec)

View file

@ -142,12 +142,10 @@ fbsd_nat_target::pid_to_exec_file (int pid)
}
/* Iterate over all the memory regions in the current inferior,
calling FUNC for each memory region. DATA is passed as the last
argument to FUNC. */
calling FUNC for each memory region. */
bool
fbsd_nat_target::find_memory_regions (find_memory_region_ftype func,
void *data)
fbsd_nat_target::find_memory_regions (find_memory_region_ftype func)
{
pid_t pid = inferior_ptid.pid ();
struct kinfo_vmentry *kve;
@ -188,7 +186,7 @@ fbsd_nat_target::find_memory_regions (find_memory_region_ftype func,
Pass MODIFIED as true, we do not know the real modification state. */
func (kve->kve_start, size, kve->kve_protection & KVME_PROT_READ,
kve->kve_protection & KVME_PROT_WRITE,
kve->kve_protection & KVME_PROT_EXEC, true, false, data);
kve->kve_protection & KVME_PROT_EXEC, true, false);
}
return true;
}

View file

@ -49,7 +49,7 @@ class fbsd_nat_target : public inf_ptrace_target
public:
const char *pid_to_exec_file (int pid) override;
bool find_memory_regions (find_memory_region_ftype func, void *data) override;
bool find_memory_regions (find_memory_region_ftype func) override;
bool info_proc (const char *, enum info_proc_what) override;

37
gdb/find-memory-region.h Normal file
View file

@ -0,0 +1,37 @@
/* Copyright (C) 2026 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/>. */
#ifndef GDB_FIND_MEMORY_REGION_H
#define GDB_FIND_MEMORY_REGION_H
#include "gdbsupport/function-view.h"
/* Process memory area starting at ADDR with length SIZE. Area is readable iff
READ is true, writable if WRITE is true, executable if EXEC is true. Area
is possibly changed against its original file based copy if MODIFIED is true.
MEMORY_TAGGED is true if the memory region contains memory tags, false
otherwise.
Return true on success, false otherwise. */
using find_memory_region_ftype
= gdb::function_view<bool (CORE_ADDR addr, unsigned long size, bool read,
bool write, bool exec, bool modified,
bool memory_tagged)>;
#endif /* GDB_FIND_MEMORY_REGION_H */

View file

@ -395,14 +395,13 @@ make_output_phdrs (bfd *obfd, asection *osec)
MEMORY_TAGGED is true if the memory region contains memory tags, false
otherwise.
DATA is 'bfd *' for the core file GDB is creating. */
OBFD is the core file GDB is creating. */
static bool
gcore_create_callback (CORE_ADDR vaddr, unsigned long size, bool read,
bool write, bool exec, bool modified, bool memory_tagged,
void *data)
bool write, bool exec, bool modified,
bool memory_tagged, bfd *obfd)
{
bfd *obfd = (bfd *) data;
asection *osec;
flagword flags = SEC_ALLOC | SEC_HAS_CONTENTS | SEC_LOAD;
@ -485,20 +484,18 @@ gcore_create_callback (CORE_ADDR vaddr, unsigned long size, bool read,
MEMORY_TAGGED is true if the memory region contains memory tags, false
otherwise.
DATA is 'bfd *' for the core file GDB is creating. */
OBFD is the core file GDB is creating. */
static bool
gcore_create_memtag_section_callback (CORE_ADDR vaddr, unsigned long size,
bool read, bool write, bool exec,
bool modified, bool memory_tagged,
void *data)
bfd *obfd)
{
/* Are there memory tags in this particular memory map entry? */
if (!memory_tagged)
return true;
bfd *obfd = (bfd *) data;
/* Ask the architecture to create a memory tag section for this particular
memory map entry. It will be populated with contents later, as we can't
start writing the contents before we have all the sections sorted out. */
@ -526,7 +523,7 @@ gcore_create_memtag_section_callback (CORE_ADDR vaddr, unsigned long size,
bool
objfile_find_memory_regions (struct target_ops *self,
find_memory_region_ftype func, void *obfd)
find_memory_region_ftype func)
{
/* Use objfile data to create memory sections. */
bfd_vma temp_bottom = 0, temp_top = 0;
@ -550,8 +547,7 @@ objfile_find_memory_regions (struct target_ops *self,
(flags & SEC_READONLY) == 0, /* Writable. */
(flags & SEC_CODE) != 0, /* Executable. */
true, /* MODIFIED is unknown, pass it as true. */
false, /* No memory tags in the object file. */
obfd);
false /* No memory tags in the object file. */);
if (!ret)
return ret;
}
@ -564,8 +560,7 @@ objfile_find_memory_regions (struct target_ops *self,
true, /* Stack section will be writable. */
false, /* Stack section will not be executable. */
true, /* Stack section will be modified. */
false, /* No memory tags in the object file. */
obfd))
false /* No memory tags in the object file. */))
return false;
/* Make a heap segment. */
@ -576,8 +571,7 @@ objfile_find_memory_regions (struct target_ops *self,
true, /* Heap section will be writable. */
false, /* Heap section will not be executable. */
true, /* Heap section will be modified. */
false, /* No memory tags in the object file. */
obfd))
false /* No memory tags in the object file. */))
return false;
return true;
@ -847,23 +841,36 @@ gcore_copy_memtag_section_callback (bfd *obfd, asection *osec)
static bool
gcore_memory_sections (bfd *obfd)
{
auto cb = [obfd] (CORE_ADDR vaddr, unsigned long size, bool read, bool write,
bool exec, bool modified, bool memory_tagged)
{
return gcore_create_callback (vaddr, size, read, write, exec, modified,
memory_tagged, obfd);
};
/* Try gdbarch method first, then fall back to target method. */
gdbarch *arch = current_inferior ()->arch ();
if (!gdbarch_find_memory_regions_p (arch)
|| !gdbarch_find_memory_regions (arch, gcore_create_callback, obfd))
|| !gdbarch_find_memory_regions (arch, cb))
{
if (!target_find_memory_regions (gcore_create_callback, obfd))
if (!target_find_memory_regions (cb))
return false; /* FIXME: error return/msg? */
}
auto cb_memtag = [obfd] (CORE_ADDR vaddr, unsigned long size, bool read,
bool write, bool exec, bool modified,
bool memory_tagged)
{
return gcore_create_memtag_section_callback (vaddr, size, read, write,
exec, modified,
memory_tagged, obfd);
};
/* Take care of dumping memory tags, if there are any. */
if (!gdbarch_find_memory_regions_p (arch)
|| !gdbarch_find_memory_regions (arch,
gcore_create_memtag_section_callback,
obfd))
|| !gdbarch_find_memory_regions (arch, cb_memtag))
{
if (!target_find_memory_regions (gcore_create_memtag_section_callback,
obfd))
if (!target_find_memory_regions (cb_memtag))
return false;
}

View file

@ -20,6 +20,7 @@
#ifndef GDB_GCORE_H
#define GDB_GCORE_H
#include "find-memory-region.h"
#include "gdb_bfd.h"
struct thread_info;
@ -27,8 +28,7 @@ struct thread_info;
extern gdb_bfd_ref_ptr create_gcore_bfd (const char *filename);
extern void write_gcore_file (bfd *obfd);
extern bool objfile_find_memory_regions (struct target_ops *self,
find_memory_region_ftype func,
void *obfd);
find_memory_region_ftype func);
/* Find the signalled thread. In case there's more than one signalled
thread, prefer the current thread, if it is signalled. If no thread was

View file

@ -3674,13 +3674,13 @@ gdbarch_find_memory_regions_p (struct gdbarch *gdbarch)
}
bool
gdbarch_find_memory_regions (struct gdbarch *gdbarch, find_memory_region_ftype func, void *data)
gdbarch_find_memory_regions (struct gdbarch *gdbarch, find_memory_region_ftype func)
{
gdb_assert (gdbarch != nullptr);
gdb_assert (gdbarch->find_memory_regions != nullptr);
if (gdbarch_debug >= 2)
gdb_printf (gdb_stdlog, "gdbarch_find_memory_regions called\n");
return gdbarch->find_memory_regions (gdbarch, func, data);
return gdbarch->find_memory_regions (gdbarch, func);
}
void

View file

@ -962,8 +962,8 @@ void set_gdbarch_make_corefile_notes (struct gdbarch *gdbarch, gdbarch_make_core
bool gdbarch_find_memory_regions_p (struct gdbarch *gdbarch);
using gdbarch_find_memory_regions_ftype = bool (struct gdbarch *gdbarch, find_memory_region_ftype func, void *data);
bool gdbarch_find_memory_regions (struct gdbarch *gdbarch, find_memory_region_ftype func, void *data);
using gdbarch_find_memory_regions_ftype = bool (struct gdbarch *gdbarch, find_memory_region_ftype func);
bool gdbarch_find_memory_regions (struct gdbarch *gdbarch, find_memory_region_ftype func);
void set_gdbarch_find_memory_regions (struct gdbarch *gdbarch, gdbarch_find_memory_regions_ftype *find_memory_regions);
/* Given a bfd OBFD, segment ADDRESS and SIZE, create a memory tag section to be dumped to a core file */

View file

@ -31,6 +31,7 @@
#include "gdbsupport/gdb-checked-static-cast.h"
#include "registry.h"
#include "solib.h"
#include "find-memory-region.h"
struct floatformat;
struct ui_file;

View file

@ -1636,7 +1636,7 @@ Find core file memory regions
""",
type="bool",
name="find_memory_regions",
params=[("find_memory_region_ftype", "func"), ("void *", "data")],
params=[("find_memory_region_ftype", "func")],
predicate=True,
)

View file

@ -2566,8 +2566,7 @@ gnu_nat_target::xfer_partial (enum target_object object,
/* Call FUNC on each memory region in the task. */
bool
gnu_nat_target::find_memory_regions (find_memory_region_ftype func,
void *data)
gnu_nat_target::find_memory_regions (find_memory_region_ftype func)
{
kern_return_t err;
task_t task;
@ -2624,8 +2623,7 @@ gnu_nat_target::find_memory_regions (find_memory_region_ftype func,
last_protection & VM_PROT_WRITE,
last_protection & VM_PROT_EXECUTE,
true, /* MODIFIED is unknown, pass it as true. */
false, /* No memory tags in the object file. */
data);
false /* No memory tags in the object file. */);
last_region_address = region_address;
last_region_end = region_address += region_length;
last_protection = protection;
@ -2634,13 +2632,12 @@ gnu_nat_target::find_memory_regions (find_memory_region_ftype func,
/* Report the final region. */
if (last_region_end > last_region_address && last_protection != VM_PROT_NONE)
(*func) (last_region_address, last_region_end - last_region_address,
last_protection & VM_PROT_READ,
last_protection & VM_PROT_WRITE,
last_protection & VM_PROT_EXECUTE,
1, /* MODIFIED is unknown, pass it as true. */
false, /* No memory tags in the object file. */
data);
func (last_region_address, last_region_end - last_region_address,
last_protection & VM_PROT_READ,
last_protection & VM_PROT_WRITE,
last_protection & VM_PROT_EXECUTE,
true, /* MODIFIED is unknown, pass it as true. */
false /* No memory tags in the object file. */);
return true;
}

View file

@ -1624,15 +1624,12 @@ linux_find_memory_regions_full (struct gdbarch *gdbarch,
static bool
linux_find_memory_regions (struct gdbarch *gdbarch,
find_memory_region_ftype func, void *data)
find_memory_region_ftype func)
{
auto cb = [&] (ULONGEST vaddr, ULONGEST size, ULONGEST offset, bool read,
bool write, bool exec, bool modified, bool memory_tagged,
const std::string &filename)
{
return func (vaddr, size, read, write, exec, modified, memory_tagged,
data);
};
{ return func (vaddr, size, read, write, exec, modified, memory_tagged); };
return linux_find_memory_regions_full (gdbarch, dump_mapping_p, cb);
}

View file

@ -209,12 +209,10 @@ nbsd_kinfo_get_vmmap (pid_t pid, size_t *size)
}
/* Iterate over all the memory regions in the current inferior,
calling FUNC for each memory region. OBFD is passed as the last
argument to FUNC. */
calling FUNC for each memory region. */
bool
nbsd_nat_target::find_memory_regions (find_memory_region_ftype func,
void *data)
nbsd_nat_target::find_memory_regions (find_memory_region_ftype func)
{
pid_t pid = inferior_ptid.pid ();
@ -260,7 +258,7 @@ nbsd_nat_target::find_memory_regions (find_memory_region_ftype func,
Pass MODIFIED as true, we do not know the real modification state. */
func (kve->kve_start, size, kve->kve_protection & KVME_PROT_READ,
kve->kve_protection & KVME_PROT_WRITE,
kve->kve_protection & KVME_PROT_EXEC, true, false, data);
kve->kve_protection & KVME_PROT_EXEC, true, false);
}
return true;
}

View file

@ -36,7 +36,7 @@ struct nbsd_nat_target : public inf_ptrace_target
void update_thread_list () override;
std::string pid_to_str (ptid_t ptid) override;
bool find_memory_regions (find_memory_region_ftype func, void *data) override;
bool find_memory_regions (find_memory_region_ftype func) override;
bool info_proc (const char *, enum info_proc_what) override;
void resume (ptid_t, int, enum gdb_signal) override;

View file

@ -134,8 +134,7 @@ public:
{ return tc_schedlock; }
/* find_memory_regions support method for gcore */
bool find_memory_regions (find_memory_region_ftype func, void *data)
override;
bool find_memory_regions (find_memory_region_ftype func) override;
gdb::unique_xmalloc_ptr<char> make_corefile_notes (bfd *, int *) override;
@ -3107,10 +3106,8 @@ procfs_target::region_ok_for_hw_watchpoint (CORE_ADDR addr, int len)
static bool
iterate_over_mappings (procinfo *pi, find_memory_region_ftype child_func,
void *data,
bool (*func) (struct prmap *map,
find_memory_region_ftype child_func,
void *data))
find_memory_region_ftype child_func))
{
char pathname[MAX_PROC_NAME_SIZE];
struct prmap *prmaps;
@ -3139,7 +3136,7 @@ iterate_over_mappings (procinfo *pi, find_memory_region_ftype child_func,
proc_error (pi, "iterate_over_mappings (read)", __LINE__);
for (prmap = prmaps; nmap > 0; prmap++, nmap--)
if (!func (prmap, child_func, data))
if (!func (prmap, child_func))
return false;
return true;
@ -3150,17 +3147,15 @@ iterate_over_mappings (procinfo *pi, find_memory_region_ftype child_func,
Returns the value returned by the callback. */
static bool
find_memory_regions_callback (struct prmap *map,
find_memory_region_ftype func, void *data)
find_memory_regions_callback (struct prmap *map, find_memory_region_ftype func)
{
return (*func) ((CORE_ADDR) map->pr_vaddr,
map->pr_size,
(map->pr_mflags & MA_READ) != 0,
(map->pr_mflags & MA_WRITE) != 0,
(map->pr_mflags & MA_EXEC) != 0,
true, /* MODIFIED is unknown, pass it as true. */
false,
data);
return func ((CORE_ADDR) map->pr_vaddr,
map->pr_size,
(map->pr_mflags & MA_READ) != 0,
(map->pr_mflags & MA_WRITE) != 0,
(map->pr_mflags & MA_EXEC) != 0,
true, /* MODIFIED is unknown, pass it as true. */
false);
}
/* External interface. Calls a callback function once for each
@ -3176,12 +3171,11 @@ find_memory_regions_callback (struct prmap *map,
the callback. */
bool
procfs_target::find_memory_regions (find_memory_region_ftype func, void *data)
procfs_target::find_memory_regions (find_memory_region_ftype func)
{
procinfo *pi = find_procinfo_or_die (inferior_ptid.pid (), 0);
return iterate_over_mappings (pi, func, data,
find_memory_regions_callback);
return iterate_over_mappings (pi, func, find_memory_regions_callback);
}
/* Returns an ascii representation of a memory mapping's flags. */

View file

@ -170,13 +170,9 @@ target_debug_print_const_std_vector_target_section_p
(const std::vector<target_section> *vec)
{ return host_address_to_string (vec->data ()); }
static std::string
target_debug_print_void_p (void *p)
{ return host_address_to_string (p); }
static std::string
target_debug_print_find_memory_region_ftype (find_memory_region_ftype func)
{ return host_address_to_string (func); }
{ return "<function_view>"; }
static std::string
target_debug_print_bfd_p (bfd *bfd)

View file

@ -109,7 +109,7 @@ struct dummy_target : public target_ops
bool supports_set_thread_options (gdb_thread_options arg0) override;
bool supports_non_stop () override;
bool always_non_stop_p () override;
bool find_memory_regions (find_memory_region_ftype arg0, void *arg1) override;
bool find_memory_regions (find_memory_region_ftype arg0) override;
gdb::unique_xmalloc_ptr<char> make_corefile_notes (bfd *arg0, int *arg1) override;
gdb_byte *get_bookmark (const char *arg0, int arg1) override;
void goto_bookmark (const gdb_byte *arg0, int arg1) override;
@ -290,7 +290,7 @@ struct debug_target : public target_ops
bool supports_set_thread_options (gdb_thread_options arg0) override;
bool supports_non_stop () override;
bool always_non_stop_p () override;
bool find_memory_regions (find_memory_region_ftype arg0, void *arg1) override;
bool find_memory_regions (find_memory_region_ftype arg0) override;
gdb::unique_xmalloc_ptr<char> make_corefile_notes (bfd *arg0, int *arg1) override;
gdb_byte *get_bookmark (const char *arg0, int arg1) override;
void goto_bookmark (const gdb_byte *arg0, int arg1) override;
@ -2266,27 +2266,26 @@ debug_target::always_non_stop_p ()
}
bool
target_ops::find_memory_regions (find_memory_region_ftype arg0, void *arg1)
target_ops::find_memory_regions (find_memory_region_ftype arg0)
{
return this->beneath ()->find_memory_regions (arg0, arg1);
return this->beneath ()->find_memory_regions (arg0);
}
bool
dummy_target::find_memory_regions (find_memory_region_ftype arg0, void *arg1)
dummy_target::find_memory_regions (find_memory_region_ftype arg0)
{
return dummy_find_memory_regions (this, arg0, arg1);
return dummy_find_memory_regions (this, arg0);
}
bool
debug_target::find_memory_regions (find_memory_region_ftype arg0, void *arg1)
debug_target::find_memory_regions (find_memory_region_ftype arg0)
{
target_debug_printf_nofunc ("-> %s->find_memory_regions (...)", this->beneath ()->shortname ());
bool result
= this->beneath ()->find_memory_regions (arg0, arg1);
target_debug_printf_nofunc ("<- %s->find_memory_regions (%s, %s) = %s",
= this->beneath ()->find_memory_regions (arg0);
target_debug_printf_nofunc ("<- %s->find_memory_regions (%s) = %s",
this->beneath ()->shortname (),
target_debug_print_find_memory_region_ftype (arg0).c_str (),
target_debug_print_void_p (arg1).c_str (),
target_debug_print_bool (result).c_str ());
return result;
}

View file

@ -416,9 +416,9 @@ target_thread_architecture (ptid_t ptid)
/* See target.h. */
bool
target_find_memory_regions (find_memory_region_ftype func, void *data)
target_find_memory_regions (find_memory_region_ftype func)
{
return current_inferior ()->top_target ()->find_memory_regions (func, data);
return current_inferior ()->top_target ()->find_memory_regions (func);
}
/* See target.h. */
@ -3686,8 +3686,7 @@ default_pid_to_str (struct target_ops *ops, ptid_t ptid)
/* Error-catcher for target_find_memory_regions. */
static bool
dummy_find_memory_regions (struct target_ops *self,
find_memory_region_ftype ignore1, void *ignore2)
dummy_find_memory_regions (target_ops *self, find_memory_region_ftype ignore1)
{
error (_("Command not implemented for this target."));
}

View file

@ -85,8 +85,8 @@ typedef const gdb_byte const_gdb_byte;
#include "tracepoint.h"
#include "gdbsupport/fileio.h"
#include "gdbsupport/x86-xstate.h"
#include "gdbsupport/break-common.h"
#include "find-memory-region.h"
enum strata
{
@ -765,7 +765,7 @@ struct target_ops
virtual bool always_non_stop_p ()
TARGET_DEFAULT_RETURN (false);
/* find_memory_regions support method for gcore */
virtual bool find_memory_regions (find_memory_region_ftype func, void *data)
virtual bool find_memory_regions (find_memory_region_ftype func)
TARGET_DEFAULT_FUNC (dummy_find_memory_regions);
/* make_corefile_notes support method for gcore */
virtual gdb::unique_xmalloc_ptr<char> make_corefile_notes (bfd *, int *)
@ -2040,8 +2040,7 @@ extern gdbarch *target_thread_architecture (ptid_t ptid);
If FUNC ever returns false, stop iterating and return false. Otherwise,
return true. */
extern bool target_find_memory_regions (find_memory_region_ftype func,
void *data);
extern bool target_find_memory_regions (find_memory_region_ftype func);
/*
* Compose corefile .note section.