mirror of
https://github.com/espressif/binutils-gdb.git
synced 2025-08-06 14:49:38 +08:00

Many spots incorrectly use only spaces for indentation (for example, there are a lot of spots in ada-lang.c). I've always found it awkward when I needed to edit one of these spots: do I keep the original wrong indentation, or do I fix it? What if the lines around it are also wrong, do I fix them too? I probably don't want to fix them in the same patch, to avoid adding noise to my patch. So I propose to fix as much as possible once and for all (hopefully). One typical counter argument for this is that it makes code archeology more difficult, because git-blame will show this commit as the last change for these lines. My counter counter argument is: when git-blaming, you often need to do "blame the file at the parent commit" anyway, to go past some other refactor that touched the line you are interested in, but is not the change you are looking for. So you already need a somewhat efficient way to do this. Using some interactive tool, rather than plain git-blame, makes this trivial. For example, I use "tig blame <file>", where going back past the commit that changed the currently selected line is one keystroke. It looks like Magit in Emacs does it too (though I've never used it). Web viewers of Github and Gitlab do it too. My point is that it won't really make archeology more difficult. The other typical counter argument is that it will cause conflicts with existing patches. That's true... but it's a one time cost, and those are not conflicts that are difficult to resolve. I have also tried "git rebase --ignore-whitespace", it seems to work well. Although that will re-introduce the faulty indentation, so one needs to take care of fixing the indentation in the patch after that (which is easy). gdb/ChangeLog: * aarch64-linux-tdep.c: Fix indentation. * aarch64-ravenscar-thread.c: Fix indentation. * aarch64-tdep.c: Fix indentation. * aarch64-tdep.h: Fix indentation. * ada-lang.c: Fix indentation. * ada-lang.h: Fix indentation. * ada-tasks.c: Fix indentation. * ada-typeprint.c: Fix indentation. * ada-valprint.c: Fix indentation. * ada-varobj.c: Fix indentation. * addrmap.c: Fix indentation. * addrmap.h: Fix indentation. * agent.c: Fix indentation. * aix-thread.c: Fix indentation. * alpha-bsd-nat.c: Fix indentation. * alpha-linux-tdep.c: Fix indentation. * alpha-mdebug-tdep.c: Fix indentation. * alpha-nbsd-tdep.c: Fix indentation. * alpha-obsd-tdep.c: Fix indentation. * alpha-tdep.c: Fix indentation. * amd64-bsd-nat.c: Fix indentation. * amd64-darwin-tdep.c: Fix indentation. * amd64-linux-nat.c: Fix indentation. * amd64-linux-tdep.c: Fix indentation. * amd64-nat.c: Fix indentation. * amd64-obsd-tdep.c: Fix indentation. * amd64-tdep.c: Fix indentation. * amd64-windows-tdep.c: Fix indentation. * annotate.c: Fix indentation. * arc-tdep.c: Fix indentation. * arch-utils.c: Fix indentation. * arch/arm-get-next-pcs.c: Fix indentation. * arch/arm.c: Fix indentation. * arm-linux-nat.c: Fix indentation. * arm-linux-tdep.c: Fix indentation. * arm-nbsd-tdep.c: Fix indentation. * arm-pikeos-tdep.c: Fix indentation. * arm-tdep.c: Fix indentation. * arm-tdep.h: Fix indentation. * arm-wince-tdep.c: Fix indentation. * auto-load.c: Fix indentation. * auxv.c: Fix indentation. * avr-tdep.c: Fix indentation. * ax-gdb.c: Fix indentation. * ax-general.c: Fix indentation. * bfin-linux-tdep.c: Fix indentation. * block.c: Fix indentation. * block.h: Fix indentation. * blockframe.c: Fix indentation. * bpf-tdep.c: Fix indentation. * break-catch-sig.c: Fix indentation. * break-catch-syscall.c: Fix indentation. * break-catch-throw.c: Fix indentation. * breakpoint.c: Fix indentation. * breakpoint.h: Fix indentation. * bsd-uthread.c: Fix indentation. * btrace.c: Fix indentation. * build-id.c: Fix indentation. * buildsym-legacy.h: Fix indentation. * buildsym.c: Fix indentation. * c-typeprint.c: Fix indentation. * c-valprint.c: Fix indentation. * c-varobj.c: Fix indentation. * charset.c: Fix indentation. * cli/cli-cmds.c: Fix indentation. * cli/cli-decode.c: Fix indentation. * cli/cli-decode.h: Fix indentation. * cli/cli-script.c: Fix indentation. * cli/cli-setshow.c: Fix indentation. * coff-pe-read.c: Fix indentation. * coffread.c: Fix indentation. * compile/compile-cplus-types.c: Fix indentation. * compile/compile-object-load.c: Fix indentation. * compile/compile-object-run.c: Fix indentation. * completer.c: Fix indentation. * corefile.c: Fix indentation. * corelow.c: Fix indentation. * cp-abi.h: Fix indentation. * cp-namespace.c: Fix indentation. * cp-support.c: Fix indentation. * cp-valprint.c: Fix indentation. * cris-linux-tdep.c: Fix indentation. * cris-tdep.c: Fix indentation. * darwin-nat-info.c: Fix indentation. * darwin-nat.c: Fix indentation. * darwin-nat.h: Fix indentation. * dbxread.c: Fix indentation. * dcache.c: Fix indentation. * disasm.c: Fix indentation. * dtrace-probe.c: Fix indentation. * dwarf2/abbrev.c: Fix indentation. * dwarf2/attribute.c: Fix indentation. * dwarf2/expr.c: Fix indentation. * dwarf2/frame.c: Fix indentation. * dwarf2/index-cache.c: Fix indentation. * dwarf2/index-write.c: Fix indentation. * dwarf2/line-header.c: Fix indentation. * dwarf2/loc.c: Fix indentation. * dwarf2/macro.c: Fix indentation. * dwarf2/read.c: Fix indentation. * dwarf2/read.h: Fix indentation. * elfread.c: Fix indentation. * eval.c: Fix indentation. * event-top.c: Fix indentation. * exec.c: Fix indentation. * exec.h: Fix indentation. * expprint.c: Fix indentation. * f-lang.c: Fix indentation. * f-typeprint.c: Fix indentation. * f-valprint.c: Fix indentation. * fbsd-nat.c: Fix indentation. * fbsd-tdep.c: Fix indentation. * findvar.c: Fix indentation. * fork-child.c: Fix indentation. * frame-unwind.c: Fix indentation. * frame-unwind.h: Fix indentation. * frame.c: Fix indentation. * frv-linux-tdep.c: Fix indentation. * frv-tdep.c: Fix indentation. * frv-tdep.h: Fix indentation. * ft32-tdep.c: Fix indentation. * gcore.c: Fix indentation. * gdb_bfd.c: Fix indentation. * gdbarch.sh: Fix indentation. * gdbarch.c: Re-generate * gdbarch.h: Re-generate. * gdbcore.h: Fix indentation. * gdbthread.h: Fix indentation. * gdbtypes.c: Fix indentation. * gdbtypes.h: Fix indentation. * glibc-tdep.c: Fix indentation. * gnu-nat.c: Fix indentation. * gnu-nat.h: Fix indentation. * gnu-v2-abi.c: Fix indentation. * gnu-v3-abi.c: Fix indentation. * go32-nat.c: Fix indentation. * guile/guile-internal.h: Fix indentation. * guile/scm-cmd.c: Fix indentation. * guile/scm-frame.c: Fix indentation. * guile/scm-iterator.c: Fix indentation. * guile/scm-math.c: Fix indentation. * guile/scm-ports.c: Fix indentation. * guile/scm-pretty-print.c: Fix indentation. * guile/scm-value.c: Fix indentation. * h8300-tdep.c: Fix indentation. * hppa-linux-nat.c: Fix indentation. * hppa-linux-tdep.c: Fix indentation. * hppa-nbsd-nat.c: Fix indentation. * hppa-nbsd-tdep.c: Fix indentation. * hppa-obsd-nat.c: Fix indentation. * hppa-tdep.c: Fix indentation. * hppa-tdep.h: Fix indentation. * i386-bsd-nat.c: Fix indentation. * i386-darwin-nat.c: Fix indentation. * i386-darwin-tdep.c: Fix indentation. * i386-dicos-tdep.c: Fix indentation. * i386-gnu-nat.c: Fix indentation. * i386-linux-nat.c: Fix indentation. * i386-linux-tdep.c: Fix indentation. * i386-nto-tdep.c: Fix indentation. * i386-obsd-tdep.c: Fix indentation. * i386-sol2-nat.c: Fix indentation. * i386-tdep.c: Fix indentation. * i386-tdep.h: Fix indentation. * i386-windows-tdep.c: Fix indentation. * i387-tdep.c: Fix indentation. * i387-tdep.h: Fix indentation. * ia64-libunwind-tdep.c: Fix indentation. * ia64-libunwind-tdep.h: Fix indentation. * ia64-linux-nat.c: Fix indentation. * ia64-linux-tdep.c: Fix indentation. * ia64-tdep.c: Fix indentation. * ia64-tdep.h: Fix indentation. * ia64-vms-tdep.c: Fix indentation. * infcall.c: Fix indentation. * infcmd.c: Fix indentation. * inferior.c: Fix indentation. * infrun.c: Fix indentation. * iq2000-tdep.c: Fix indentation. * language.c: Fix indentation. * linespec.c: Fix indentation. * linux-fork.c: Fix indentation. * linux-nat.c: Fix indentation. * linux-tdep.c: Fix indentation. * linux-thread-db.c: Fix indentation. * lm32-tdep.c: Fix indentation. * m2-lang.c: Fix indentation. * m2-typeprint.c: Fix indentation. * m2-valprint.c: Fix indentation. * m32c-tdep.c: Fix indentation. * m32r-linux-tdep.c: Fix indentation. * m32r-tdep.c: Fix indentation. * m68hc11-tdep.c: Fix indentation. * m68k-bsd-nat.c: Fix indentation. * m68k-linux-nat.c: Fix indentation. * m68k-linux-tdep.c: Fix indentation. * m68k-tdep.c: Fix indentation. * machoread.c: Fix indentation. * macrocmd.c: Fix indentation. * macroexp.c: Fix indentation. * macroscope.c: Fix indentation. * macrotab.c: Fix indentation. * macrotab.h: Fix indentation. * main.c: Fix indentation. * mdebugread.c: Fix indentation. * mep-tdep.c: Fix indentation. * mi/mi-cmd-catch.c: Fix indentation. * mi/mi-cmd-disas.c: Fix indentation. * mi/mi-cmd-env.c: Fix indentation. * mi/mi-cmd-stack.c: Fix indentation. * mi/mi-cmd-var.c: Fix indentation. * mi/mi-cmds.c: Fix indentation. * mi/mi-main.c: Fix indentation. * mi/mi-parse.c: Fix indentation. * microblaze-tdep.c: Fix indentation. * minidebug.c: Fix indentation. * minsyms.c: Fix indentation. * mips-linux-nat.c: Fix indentation. * mips-linux-tdep.c: Fix indentation. * mips-nbsd-tdep.c: Fix indentation. * mips-tdep.c: Fix indentation. * mn10300-linux-tdep.c: Fix indentation. * mn10300-tdep.c: Fix indentation. * moxie-tdep.c: Fix indentation. * msp430-tdep.c: Fix indentation. * namespace.h: Fix indentation. * nat/fork-inferior.c: Fix indentation. * nat/gdb_ptrace.h: Fix indentation. * nat/linux-namespaces.c: Fix indentation. * nat/linux-osdata.c: Fix indentation. * nat/netbsd-nat.c: Fix indentation. * nat/x86-dregs.c: Fix indentation. * nbsd-nat.c: Fix indentation. * nbsd-tdep.c: Fix indentation. * nios2-linux-tdep.c: Fix indentation. * nios2-tdep.c: Fix indentation. * nto-procfs.c: Fix indentation. * nto-tdep.c: Fix indentation. * objfiles.c: Fix indentation. * objfiles.h: Fix indentation. * opencl-lang.c: Fix indentation. * or1k-tdep.c: Fix indentation. * osabi.c: Fix indentation. * osabi.h: Fix indentation. * osdata.c: Fix indentation. * p-lang.c: Fix indentation. * p-typeprint.c: Fix indentation. * p-valprint.c: Fix indentation. * parse.c: Fix indentation. * ppc-linux-nat.c: Fix indentation. * ppc-linux-tdep.c: Fix indentation. * ppc-nbsd-nat.c: Fix indentation. * ppc-nbsd-tdep.c: Fix indentation. * ppc-obsd-nat.c: Fix indentation. * ppc-ravenscar-thread.c: Fix indentation. * ppc-sysv-tdep.c: Fix indentation. * ppc64-tdep.c: Fix indentation. * printcmd.c: Fix indentation. * proc-api.c: Fix indentation. * producer.c: Fix indentation. * producer.h: Fix indentation. * prologue-value.c: Fix indentation. * prologue-value.h: Fix indentation. * psymtab.c: Fix indentation. * python/py-arch.c: Fix indentation. * python/py-bpevent.c: Fix indentation. * python/py-event.c: Fix indentation. * python/py-event.h: Fix indentation. * python/py-finishbreakpoint.c: Fix indentation. * python/py-frame.c: Fix indentation. * python/py-framefilter.c: Fix indentation. * python/py-inferior.c: Fix indentation. * python/py-infthread.c: Fix indentation. * python/py-objfile.c: Fix indentation. * python/py-prettyprint.c: Fix indentation. * python/py-registers.c: Fix indentation. * python/py-signalevent.c: Fix indentation. * python/py-stopevent.c: Fix indentation. * python/py-stopevent.h: Fix indentation. * python/py-threadevent.c: Fix indentation. * python/py-tui.c: Fix indentation. * python/py-unwind.c: Fix indentation. * python/py-value.c: Fix indentation. * python/py-xmethods.c: Fix indentation. * python/python-internal.h: Fix indentation. * python/python.c: Fix indentation. * ravenscar-thread.c: Fix indentation. * record-btrace.c: Fix indentation. * record-full.c: Fix indentation. * record.c: Fix indentation. * reggroups.c: Fix indentation. * regset.h: Fix indentation. * remote-fileio.c: Fix indentation. * remote.c: Fix indentation. * reverse.c: Fix indentation. * riscv-linux-tdep.c: Fix indentation. * riscv-ravenscar-thread.c: Fix indentation. * riscv-tdep.c: Fix indentation. * rl78-tdep.c: Fix indentation. * rs6000-aix-tdep.c: Fix indentation. * rs6000-lynx178-tdep.c: Fix indentation. * rs6000-nat.c: Fix indentation. * rs6000-tdep.c: Fix indentation. * rust-lang.c: Fix indentation. * rx-tdep.c: Fix indentation. * s12z-tdep.c: Fix indentation. * s390-linux-tdep.c: Fix indentation. * score-tdep.c: Fix indentation. * ser-base.c: Fix indentation. * ser-mingw.c: Fix indentation. * ser-uds.c: Fix indentation. * ser-unix.c: Fix indentation. * serial.c: Fix indentation. * sh-linux-tdep.c: Fix indentation. * sh-nbsd-tdep.c: Fix indentation. * sh-tdep.c: Fix indentation. * skip.c: Fix indentation. * sol-thread.c: Fix indentation. * solib-aix.c: Fix indentation. * solib-darwin.c: Fix indentation. * solib-frv.c: Fix indentation. * solib-svr4.c: Fix indentation. * solib.c: Fix indentation. * source.c: Fix indentation. * sparc-linux-tdep.c: Fix indentation. * sparc-nbsd-tdep.c: Fix indentation. * sparc-obsd-tdep.c: Fix indentation. * sparc-ravenscar-thread.c: Fix indentation. * sparc-tdep.c: Fix indentation. * sparc64-linux-tdep.c: Fix indentation. * sparc64-nbsd-tdep.c: Fix indentation. * sparc64-obsd-tdep.c: Fix indentation. * sparc64-tdep.c: Fix indentation. * stabsread.c: Fix indentation. * stack.c: Fix indentation. * stap-probe.c: Fix indentation. * stubs/ia64vms-stub.c: Fix indentation. * stubs/m32r-stub.c: Fix indentation. * stubs/m68k-stub.c: Fix indentation. * stubs/sh-stub.c: Fix indentation. * stubs/sparc-stub.c: Fix indentation. * symfile-mem.c: Fix indentation. * symfile.c: Fix indentation. * symfile.h: Fix indentation. * symmisc.c: Fix indentation. * symtab.c: Fix indentation. * symtab.h: Fix indentation. * target-float.c: Fix indentation. * target.c: Fix indentation. * target.h: Fix indentation. * tic6x-tdep.c: Fix indentation. * tilegx-linux-tdep.c: Fix indentation. * tilegx-tdep.c: Fix indentation. * top.c: Fix indentation. * tracefile-tfile.c: Fix indentation. * tracepoint.c: Fix indentation. * tui/tui-disasm.c: Fix indentation. * tui/tui-io.c: Fix indentation. * tui/tui-regs.c: Fix indentation. * tui/tui-stack.c: Fix indentation. * tui/tui-win.c: Fix indentation. * tui/tui-winsource.c: Fix indentation. * tui/tui.c: Fix indentation. * typeprint.c: Fix indentation. * ui-out.h: Fix indentation. * unittests/copy_bitwise-selftests.c: Fix indentation. * unittests/memory-map-selftests.c: Fix indentation. * utils.c: Fix indentation. * v850-tdep.c: Fix indentation. * valarith.c: Fix indentation. * valops.c: Fix indentation. * valprint.c: Fix indentation. * valprint.h: Fix indentation. * value.c: Fix indentation. * value.h: Fix indentation. * varobj.c: Fix indentation. * vax-tdep.c: Fix indentation. * windows-nat.c: Fix indentation. * windows-tdep.c: Fix indentation. * xcoffread.c: Fix indentation. * xml-syscall.c: Fix indentation. * xml-tdesc.c: Fix indentation. * xstormy16-tdep.c: Fix indentation. * xtensa-config.c: Fix indentation. * xtensa-linux-nat.c: Fix indentation. * xtensa-linux-tdep.c: Fix indentation. * xtensa-tdep.c: Fix indentation. gdbserver/ChangeLog: * ax.cc: Fix indentation. * dll.cc: Fix indentation. * inferiors.h: Fix indentation. * linux-low.cc: Fix indentation. * linux-nios2-low.cc: Fix indentation. * linux-ppc-ipa.cc: Fix indentation. * linux-ppc-low.cc: Fix indentation. * linux-x86-low.cc: Fix indentation. * linux-xtensa-low.cc: Fix indentation. * regcache.cc: Fix indentation. * server.cc: Fix indentation. * tracepoint.cc: Fix indentation. gdbsupport/ChangeLog: * common-exceptions.h: Fix indentation. * event-loop.cc: Fix indentation. * fileio.cc: Fix indentation. * filestuff.cc: Fix indentation. * gdb-dlfcn.cc: Fix indentation. * gdb_string_view.h: Fix indentation. * job-control.cc: Fix indentation. * signals.cc: Fix indentation. Change-Id: I4bad7ae6be0fbe14168b8ebafb98ffe14964a695
614 lines
18 KiB
C
614 lines
18 KiB
C
/* Python interface to register, and register group information.
|
|
|
|
Copyright (C) 2020 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 "gdbarch.h"
|
|
#include "arch-utils.h"
|
|
#include "disasm.h"
|
|
#include "reggroups.h"
|
|
#include "python-internal.h"
|
|
#include "user-regs.h"
|
|
#include <unordered_map>
|
|
|
|
/* Token to access per-gdbarch data related to register descriptors. */
|
|
static struct gdbarch_data *gdbpy_register_object_data = NULL;
|
|
|
|
/* Structure for iterator over register descriptors. */
|
|
typedef struct {
|
|
PyObject_HEAD
|
|
|
|
/* The register group that the user is iterating over. This will never
|
|
be NULL. */
|
|
struct reggroup *reggroup;
|
|
|
|
/* The next register number to lookup. Starts at 0 and counts up. */
|
|
int regnum;
|
|
|
|
/* Pointer back to the architecture we're finding registers for. */
|
|
struct gdbarch *gdbarch;
|
|
} register_descriptor_iterator_object;
|
|
|
|
extern PyTypeObject register_descriptor_iterator_object_type
|
|
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("register_descriptor_iterator_object");
|
|
|
|
/* A register descriptor. */
|
|
typedef struct {
|
|
PyObject_HEAD
|
|
|
|
/* The register this is a descriptor for. */
|
|
int regnum;
|
|
|
|
/* The architecture this is a register for. */
|
|
struct gdbarch *gdbarch;
|
|
} register_descriptor_object;
|
|
|
|
extern PyTypeObject register_descriptor_object_type
|
|
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("register_descriptor_object");
|
|
|
|
/* Structure for iterator over register groups. */
|
|
typedef struct {
|
|
PyObject_HEAD
|
|
|
|
/* The last register group returned. Initially this will be NULL. */
|
|
struct reggroup *reggroup;
|
|
|
|
/* Pointer back to the architecture we're finding registers for. */
|
|
struct gdbarch *gdbarch;
|
|
} reggroup_iterator_object;
|
|
|
|
extern PyTypeObject reggroup_iterator_object_type
|
|
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("reggroup_iterator_object");
|
|
|
|
/* A register group object. */
|
|
typedef struct {
|
|
PyObject_HEAD
|
|
|
|
/* The register group being described. */
|
|
struct reggroup *reggroup;
|
|
} reggroup_object;
|
|
|
|
extern PyTypeObject reggroup_object_type
|
|
CPYCHECKER_TYPE_OBJECT_FOR_TYPEDEF ("reggroup_object");
|
|
|
|
/* Associates a vector of gdb.RegisterDescriptor objects with GDBARCH as
|
|
gdbarch_data via the gdbarch post init registration mechanism
|
|
(gdbarch_data_register_post_init). */
|
|
|
|
static void *
|
|
gdbpy_register_object_data_init (struct gdbarch *gdbarch)
|
|
{
|
|
return new std::vector<gdbpy_ref<>>;
|
|
}
|
|
|
|
/* Return a gdb.RegisterGroup object wrapping REGGROUP. The register
|
|
group objects are cached, and the same Python object will always be
|
|
returned for the same REGGROUP pointer. */
|
|
|
|
static gdbpy_ref<>
|
|
gdbpy_get_reggroup (struct reggroup *reggroup)
|
|
{
|
|
/* Map from GDB's internal reggroup objects to the Python representation.
|
|
GDB's reggroups are global, and are never deleted, so using a map like
|
|
this is safe. */
|
|
static std::unordered_map<struct reggroup *,gdbpy_ref<>>
|
|
gdbpy_reggroup_object_map;
|
|
|
|
/* If there is not already a suitable Python object in the map then
|
|
create a new one, and add it to the map. */
|
|
if (gdbpy_reggroup_object_map[reggroup] == nullptr)
|
|
{
|
|
/* Create a new object and fill in its details. */
|
|
gdbpy_ref<reggroup_object> group
|
|
(PyObject_New (reggroup_object, ®group_object_type));
|
|
if (group == NULL)
|
|
return NULL;
|
|
group->reggroup = reggroup;
|
|
gdbpy_reggroup_object_map[reggroup]
|
|
= gdbpy_ref<> ((PyObject *) group.release ());
|
|
}
|
|
|
|
/* Fetch the Python object wrapping REGGROUP from the map, increasing
|
|
the reference count is handled by the gdbpy_ref class. */
|
|
return gdbpy_reggroup_object_map[reggroup];
|
|
}
|
|
|
|
/* Convert a gdb.RegisterGroup to a string, it just returns the name of
|
|
the register group. */
|
|
|
|
static PyObject *
|
|
gdbpy_reggroup_to_string (PyObject *self)
|
|
{
|
|
reggroup_object *group = (reggroup_object *) self;
|
|
struct reggroup *reggroup = group->reggroup;
|
|
|
|
const char *name = reggroup_name (reggroup);
|
|
return PyString_FromString (name);
|
|
}
|
|
|
|
/* Implement gdb.RegisterGroup.name (self) -> String.
|
|
Return a string that is the name of this register group. */
|
|
|
|
static PyObject *
|
|
gdbpy_reggroup_name (PyObject *self, void *closure)
|
|
{
|
|
return gdbpy_reggroup_to_string (self);
|
|
}
|
|
|
|
/* Return a gdb.RegisterDescriptor object for REGNUM from GDBARCH. For
|
|
each REGNUM (in GDBARCH) only one descriptor is ever created, which is
|
|
then cached on the GDBARCH. */
|
|
|
|
static gdbpy_ref<>
|
|
gdbpy_get_register_descriptor (struct gdbarch *gdbarch,
|
|
int regnum)
|
|
{
|
|
auto &vec
|
|
= *(std::vector<gdbpy_ref<>> *) gdbarch_data (gdbarch,
|
|
gdbpy_register_object_data);
|
|
|
|
/* Ensure that we have enough entries in the vector. */
|
|
if (vec.size () <= regnum)
|
|
vec.resize ((regnum + 1), nullptr);
|
|
|
|
/* If we don't already have a descriptor for REGNUM in GDBARCH then
|
|
create one now. */
|
|
if (vec[regnum] == nullptr)
|
|
{
|
|
gdbpy_ref <register_descriptor_object> reg
|
|
(PyObject_New (register_descriptor_object,
|
|
®ister_descriptor_object_type));
|
|
if (reg == NULL)
|
|
return NULL;
|
|
reg->regnum = regnum;
|
|
reg->gdbarch = gdbarch;
|
|
vec[regnum] = gdbpy_ref<> ((PyObject *) reg.release ());
|
|
}
|
|
|
|
/* Grab the register descriptor from the vector, the reference count is
|
|
automatically incremented thanks to gdbpy_ref. */
|
|
return vec[regnum];
|
|
}
|
|
|
|
/* Convert the register descriptor to a string. */
|
|
|
|
static PyObject *
|
|
gdbpy_register_descriptor_to_string (PyObject *self)
|
|
{
|
|
register_descriptor_object *reg
|
|
= (register_descriptor_object *) self;
|
|
struct gdbarch *gdbarch = reg->gdbarch;
|
|
int regnum = reg->regnum;
|
|
|
|
const char *name = gdbarch_register_name (gdbarch, regnum);
|
|
return PyString_FromString (name);
|
|
}
|
|
|
|
/* Implement gdb.RegisterDescriptor.name attribute get function. Return a
|
|
string that is the name of this register. Due to checking when register
|
|
descriptors are created the name will never by the empty string. */
|
|
|
|
static PyObject *
|
|
gdbpy_register_descriptor_name (PyObject *self, void *closure)
|
|
{
|
|
return gdbpy_register_descriptor_to_string (self);
|
|
}
|
|
|
|
/* Return a reference to the gdb.RegisterGroupsIterator object. */
|
|
|
|
static PyObject *
|
|
gdbpy_reggroup_iter (PyObject *self)
|
|
{
|
|
Py_INCREF (self);
|
|
return self;
|
|
}
|
|
|
|
/* Return the next gdb.RegisterGroup object from the iterator. */
|
|
|
|
static PyObject *
|
|
gdbpy_reggroup_iter_next (PyObject *self)
|
|
{
|
|
reggroup_iterator_object *iter_obj
|
|
= (reggroup_iterator_object *) self;
|
|
struct gdbarch *gdbarch = iter_obj->gdbarch;
|
|
|
|
struct reggroup *next_group = reggroup_next (gdbarch, iter_obj->reggroup);
|
|
if (next_group == NULL)
|
|
{
|
|
PyErr_SetString (PyExc_StopIteration, _("No more groups"));
|
|
return NULL;
|
|
}
|
|
|
|
iter_obj->reggroup = next_group;
|
|
return gdbpy_get_reggroup (iter_obj->reggroup).release ();
|
|
}
|
|
|
|
/* Return a new gdb.RegisterGroupsIterator over all the register groups in
|
|
GDBARCH. */
|
|
|
|
PyObject *
|
|
gdbpy_new_reggroup_iterator (struct gdbarch *gdbarch)
|
|
{
|
|
gdb_assert (gdbarch != nullptr);
|
|
|
|
/* Create a new object and fill in its internal state. */
|
|
reggroup_iterator_object *iter
|
|
= PyObject_New (reggroup_iterator_object,
|
|
®group_iterator_object_type);
|
|
if (iter == NULL)
|
|
return NULL;
|
|
iter->reggroup = NULL;
|
|
iter->gdbarch = gdbarch;
|
|
return (PyObject *) iter;
|
|
}
|
|
|
|
/* Create and return a new gdb.RegisterDescriptorIterator object which
|
|
will iterate over all registers in GROUP_NAME for GDBARCH. If
|
|
GROUP_NAME is either NULL or the empty string then the ALL_REGGROUP is
|
|
used, otherwise lookup the register group matching GROUP_NAME and use
|
|
that.
|
|
|
|
This function can return NULL if GROUP_NAME isn't found. */
|
|
|
|
PyObject *
|
|
gdbpy_new_register_descriptor_iterator (struct gdbarch *gdbarch,
|
|
const char *group_name)
|
|
{
|
|
struct reggroup *grp = NULL;
|
|
|
|
/* Lookup the requested register group, or find the default. */
|
|
if (group_name == NULL || *group_name == '\0')
|
|
grp = all_reggroup;
|
|
else
|
|
{
|
|
grp = reggroup_find (gdbarch, group_name);
|
|
if (grp == NULL)
|
|
{
|
|
PyErr_SetString (PyExc_ValueError,
|
|
_("Unknown register group name."));
|
|
return NULL;
|
|
}
|
|
}
|
|
/* Create a new iterator object initialised for this architecture and
|
|
fill in all of the details. */
|
|
register_descriptor_iterator_object *iter
|
|
= PyObject_New (register_descriptor_iterator_object,
|
|
®ister_descriptor_iterator_object_type);
|
|
if (iter == NULL)
|
|
return NULL;
|
|
iter->regnum = 0;
|
|
iter->gdbarch = gdbarch;
|
|
gdb_assert (grp != NULL);
|
|
iter->reggroup = grp;
|
|
|
|
return (PyObject *) iter;
|
|
}
|
|
|
|
/* Return a reference to the gdb.RegisterDescriptorIterator object. */
|
|
|
|
static PyObject *
|
|
gdbpy_register_descriptor_iter (PyObject *self)
|
|
{
|
|
Py_INCREF (self);
|
|
return self;
|
|
}
|
|
|
|
/* Return the next register name. */
|
|
|
|
static PyObject *
|
|
gdbpy_register_descriptor_iter_next (PyObject *self)
|
|
{
|
|
register_descriptor_iterator_object *iter_obj
|
|
= (register_descriptor_iterator_object *) self;
|
|
struct gdbarch *gdbarch = iter_obj->gdbarch;
|
|
|
|
do
|
|
{
|
|
if (iter_obj->regnum >= gdbarch_num_cooked_regs (gdbarch))
|
|
{
|
|
PyErr_SetString (PyExc_StopIteration, _("No more registers"));
|
|
return NULL;
|
|
}
|
|
|
|
const char *name = nullptr;
|
|
int regnum = iter_obj->regnum;
|
|
if (gdbarch_register_reggroup_p (gdbarch, regnum,
|
|
iter_obj->reggroup))
|
|
name = gdbarch_register_name (gdbarch, regnum);
|
|
iter_obj->regnum++;
|
|
|
|
if (name != nullptr && *name != '\0')
|
|
return gdbpy_get_register_descriptor (gdbarch, regnum).release ();
|
|
}
|
|
while (true);
|
|
}
|
|
|
|
/* Implement:
|
|
|
|
gdb.RegisterDescriptorIterator.find (self, name) -> gdb.RegisterDescriptor
|
|
|
|
Look up a descriptor for register with NAME. If no matching register is
|
|
found then return None. */
|
|
|
|
static PyObject *
|
|
register_descriptor_iter_find (PyObject *self, PyObject *args, PyObject *kw)
|
|
{
|
|
static const char *keywords[] = { "name", NULL };
|
|
const char *register_name = NULL;
|
|
|
|
register_descriptor_iterator_object *iter_obj
|
|
= (register_descriptor_iterator_object *) self;
|
|
struct gdbarch *gdbarch = iter_obj->gdbarch;
|
|
|
|
if (!gdb_PyArg_ParseTupleAndKeywords (args, kw, "s", keywords,
|
|
®ister_name))
|
|
return NULL;
|
|
|
|
if (register_name != NULL && *register_name != '\0')
|
|
{
|
|
int regnum = user_reg_map_name_to_regnum (gdbarch, register_name,
|
|
strlen (register_name));
|
|
if (regnum >= 0)
|
|
return gdbpy_get_register_descriptor (gdbarch, regnum).release ();
|
|
}
|
|
|
|
Py_RETURN_NONE;
|
|
}
|
|
|
|
/* See python-internal.h. */
|
|
|
|
bool
|
|
gdbpy_parse_register_id (struct gdbarch *gdbarch, PyObject *pyo_reg_id,
|
|
int *reg_num)
|
|
{
|
|
gdb_assert (pyo_reg_id != NULL);
|
|
|
|
/* The register could be a string, its name. */
|
|
if (gdbpy_is_string (pyo_reg_id))
|
|
{
|
|
gdb::unique_xmalloc_ptr<char> reg_name (gdbpy_obj_to_string (pyo_reg_id));
|
|
|
|
if (reg_name != NULL)
|
|
{
|
|
*reg_num = user_reg_map_name_to_regnum (gdbarch, reg_name.get (),
|
|
strlen (reg_name.get ()));
|
|
return *reg_num >= 0;
|
|
}
|
|
}
|
|
/* The register could be its internal GDB register number. */
|
|
else if (PyInt_Check (pyo_reg_id))
|
|
{
|
|
long value;
|
|
if (gdb_py_int_as_long (pyo_reg_id, &value) && (int) value == value)
|
|
{
|
|
if (user_reg_map_regnum_to_name (gdbarch, value) != NULL)
|
|
{
|
|
*reg_num = (int) value;
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
/* The register could be a gdb.RegisterDescriptor object. */
|
|
else if (PyObject_IsInstance (pyo_reg_id,
|
|
(PyObject *) ®ister_descriptor_object_type))
|
|
{
|
|
register_descriptor_object *reg
|
|
= (register_descriptor_object *) pyo_reg_id;
|
|
if (reg->gdbarch == gdbarch)
|
|
{
|
|
*reg_num = reg->regnum;
|
|
return true;
|
|
}
|
|
else
|
|
PyErr_SetString (PyExc_ValueError,
|
|
_("Invalid Architecture in RegisterDescriptor"));
|
|
}
|
|
|
|
gdb_assert (PyErr_Occurred ());
|
|
return false;
|
|
}
|
|
|
|
/* Initializes the new Python classes from this file in the gdb module. */
|
|
|
|
int
|
|
gdbpy_initialize_registers ()
|
|
{
|
|
gdbpy_register_object_data
|
|
= gdbarch_data_register_post_init (gdbpy_register_object_data_init);
|
|
|
|
register_descriptor_object_type.tp_new = PyType_GenericNew;
|
|
if (PyType_Ready (®ister_descriptor_object_type) < 0)
|
|
return -1;
|
|
if (gdb_pymodule_addobject
|
|
(gdb_module, "RegisterDescriptor",
|
|
(PyObject *) ®ister_descriptor_object_type) < 0)
|
|
return -1;
|
|
|
|
reggroup_iterator_object_type.tp_new = PyType_GenericNew;
|
|
if (PyType_Ready (®group_iterator_object_type) < 0)
|
|
return -1;
|
|
if (gdb_pymodule_addobject
|
|
(gdb_module, "RegisterGroupsIterator",
|
|
(PyObject *) ®group_iterator_object_type) < 0)
|
|
return -1;
|
|
|
|
reggroup_object_type.tp_new = PyType_GenericNew;
|
|
if (PyType_Ready (®group_object_type) < 0)
|
|
return -1;
|
|
if (gdb_pymodule_addobject
|
|
(gdb_module, "RegisterGroup",
|
|
(PyObject *) ®group_object_type) < 0)
|
|
return -1;
|
|
|
|
register_descriptor_iterator_object_type.tp_new = PyType_GenericNew;
|
|
if (PyType_Ready (®ister_descriptor_iterator_object_type) < 0)
|
|
return -1;
|
|
return (gdb_pymodule_addobject
|
|
(gdb_module, "RegisterDescriptorIterator",
|
|
(PyObject *) ®ister_descriptor_iterator_object_type));
|
|
}
|
|
|
|
static PyMethodDef register_descriptor_iterator_object_methods [] = {
|
|
{ "find", (PyCFunction) register_descriptor_iter_find,
|
|
METH_VARARGS | METH_KEYWORDS,
|
|
"registers (name) -> gdb.RegisterDescriptor.\n\
|
|
Return a register descriptor for the register NAME, or None if no register\n\
|
|
with that name exists in this iterator." },
|
|
{NULL} /* Sentinel */
|
|
};
|
|
|
|
PyTypeObject register_descriptor_iterator_object_type = {
|
|
PyVarObject_HEAD_INIT (NULL, 0)
|
|
"gdb.RegisterDescriptorIterator", /*tp_name*/
|
|
sizeof (register_descriptor_iterator_object), /*tp_basicsize*/
|
|
0, /*tp_itemsize*/
|
|
0, /*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_HAVE_ITER, /*tp_flags*/
|
|
"GDB architecture register descriptor iterator object", /*tp_doc */
|
|
0, /*tp_traverse */
|
|
0, /*tp_clear */
|
|
0, /*tp_richcompare */
|
|
0, /*tp_weaklistoffset */
|
|
gdbpy_register_descriptor_iter, /*tp_iter */
|
|
gdbpy_register_descriptor_iter_next, /*tp_iternext */
|
|
register_descriptor_iterator_object_methods /*tp_methods */
|
|
};
|
|
|
|
static gdb_PyGetSetDef gdbpy_register_descriptor_getset[] = {
|
|
{ "name", gdbpy_register_descriptor_name, NULL,
|
|
"The name of this register.", NULL },
|
|
{ NULL } /* Sentinel */
|
|
};
|
|
|
|
PyTypeObject register_descriptor_object_type = {
|
|
PyVarObject_HEAD_INIT (NULL, 0)
|
|
"gdb.RegisterDescriptor", /*tp_name*/
|
|
sizeof (register_descriptor_object), /*tp_basicsize*/
|
|
0, /*tp_itemsize*/
|
|
0, /*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*/
|
|
gdbpy_register_descriptor_to_string, /*tp_str*/
|
|
0, /*tp_getattro*/
|
|
0, /*tp_setattro*/
|
|
0, /*tp_as_buffer*/
|
|
Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
|
"GDB architecture register descriptor 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 */
|
|
gdbpy_register_descriptor_getset /*tp_getset */
|
|
};
|
|
|
|
PyTypeObject reggroup_iterator_object_type = {
|
|
PyVarObject_HEAD_INIT (NULL, 0)
|
|
"gdb.RegisterGroupsIterator", /*tp_name*/
|
|
sizeof (reggroup_iterator_object), /*tp_basicsize*/
|
|
0, /*tp_itemsize*/
|
|
0, /*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_HAVE_ITER, /*tp_flags*/
|
|
"GDB register groups iterator object", /*tp_doc */
|
|
0, /*tp_traverse */
|
|
0, /*tp_clear */
|
|
0, /*tp_richcompare */
|
|
0, /*tp_weaklistoffset */
|
|
gdbpy_reggroup_iter, /*tp_iter */
|
|
gdbpy_reggroup_iter_next, /*tp_iternext */
|
|
0 /*tp_methods */
|
|
};
|
|
|
|
static gdb_PyGetSetDef gdbpy_reggroup_getset[] = {
|
|
{ "name", gdbpy_reggroup_name, NULL,
|
|
"The name of this register group.", NULL },
|
|
{ NULL } /* Sentinel */
|
|
};
|
|
|
|
PyTypeObject reggroup_object_type = {
|
|
PyVarObject_HEAD_INIT (NULL, 0)
|
|
"gdb.RegisterGroup", /*tp_name*/
|
|
sizeof (reggroup_object), /*tp_basicsize*/
|
|
0, /*tp_itemsize*/
|
|
0, /*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*/
|
|
gdbpy_reggroup_to_string, /*tp_str*/
|
|
0, /*tp_getattro*/
|
|
0, /*tp_setattro*/
|
|
0, /*tp_as_buffer*/
|
|
Py_TPFLAGS_DEFAULT, /*tp_flags*/
|
|
"GDB register group 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 */
|
|
gdbpy_reggroup_getset /*tp_getset */
|
|
};
|