From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2126) id 0A56B384BC02; Tue, 14 Jun 2022 15:13:17 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 0A56B384BC02 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable From: Tom Tromey To: gdb-cvs@sourceware.org Subject: [binutils-gdb] Reimplement ravenscar registers using tables X-Act-Checkin: binutils-gdb X-Git-Author: Tom Tromey X-Git-Refname: refs/heads/master X-Git-Oldrev: 2808125fbb5f9c55f52e863283b7f1c5f0ef1a65 X-Git-Newrev: e73434e38f55e21cc33457ce3b218fa7b4592fec Message-Id: <20220614151317.0A56B384BC02@sourceware.org> Date: Tue, 14 Jun 2022 15:13:17 +0000 (GMT) X-BeenThere: gdb-cvs@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-cvs mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 14 Jun 2022 15:13:17 -0000 https://sourceware.org/git/gitweb.cgi?p=3Dbinutils-gdb.git;h=3De73434e38f55= e21cc33457ce3b218fa7b4592fec commit e73434e38f55e21cc33457ce3b218fa7b4592fec Author: Tom Tromey Date: Tue May 3 08:18:14 2022 -0600 Reimplement ravenscar registers using tables =20 Currently, the ravenscar-thread implementation for each architecture is written by hand. However, these are actually written by copy-paste. It seems better to switch to a table-driven approach. =20 The previous code also fetched all registers whenever any register was requested. This is corrected in the new implementation. Diff: --- gdb/aarch64-ravenscar-thread.c | 121 +------------------------------- gdb/amd64-ravenscar-thread.c | 112 +++++------------------------- gdb/ppc-ravenscar-thread.c | 154 +------------------------------------= ---- gdb/ravenscar-thread.c | 113 +++++++++++++++++++++++++++++- gdb/ravenscar-thread.h | 42 ++++++++++- gdb/riscv-ravenscar-thread.c | 120 ++++++++------------------------ gdb/sparc-ravenscar-thread.c | 124 +-------------------------------- 7 files changed, 206 insertions(+), 580 deletions(-) diff --git a/gdb/aarch64-ravenscar-thread.c b/gdb/aarch64-ravenscar-thread.c index dc35537e3d5..045d022fc23 100644 --- a/gdb/aarch64-ravenscar-thread.c +++ b/gdb/aarch64-ravenscar-thread.c @@ -61,127 +61,10 @@ static const int aarch64_context_offsets[] =3D 112, 116, }; =20 -/* The register layout info. */ - -struct ravenscar_reg_info -{ - /* A table providing the offset relative to the context structure - where each register is saved. */ - const int *context_offsets; - - /* The number of elements in the context_offsets table above. */ - int context_offsets_size; -}; - -/* supply register REGNUM, which has been saved on REGISTER_ADDR, to the - regcache. */ - -static void -supply_register_at_address (struct regcache *regcache, int regnum, - CORE_ADDR register_addr) -{ - struct gdbarch *gdbarch =3D regcache->arch (); - int buf_size =3D register_size (gdbarch, regnum); - gdb_byte *buf; - - buf =3D (gdb_byte *) alloca (buf_size); - read_memory (register_addr, buf, buf_size); - regcache->raw_supply (regnum, buf); -} - -/* Return true if, for a non-running thread, REGNUM has been saved on the - Thread_Descriptor. */ - -static int -register_in_thread_descriptor_p (const struct ravenscar_reg_info *reg_info, - int regnum) -{ - /* Check FPU registers */ - return (regnum < reg_info->context_offsets_size - && reg_info->context_offsets[regnum] !=3D NO_OFFSET); -} - -/* to_fetch_registers when inferior_ptid is different from the running - thread. */ - -static void -aarch64_ravenscar_generic_fetch_registers - (const struct ravenscar_reg_info *reg_info, - struct regcache *regcache, int regnum) -{ - struct gdbarch *gdbarch =3D regcache->arch (); - const int num_regs =3D gdbarch_num_regs (gdbarch); - int current_regnum; - CORE_ADDR current_address; - CORE_ADDR thread_descriptor_address; - - /* The tid is the thread_id field, which is a pointer to the thread. */ - thread_descriptor_address =3D (CORE_ADDR) inferior_ptid.tid (); - - /* Read registers. */ - for (current_regnum =3D 0; current_regnum < num_regs; current_regnum++) - { - if (register_in_thread_descriptor_p (reg_info, current_regnum)) - { - current_address =3D thread_descriptor_address - + reg_info->context_offsets[current_regnum]; - supply_register_at_address (regcache, current_regnum, - current_address); - } - } -} - -/* to_store_registers when inferior_ptid is different from the running - thread. */ - -static void -aarch64_ravenscar_generic_store_registers - (const struct ravenscar_reg_info *reg_info, - struct regcache *regcache, int regnum) -{ - struct gdbarch *gdbarch =3D regcache->arch (); - int buf_size =3D register_size (gdbarch, regnum); - gdb_byte buf[buf_size]; - ULONGEST register_address; - - if (register_in_thread_descriptor_p (reg_info, regnum)) - register_address - =3D inferior_ptid.tid () + reg_info->context_offsets [regnum]; - else - return; - - regcache->raw_collect (regnum, buf); - write_memory (register_address, - buf, - buf_size); -} - -/* The ravenscar_reg_info for most Aarch64 targets. */ - -static const struct ravenscar_reg_info aarch64_reg_info =3D -{ - aarch64_context_offsets, - ARRAY_SIZE (aarch64_context_offsets), -}; - -struct aarch64_ravenscar_ops : public ravenscar_arch_ops -{ - void fetch_registers (struct regcache *regcache, int regnum) override - { - aarch64_ravenscar_generic_fetch_registers - (&aarch64_reg_info, regcache, regnum); - } - - void store_registers (struct regcache *regcache, int regnum) override - { - aarch64_ravenscar_generic_store_registers - (&aarch64_reg_info, regcache, regnum); - } -}; - /* The ravenscar_arch_ops vector for most Aarch64 targets. */ =20 -static struct aarch64_ravenscar_ops aarch64_ravenscar_ops; +static struct ravenscar_arch_ops aarch64_ravenscar_ops + (aarch64_context_offsets); =20 /* Register aarch64_ravenscar_ops in GDBARCH. */ =20 diff --git a/gdb/amd64-ravenscar-thread.c b/gdb/amd64-ravenscar-thread.c index d06cdf8b7a2..18c000dc988 100644 --- a/gdb/amd64-ravenscar-thread.c +++ b/gdb/amd64-ravenscar-thread.c @@ -26,17 +26,6 @@ #include "ravenscar-thread.h" #include "amd64-ravenscar-thread.h" =20 -struct amd64_ravenscar_ops : public ravenscar_arch_ops -{ - void fetch_registers (struct regcache *regcache, int regnum) override; - void store_registers (struct regcache *regcache, int regnum) override; - -private: - - /* Return the offset of the register in the context buffer. */ - int register_offset (struct gdbarch *arch, int regnum); -}; - /* x86-64 Ravenscar stores registers as: =20 type Context_Buffer is record @@ -54,92 +43,29 @@ private: */ static const int register_layout[] =3D { - AMD64_RIP_REGNUM, - AMD64_EFLAGS_REGNUM, - AMD64_RSP_REGNUM, - AMD64_RBX_REGNUM, - AMD64_RBP_REGNUM, - AMD64_R12_REGNUM, - AMD64_R13_REGNUM, - AMD64_R14_REGNUM, - AMD64_R15_REGNUM, + /* RAX */ -1, + /* RBX */ 3 * 8, + /* RCX */ -1, + /* RDX */ -1, + /* RSI */ -1, + /* RDI */ -1, + /* RBP */ 4 * 8, + /* RSP */ 2 * 8, + /* R8 */ -1, + /* R9 */ -1, + /* R10 */ -1, + /* R11 */ -1, + /* R12 */ 5 * 8, + /* R13 */ 6 * 8, + /* R14 */ 7 * 8, + /* R15 */ 8 * 8, + /* RIP */ 0 * 8, + /* EFLAGS */ 1 * 8, }; =20 -int -amd64_ravenscar_ops::register_offset (struct gdbarch *arch, int regnum) -{ - for (int i =3D 0; i < ARRAY_SIZE (register_layout); ++i) - if (register_layout[i] =3D=3D regnum) - return i * 8; - /* Not saved. */ - return -1; -} - -/* Supply register REGNUM, which has been saved at REGISTER_ADDR, to - the regcache. */ - -static void -supply_register_at_address (struct regcache *regcache, int regnum, - CORE_ADDR register_addr) -{ - struct gdbarch *gdbarch =3D regcache->arch (); - int buf_size =3D register_size (gdbarch, regnum); - gdb_byte *buf; - - buf =3D (gdb_byte *) alloca (buf_size); - read_memory (register_addr, buf, buf_size); - regcache->raw_supply (regnum, buf); -} - -void -amd64_ravenscar_ops::fetch_registers (struct regcache *regcache, int regnu= m) -{ - struct gdbarch *gdbarch =3D regcache->arch (); - const int num_regs =3D gdbarch_num_regs (gdbarch); - int current_regnum; - CORE_ADDR current_address; - CORE_ADDR thread_descriptor_address; - - /* The tid is the thread_id field, which is a pointer to the thread. */ - thread_descriptor_address =3D (CORE_ADDR) inferior_ptid.tid (); - - /* Read registers. */ - for (current_regnum =3D 0; current_regnum < num_regs; current_regnum++) - { - int offset =3D register_offset (gdbarch, current_regnum); - - if (offset !=3D -1) - { - current_address =3D thread_descriptor_address + offset; - supply_register_at_address (regcache, current_regnum, - current_address); - } - } -} - -void -amd64_ravenscar_ops::store_registers (struct regcache *regcache, int regnu= m) -{ - struct gdbarch *gdbarch =3D regcache->arch (); - int buf_size =3D register_size (gdbarch, regnum); - gdb_byte buf[buf_size]; - CORE_ADDR register_address; - - int offset =3D register_offset (gdbarch, regnum); - if (offset !=3D -1) - { - register_address =3D inferior_ptid.tid () + offset; - - regcache->raw_collect (regnum, buf); - write_memory (register_address, - buf, - buf_size); - } -} - /* The ravenscar_arch_ops vector for AMD64 targets. */ =20 -static struct amd64_ravenscar_ops amd64_ravenscar_ops; +static struct ravenscar_arch_ops amd64_ravenscar_ops (register_layout); =20 /* Register amd64_ravenscar_ops in GDBARCH. */ =20 diff --git a/gdb/ppc-ravenscar-thread.c b/gdb/ppc-ravenscar-thread.c index 42d7334b93f..0691a6317d5 100644 --- a/gdb/ppc-ravenscar-thread.c +++ b/gdb/ppc-ravenscar-thread.c @@ -100,129 +100,10 @@ static const int e500_context_offsets[] =3D NO_OFFSET, 176 }; =20 -/* The register layout info. */ - -struct ravenscar_reg_info -{ - /* A table providing the offset relative to the context structure - where each register is saved. */ - const int *context_offsets; - - /* The number of elements in the context_offsets table above. */ - int context_offsets_size; -}; - -/* supply register REGNUM, which has been saved on REGISTER_ADDR, to the - regcache. */ - -static void -supply_register_at_address (struct regcache *regcache, int regnum, - CORE_ADDR register_addr) -{ - struct gdbarch *gdbarch =3D regcache->arch (); - int buf_size =3D register_size (gdbarch, regnum); - gdb_byte *buf; - - buf =3D (gdb_byte *) alloca (buf_size); - read_memory (register_addr, buf, buf_size); - regcache->raw_supply (regnum, buf); -} - -/* Return true if, for a non-running thread, REGNUM has been saved on the - Thread_Descriptor. */ - -static int -register_in_thread_descriptor_p (const struct ravenscar_reg_info *reg_info, - int regnum) -{ - return (regnum < reg_info->context_offsets_size - && reg_info->context_offsets[regnum] !=3D NO_OFFSET); -} - -/* to_fetch_registers when inferior_ptid is different from the running - thread. */ - -static void -ppc_ravenscar_generic_fetch_registers - (const struct ravenscar_reg_info *reg_info, - struct regcache *regcache, int regnum) -{ - struct gdbarch *gdbarch =3D regcache->arch (); - const int num_regs =3D gdbarch_num_regs (gdbarch); - int current_regnum; - CORE_ADDR current_address; - CORE_ADDR thread_descriptor_address; - - /* The tid is the thread_id field, which is a pointer to the thread. */ - thread_descriptor_address =3D (CORE_ADDR) inferior_ptid.tid (); - - /* Read registers. */ - for (current_regnum =3D 0; current_regnum < num_regs; current_regnum++) - { - if (register_in_thread_descriptor_p (reg_info, current_regnum)) - { - current_address =3D thread_descriptor_address - + reg_info->context_offsets[current_regnum]; - supply_register_at_address (regcache, current_regnum, - current_address); - } - } -} - -/* to_store_registers when inferior_ptid is different from the running - thread. */ - -static void -ppc_ravenscar_generic_store_registers - (const struct ravenscar_reg_info *reg_info, - struct regcache *regcache, int regnum) -{ - struct gdbarch *gdbarch =3D regcache->arch (); - int buf_size =3D register_size (gdbarch, regnum); - gdb_byte buf[buf_size]; - ULONGEST register_address; - - if (register_in_thread_descriptor_p (reg_info, regnum)) - register_address - =3D inferior_ptid.tid () + reg_info->context_offsets [regnum]; - else - return; - - regcache->raw_collect (regnum, buf); - write_memory (register_address, - buf, - buf_size); -} - -/* The ravenscar_reg_info for most PowerPC targets. */ - -static const struct ravenscar_reg_info ppc_reg_info =3D -{ - powerpc_context_offsets, - ARRAY_SIZE (powerpc_context_offsets), -}; - -struct ppc_ravenscar_powerpc_ops : public ravenscar_arch_ops -{ - void fetch_registers (struct regcache *, int) override; - void store_registers (struct regcache *, int) override; -}; - -void -ppc_ravenscar_powerpc_ops::fetch_registers (struct regcache *regcache, int= regnum) -{ - ppc_ravenscar_generic_fetch_registers (&ppc_reg_info, regcache, regnum); -} - -void -ppc_ravenscar_powerpc_ops::store_registers (struct regcache *regcache, int= regnum) -{ - ppc_ravenscar_generic_store_registers (&ppc_reg_info, regcache, regnum); -} - /* The ravenscar_arch_ops vector for most PowerPC targets. */ =20 -static struct ppc_ravenscar_powerpc_ops ppc_ravenscar_powerpc_ops; +static struct ravenscar_arch_ops ppc_ravenscar_powerpc_ops + (powerpc_context_offsets); =20 /* Register ppc_ravenscar_powerpc_ops in GDBARCH. */ =20 @@ -232,38 +113,9 @@ register_ppc_ravenscar_ops (struct gdbarch *gdbarch) set_gdbarch_ravenscar_ops (gdbarch, &ppc_ravenscar_powerpc_ops); } =20 -/* The ravenscar_reg_info for E500 targets. */ - -static const struct ravenscar_reg_info e500_reg_info =3D -{ - e500_context_offsets, - ARRAY_SIZE (e500_context_offsets), -}; - -struct ppc_ravenscar_e500_ops : public ravenscar_arch_ops -{ - void fetch_registers (struct regcache *, int) override; - void store_registers (struct regcache *, int) override; -}; - -void -ppc_ravenscar_e500_ops::fetch_registers (struct regcache *regcache, int re= gnum) -{ - ppc_ravenscar_generic_fetch_registers (&e500_reg_info, regcache, regnum); -} - -/* Implement the to_store_registers ravenscar_arch_ops method - for E500 targets. */ - -void -ppc_ravenscar_e500_ops::store_registers (struct regcache *regcache, int re= gnum) -{ - ppc_ravenscar_generic_store_registers (&e500_reg_info, regcache, regnum); -} - /* The ravenscar_arch_ops vector for E500 targets. */ =20 -static struct ppc_ravenscar_e500_ops ppc_ravenscar_e500_ops; +static struct ravenscar_arch_ops ppc_ravenscar_e500_ops (e500_context_offs= ets); =20 /* Register ppc_ravenscar_e500_ops in GDBARCH. */ =20 diff --git a/gdb/ravenscar-thread.c b/gdb/ravenscar-thread.c index aae6e397327..e300095b53f 100644 --- a/gdb/ravenscar-thread.c +++ b/gdb/ravenscar-thread.c @@ -477,6 +477,116 @@ ravenscar_thread_target::pid_to_str (ptid_t ptid) phex_nz (ptid.tid (), sizeof (ULONGEST))); } =20 +CORE_ADDR +ravenscar_arch_ops::get_stack_base (struct regcache *regcache) const +{ + struct gdbarch *gdbarch =3D regcache->arch (); + const int sp_regnum =3D gdbarch_sp_regnum (gdbarch); + ULONGEST stack_address; + regcache_cooked_read_unsigned (regcache, sp_regnum, &stack_address); + return (CORE_ADDR) stack_address; +} + +void +ravenscar_arch_ops::supply_one_register (struct regcache *regcache, + int regnum, + CORE_ADDR descriptor, + CORE_ADDR stack_base) const +{ + CORE_ADDR addr; + if (regnum >=3D first_stack_register && regnum <=3D last_stack_register) + addr =3D stack_base; + else + addr =3D descriptor; + addr +=3D offsets[regnum]; + + struct gdbarch *gdbarch =3D regcache->arch (); + int size =3D register_size (gdbarch, regnum); + gdb_byte *buf =3D (gdb_byte *) alloca (size); + read_memory (addr, buf, size); + regcache->raw_supply (regnum, buf); +} + +void +ravenscar_arch_ops::fetch_registers (struct regcache *regcache, + int regnum) const +{ + struct gdbarch *gdbarch =3D regcache->arch (); + /* The tid is the thread_id field, which is a pointer to the thread. */ + CORE_ADDR thread_descriptor_address + =3D (CORE_ADDR) regcache->ptid ().tid (); + + int sp_regno =3D -1; + CORE_ADDR stack_address =3D 0; + if (regnum =3D=3D -1 + || (regnum >=3D first_stack_register && regnum <=3D last_stack_regis= ter)) + { + /* We must supply SP for get_stack_base, so recurse. */ + sp_regno =3D gdbarch_sp_regnum (gdbarch); + gdb_assert (!(sp_regno >=3D first_stack_register + && sp_regno <=3D last_stack_register)); + fetch_registers (regcache, sp_regno); + stack_address =3D get_stack_base (regcache); + } + + if (regnum =3D=3D -1) + { + /* Fetch all registers. */ + for (int reg =3D 0; reg < offsets.size (); ++reg) + if (reg !=3D sp_regno && offsets[reg] !=3D -1) + supply_one_register (regcache, reg, thread_descriptor_address, + stack_address); + } + else if (regnum < offsets.size () && offsets[regnum] !=3D -1) + supply_one_register (regcache, regnum, thread_descriptor_address, + stack_address); +} + +void +ravenscar_arch_ops::store_one_register (struct regcache *regcache, int reg= num, + CORE_ADDR descriptor, + CORE_ADDR stack_base) const +{ + CORE_ADDR addr; + if (regnum >=3D first_stack_register && regnum <=3D last_stack_register) + addr =3D stack_base; + else + addr =3D descriptor; + addr +=3D offsets[regnum]; + + struct gdbarch *gdbarch =3D regcache->arch (); + int size =3D register_size (gdbarch, regnum); + gdb_byte *buf =3D (gdb_byte *) alloca (size); + regcache->raw_collect (regnum, buf); + write_memory (addr, buf, size); +} + +void +ravenscar_arch_ops::store_registers (struct regcache *regcache, + int regnum) const +{ + /* The tid is the thread_id field, which is a pointer to the thread. */ + CORE_ADDR thread_descriptor_address + =3D (CORE_ADDR) regcache->ptid ().tid (); + + CORE_ADDR stack_address =3D 0; + if (regnum =3D=3D -1 + || (regnum >=3D first_stack_register && regnum <=3D last_stack_regis= ter)) + stack_address =3D get_stack_base (regcache); + + if (regnum =3D=3D -1) + { + /* Store all registers. */ + for (int reg =3D 0; reg < offsets.size (); ++reg) + if (offsets[reg] !=3D -1) + store_one_register (regcache, reg, thread_descriptor_address, + stack_address); + } + else if (regnum < offsets.size () && offsets[regnum] !=3D -1) + store_one_register (regcache, regnum, thread_descriptor_address, + stack_address); +} + /* Temporarily set the ptid of a regcache to some other value. When this object is destroyed, the regcache's original ptid is restored. */ @@ -506,7 +616,8 @@ private: }; =20 void -ravenscar_thread_target::fetch_registers (struct regcache *regcache, int r= egnum) +ravenscar_thread_target::fetch_registers (struct regcache *regcache, + int regnum) { ptid_t ptid =3D regcache->ptid (); =20 diff --git a/gdb/ravenscar-thread.h b/gdb/ravenscar-thread.h index df750667ab9..5d5661f48df 100644 --- a/gdb/ravenscar-thread.h +++ b/gdb/ravenscar-thread.h @@ -24,12 +24,48 @@ =20 struct ravenscar_arch_ops { - virtual ~ravenscar_arch_ops () + ravenscar_arch_ops (gdb::array_view offsets_, + int first_stack =3D -1, + int last_stack =3D -1) + : offsets (offsets_), + first_stack_register (first_stack), + last_stack_register (last_stack) { + /* These must either both be -1 or both be valid. */ + gdb_assert ((first_stack_register =3D=3D -1) =3D=3D (last_stack_regist= er =3D=3D -1)); + /* They must also be ordered. */ + gdb_assert (last_stack_register >=3D first_stack_register); } =20 - virtual void fetch_registers (struct regcache *, int) =3D 0; - virtual void store_registers (struct regcache *, int) =3D 0; + void fetch_registers (struct regcache *, int) const; + void store_registers (struct regcache *, int) const; + +private: + + /* An array where the indices are register numbers and the contents + are offsets. The offsets are either in the thread descriptor or + the stack, depending on the other fields. An offset of -1 means + that the corresponding register is not stored. */ + const gdb::array_view offsets; + + /* If these are -1, then all registers for this architecture are + stored in the thread descriptor. Otherwise, these mark a range + of registers that are stored on the stack. */ + const int first_stack_register; + const int last_stack_register; + + /* Helper function to supply one register. */ + void supply_one_register (struct regcache *regcache, int regnum, + CORE_ADDR descriptor, + CORE_ADDR stack_base) const; + /* Helper function to store one register. */ + void store_one_register (struct regcache *regcache, int regnum, + CORE_ADDR descriptor, + CORE_ADDR stack_base) const; + /* Helper function to find stack address where registers are stored. + This must be called with the stack pointer already supplied in + the register cache. */ + CORE_ADDR get_stack_base (struct regcache *) const; }; =20 #endif /* !defined (RAVENSCAR_THREAD_H) */ diff --git a/gdb/riscv-ravenscar-thread.c b/gdb/riscv-ravenscar-thread.c index b2a7b6e0096..e28e17878c3 100644 --- a/gdb/riscv-ravenscar-thread.c +++ b/gdb/riscv-ravenscar-thread.c @@ -26,115 +26,51 @@ #include "ravenscar-thread.h" #include "riscv-ravenscar-thread.h" =20 +#define LAST_REGISTER (RISCV_FIRST_FP_REGNUM + 14) + struct riscv_ravenscar_ops : public ravenscar_arch_ops { - void fetch_registers (struct regcache *regcache, int regnum) override; - void store_registers (struct regcache *regcache, int regnum) override; - -private: + int reg_offsets[LAST_REGISTER + 1]; =20 - /* Return the offset of the register in the context buffer. */ - int register_offset (struct gdbarch *arch, int regnum); + riscv_ravenscar_ops (struct gdbarch *arch); }; =20 -int -riscv_ravenscar_ops::register_offset (struct gdbarch *arch, int regnum) -{ - int offset; - if (regnum =3D=3D RISCV_RA_REGNUM || regnum =3D=3D RISCV_PC_REGNUM) - offset =3D 0; - else if (regnum =3D=3D RISCV_SP_REGNUM) - offset =3D 1; - else if (regnum =3D=3D RISCV_ZERO_REGNUM + 8) /* S0 */ - offset =3D 2; - else if (regnum =3D=3D RISCV_ZERO_REGNUM + 9) /* S1 */ - offset =3D 3; - else if (regnum >=3D RISCV_ZERO_REGNUM + 19 - && regnum <=3D RISCV_ZERO_REGNUM + 27) /* S2..S11 */ - offset =3D regnum - (RISCV_ZERO_REGNUM + 19) + 4; - else if (regnum >=3D RISCV_FIRST_FP_REGNUM - && regnum <=3D RISCV_FIRST_FP_REGNUM + 11) - offset =3D regnum - RISCV_FIRST_FP_REGNUM + 14; /* FS0..FS11 */ - else - { - /* Not saved. */ - return -1; - } - - int size =3D register_size (arch, regnum); - return offset * size; -} - -/* Supply register REGNUM, which has been saved on REGISTER_ADDR, to the - regcache. */ - -static void -supply_register_at_address (struct regcache *regcache, int regnum, - CORE_ADDR register_addr) -{ - struct gdbarch *gdbarch =3D regcache->arch (); - int buf_size =3D register_size (gdbarch, regnum); - gdb_byte *buf; - - buf =3D (gdb_byte *) alloca (buf_size); - read_memory (register_addr, buf, buf_size); - regcache->raw_supply (regnum, buf); -} - -void -riscv_ravenscar_ops::fetch_registers (struct regcache *regcache, int regnu= m) +riscv_ravenscar_ops::riscv_ravenscar_ops (struct gdbarch *arch) + : ravenscar_arch_ops (gdb::make_array_view (reg_offsets, LAST_REGISTER += 1)) { - struct gdbarch *gdbarch =3D regcache->arch (); - const int num_regs =3D gdbarch_num_regs (gdbarch); - int current_regnum; - CORE_ADDR current_address; - CORE_ADDR thread_descriptor_address; - - /* The tid is the thread_id field, which is a pointer to the thread. */ - thread_descriptor_address =3D (CORE_ADDR) inferior_ptid.tid (); + int reg_size =3D riscv_isa_xlen (arch); =20 - /* Read registers. */ - for (current_regnum =3D 0; current_regnum < num_regs; current_regnum++) + for (int regnum =3D 0; regnum <=3D LAST_REGISTER; ++regnum) { - int offset =3D register_offset (gdbarch, current_regnum); + int offset; + if (regnum =3D=3D RISCV_RA_REGNUM || regnum =3D=3D RISCV_PC_REGNUM) + offset =3D 0; + else if (regnum =3D=3D RISCV_SP_REGNUM) + offset =3D 1; + else if (regnum =3D=3D RISCV_ZERO_REGNUM + 8) /* S0 */ + offset =3D 2; + else if (regnum =3D=3D RISCV_ZERO_REGNUM + 9) /* S1 */ + offset =3D 3; + else if (regnum >=3D RISCV_ZERO_REGNUM + 19 + && regnum <=3D RISCV_ZERO_REGNUM + 27) /* S2..S11 */ + offset =3D regnum - (RISCV_ZERO_REGNUM + 19) + 4; + else if (regnum >=3D RISCV_FIRST_FP_REGNUM + && regnum <=3D RISCV_FIRST_FP_REGNUM + 11) + offset =3D regnum - RISCV_FIRST_FP_REGNUM + 14; /* FS0..FS11 */ + else + offset =3D -1; =20 if (offset !=3D -1) - { - current_address =3D thread_descriptor_address + offset; - supply_register_at_address (regcache, current_regnum, - current_address); - } - } -} - -void -riscv_ravenscar_ops::store_registers (struct regcache *regcache, int regnu= m) -{ - struct gdbarch *gdbarch =3D regcache->arch (); - int buf_size =3D register_size (gdbarch, regnum); - gdb_byte buf[buf_size]; - CORE_ADDR register_address; - - int offset =3D register_offset (gdbarch, regnum); - if (offset !=3D -1) - { - register_address =3D inferior_ptid.tid () + offset; + offset *=3D reg_size; =20 - regcache->raw_collect (regnum, buf); - write_memory (register_address, - buf, - buf_size); + reg_offsets[regnum] =3D offset; } } =20 -/* The ravenscar_arch_ops vector for most RISC-V targets. */ - -static struct riscv_ravenscar_ops riscv_ravenscar_ops; - /* Register riscv_ravenscar_ops in GDBARCH. */ =20 void register_riscv_ravenscar_ops (struct gdbarch *gdbarch) { - set_gdbarch_ravenscar_ops (gdbarch, &riscv_ravenscar_ops); + set_gdbarch_ravenscar_ops (gdbarch, new riscv_ravenscar_ops (gdbarch)); } diff --git a/gdb/sparc-ravenscar-thread.c b/gdb/sparc-ravenscar-thread.c index 014d8981d7b..b199afb99c0 100644 --- a/gdb/sparc-ravenscar-thread.c +++ b/gdb/sparc-ravenscar-thread.c @@ -26,12 +26,6 @@ #include "sparc-ravenscar-thread.h" #include "gdbarch.h" =20 -struct sparc_ravenscar_ops : public ravenscar_arch_ops -{ - void fetch_registers (struct regcache *, int) override; - void store_registers (struct regcache *, int) override; -}; - /* Register offsets from a referenced address (exempli gratia the Thread_Descriptor). The referenced address depends on the register number. The Thread_Descriptor layout and the stack layout are document= ed @@ -56,121 +50,9 @@ static const int sparc_register_offsets[] =3D 0x40, 0x20, 0x44, -1, 0x1C, -1, 0x4C, -1 }; =20 -/* supply register REGNUM, which has been saved on REGISTER_ADDR, to the - regcache. */ - -static void -supply_register_at_address (struct regcache *regcache, int regnum, - CORE_ADDR register_addr) -{ - struct gdbarch *gdbarch =3D regcache->arch (); - int buf_size =3D register_size (gdbarch, regnum); - gdb_byte *buf; - - buf =3D (gdb_byte *) alloca (buf_size); - read_memory (register_addr, buf, buf_size); - regcache->raw_supply (regnum, buf); -} - -/* Return true if, for a non-running thread, REGNUM has been saved on the - stack. */ - -static int -register_on_stack_p (int regnum) -{ - return (regnum >=3D SPARC_L0_REGNUM && regnum <=3D SPARC_L7_REGNUM) - || (regnum >=3D SPARC_I0_REGNUM && regnum <=3D SPARC_I7_REGNUM); -} - -/* Return true if, for a non-running thread, REGNUM has been saved on the - Thread_Descriptor. */ - -static int -register_in_thread_descriptor_p (int regnum) -{ - return (regnum >=3D SPARC_O0_REGNUM && regnum <=3D SPARC_O7_REGNUM) - || (regnum =3D=3D SPARC32_PSR_REGNUM) - || (regnum >=3D SPARC_G1_REGNUM && regnum <=3D SPARC_G7_REGNUM) - || (regnum =3D=3D SPARC32_Y_REGNUM) - || (regnum =3D=3D SPARC32_WIM_REGNUM) - || (regnum =3D=3D SPARC32_FSR_REGNUM) - || (regnum >=3D SPARC_F0_REGNUM && regnum <=3D SPARC_F0_REGNUM + 31) - || (regnum =3D=3D SPARC32_PC_REGNUM); -} - -/* to_fetch_registers when inferior_ptid is different from the running - thread. */ - -void -sparc_ravenscar_ops::fetch_registers (struct regcache *regcache, int regnu= m) -{ - struct gdbarch *gdbarch =3D regcache->arch (); - const int sp_regnum =3D gdbarch_sp_regnum (gdbarch); - const int num_regs =3D gdbarch_num_regs (gdbarch); - int current_regnum; - CORE_ADDR current_address; - CORE_ADDR thread_descriptor_address; - ULONGEST stack_address; - - /* The tid is the thread_id field, which is a pointer to the thread. */ - thread_descriptor_address =3D (CORE_ADDR) inferior_ptid.tid (); - - /* Read the saved SP in the context buffer. */ - current_address =3D thread_descriptor_address - + sparc_register_offsets [sp_regnum]; - supply_register_at_address (regcache, sp_regnum, current_address); - regcache_cooked_read_unsigned (regcache, sp_regnum, &stack_address); - - /* Read registers. */ - for (current_regnum =3D 0; current_regnum < num_regs; current_regnum ++) - { - if (register_in_thread_descriptor_p (current_regnum)) - { - current_address =3D thread_descriptor_address - + sparc_register_offsets [current_regnum]; - supply_register_at_address (regcache, current_regnum, - current_address); - } - else if (register_on_stack_p (current_regnum)) - { - current_address =3D stack_address - + sparc_register_offsets [current_regnum]; - supply_register_at_address (regcache, current_regnum, - current_address); - } - } -} - -/* to_store_registers when inferior_ptid is different from the running - thread. */ - -void -sparc_ravenscar_ops::store_registers (struct regcache *regcache, int regnu= m) -{ - struct gdbarch *gdbarch =3D regcache->arch (); - int buf_size =3D register_size (gdbarch, regnum); - gdb_byte buf[buf_size]; - ULONGEST register_address; - - if (register_in_thread_descriptor_p (regnum)) - register_address =3D - inferior_ptid.tid () + sparc_register_offsets [regnum]; - else if (register_on_stack_p (regnum)) - { - regcache_cooked_read_unsigned (regcache, SPARC_SP_REGNUM, - ®ister_address); - register_address +=3D sparc_register_offsets [regnum]; - } - else - return; - - regcache->raw_collect (regnum, buf); - write_memory (register_address, - buf, - buf_size); -} - -static struct sparc_ravenscar_ops sparc_ravenscar_ops; +static struct ravenscar_arch_ops sparc_ravenscar_ops (sparc_register_offse= ts, + SPARC_L0_REGNUM, + SPARC_I7_REGNUM); =20 /* Register ravenscar_arch_ops in GDBARCH. */