From: Jiangshuai Li <jiangshuai_li@linux.alibaba.com>
To: gdb-patches@sourceware.org
Cc: Jiangshuai Li <jiangshuai_li@linux.alibaba.com>
Subject: [PATCH] gdb/csky support .reg2 for kernel 4.x and later
Date: Fri, 22 Jul 2022 13:54:46 +0800 [thread overview]
Message-ID: <20220722055446.2836-1-jiangshuai_li@linux.alibaba.com> (raw)
When kernel's version >= 4.x, the size of .reg2 section will be 400.
Contents of .reg2 are {
unsigned long vr[96]; // vr0~vr15 & fr16~fr31
unsigned long fcr;
unsigned long fesr;
unsigned long fid;
unsigned long reserved;
};
---
gdb/csky-linux-tdep.c | 203 +++++++++++++++++++++++++++++++++---------
1 file changed, 161 insertions(+), 42 deletions(-)
diff --git a/gdb/csky-linux-tdep.c b/gdb/csky-linux-tdep.c
index 440045e7713..86a40a4d0e9 100644
--- a/gdb/csky-linux-tdep.c
+++ b/gdb/csky-linux-tdep.c
@@ -36,6 +36,8 @@
#define SIZEOF_CSKY_GREGSET 34*4
/* Float regset fesr fsr fr0-fr31 for CK810. */
#define SIZEOF_CSKY_FREGSET 34*4
+/* Float regset vr0~vr15 fr15~fr31, reserved for CK810 when kernel 4.x. */
+#define SIZEOF_CSKY_FREGSET_K4X 400
/* Offset mapping table from core_section to regcache of general
registers for ck810. */
@@ -65,8 +67,8 @@ static const int csky_fregset_offset[] =
static void
csky_supply_gregset (const struct regset *regset,
- struct regcache *regcache, int regnum,
- const void *regs, size_t len)
+ struct regcache *regcache, int regnum,
+ const void *regs, size_t len)
{
int i, gregset_num;
const gdb_byte *gregs = (const gdb_byte *) regs ;
@@ -77,8 +79,8 @@ csky_supply_gregset (const struct regset *regset,
for (i = 0; i < gregset_num; i++)
{
if ((regnum == csky_gregset_offset[i] || regnum == -1)
- && csky_gregset_offset[i] != -1)
- regcache->raw_supply (csky_gregset_offset[i], gregs + 4 * i);
+ && csky_gregset_offset[i] != -1)
+ regcache->raw_supply (csky_gregset_offset[i], gregs + 4 * i);
}
}
@@ -86,8 +88,8 @@ csky_supply_gregset (const struct regset *regset,
static void
csky_collect_gregset (const struct regset *regset,
- const struct regcache *regcache,
- int regnum, void *gregs_buf, size_t len)
+ const struct regcache *regcache,
+ int regnum, void *gregs_buf, size_t len)
{
int regno, gregset_num;
gdb_byte *gregs = (gdb_byte *) gregs_buf ;
@@ -98,9 +100,9 @@ csky_collect_gregset (const struct regset *regset,
for (regno = 0; regno < gregset_num; regno++)
{
if ((regnum == csky_gregset_offset[regno] || regnum == -1)
- && csky_gregset_offset[regno] != -1)
- regcache->raw_collect (regno,
- gregs + 4 + csky_gregset_offset[regno]);
+ && csky_gregset_offset[regno] != -1)
+ regcache->raw_collect (regno,
+ gregs + 4 + csky_gregset_offset[regno]);
}
}
@@ -108,8 +110,8 @@ csky_collect_gregset (const struct regset *regset,
static void
csky_supply_fregset (const struct regset *regset,
- struct regcache *regcache, int regnum,
- const void *regs, size_t len)
+ struct regcache *regcache, int regnum,
+ const void *regs, size_t len)
{
int i;
int offset = 0;
@@ -118,15 +120,76 @@ csky_supply_fregset (const struct regset *regset,
int fregset_num = ARRAY_SIZE (csky_fregset_offset);
gdb_assert (len >= SIZEOF_CSKY_FREGSET);
- for (i = 0; i < fregset_num; i++)
+ if (len == SIZEOF_CSKY_FREGSET)
{
- if ((regnum == csky_fregset_offset[i] || regnum == -1)
- && csky_fregset_offset[i] != -1)
- {
- int num = csky_fregset_offset[i];
- offset += register_size (gdbarch, num);
- regcache->raw_supply (csky_fregset_offset[i], fregs + offset);
- }
+ for (i = 0; i < fregset_num; i++)
+ {
+ if ((regnum == csky_fregset_offset[i] || regnum == -1)
+ && csky_fregset_offset[i] != -1)
+ {
+ int num = csky_fregset_offset[i];
+ offset += register_size (gdbarch, num);
+ regcache->raw_supply (csky_fregset_offset[i], fregs + offset);
+ }
+ }
+ }
+ else if (len == SIZEOF_CSKY_FREGSET_K4X)
+ {
+ /* When kernel version >= 4.x, .reg2 size will be 400.
+ Contents is {
+ unsigned long vr[96]; // vr0~vr15 + fr16~fr31
+ unsigned long fcr;
+ unsigned long fesr;
+ unsigned long fid;
+ unsigned long reserved;
+ } */
+ int fcr_regno[] = {122, 123, 121}; /* fcr, fesr, fid. */
+
+ /* Supply vr0~vr15. */
+ for (i = 0; i < 16; i ++)
+ {
+ if (gdbarch_register_name (gdbarch, (CSKY_VR0_REGNUM + i)))
+ {
+ offset = 16 * i;
+ regcache->raw_supply (CSKY_VR0_REGNUM + i,
+ fregs + offset);
+ }
+ }
+ /* Supply fr0~fr15. */
+ for (i = 0; i < 16; i ++)
+ {
+ if (gdbarch_register_name (gdbarch, (CSKY_FR0_REGNUM + i)))
+ {
+ offset = 16 * i;
+ regcache->raw_supply (CSKY_FR0_REGNUM + i,
+ fregs + offset);
+ }
+ }
+ /* Supply fr16~fr31. */
+ for (i = 0; i < 16; i ++)
+ {
+ if (gdbarch_register_name (gdbarch, (CSKY_FR16_REGNUM + i)))
+ {
+ offset = (16 * 16) + (8 * i);
+ regcache->raw_supply (CSKY_FR16_REGNUM + i,
+ fregs + offset);
+ }
+ }
+ /* Supply fcr, fesr, fid. */
+ for (i = 0; i < 3; i ++)
+ {
+ if (gdbarch_register_name (gdbarch, fcr_regno[i]))
+ {
+ offset = (16 * 16) + (16 * 8) + (4 * i);
+ regcache->raw_supply (fcr_regno[i],
+ fregs + offset);
+ }
+ }
+ }
+ else
+ {
+ warning (_("Unknow size %ld of section .reg2, can not get value"
+ " of float registers."), len);
}
}
@@ -134,8 +197,8 @@ csky_supply_fregset (const struct regset *regset,
static void
csky_collect_fregset (const struct regset *regset,
- const struct regcache *regcache,
- int regnum, void *fregs_buf, size_t len)
+ const struct regcache *regcache,
+ int regnum, void *fregs_buf, size_t len)
{
int regno;
struct gdbarch *gdbarch = regcache->arch ();
@@ -144,14 +207,67 @@ csky_collect_fregset (const struct regset *regset,
int offset = 0;
gdb_assert (len >= SIZEOF_CSKY_FREGSET);
- for (regno = 0; regno < fregset_num; regno++)
+
+ if (len == SIZEOF_CSKY_FREGSET)
+ {
+ for (regno = 0; regno < fregset_num; regno++)
+ {
+ if ((regnum == csky_fregset_offset[regno] || regnum == -1)
+ && csky_fregset_offset[regno] != -1)
+ {
+ offset += register_size (gdbarch, csky_fregset_offset[regno]);
+ regcache->raw_collect (regno, fregs + offset);
+ }
+ }
+ }
+ else if (len == SIZEOF_CSKY_FREGSET_K4X)
+ {
+ /* When kernel version >= 4.x, .reg2 size will be 400.
+ Contents is {
+ unsigned long vr[96]; // vr0~vr15 + fr16~fr31
+ unsigned long fcr;
+ unsigned long fesr;
+ unsigned long fid;
+ unsigned long reserved;
+ } */
+ int i = 0;
+ int fcr_regno[] = {122, 123, 121}; /* fcr, fesr, fid. */
+
+ /* Supply vr0~vr15. */
+ for (i = 0; i < 16; i ++)
+ {
+ if (gdbarch_register_name (gdbarch, (CSKY_VR0_REGNUM + i)))
+ {
+ offset = 16 * i;
+ regcache ->raw_collect (CSKY_VR0_REGNUM + i,
+ fregs + offset);
+ }
+ }
+ /* Supply fr16~fr31. */
+ for (i = 0; i < 16; i ++)
+ {
+ if (gdbarch_register_name (gdbarch, (CSKY_FR16_REGNUM + i)))
+ {
+ offset = (16 * 16) + (8 * i);
+ regcache ->raw_collect (CSKY_FR16_REGNUM + i,
+ fregs + offset);
+ }
+ }
+ /* Supply fcr, fesr, fid. */
+ for (i = 0; i < 3; i ++)
+ {
+ if (gdbarch_register_name (gdbarch, fcr_regno[i]))
+ {
+ offset = (16 * 16) + (16 * 8) + (4 * i);
+ regcache ->raw_collect (fcr_regno[i],
+ fregs + offset);
+ }
+ }
+ }
+ else
{
- if ((regnum == csky_fregset_offset[regno] || regnum == -1)
- && csky_fregset_offset[regno] != -1)
- {
- offset += register_size (gdbarch, csky_fregset_offset[regno]);
- regcache->raw_collect (regno, fregs + offset);
- }
+ warning (_("Unknow size %ld of section .reg2, will not set value"
+ " of float registers."), len);
}
}
@@ -166,16 +282,19 @@ static const struct regset csky_regset_float =
{
NULL,
csky_supply_fregset,
- csky_collect_fregset
+ csky_collect_fregset,
+ /* Allow .reg2 has different size, buf size of .reg2 should
+ always is or bigger than SIZEOF_CSKY_FREGSET. */
+ 1
};
/* Iterate over core file register note sections. */
static void
csky_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
- iterate_over_regset_sections_cb *cb,
- void *cb_data,
- const struct regcache *regcache)
+ iterate_over_regset_sections_cb *cb,
+ void *cb_data,
+ const struct regcache *regcache)
{
cb (".reg", sizeof (csky_gregset_offset), sizeof (csky_gregset_offset),
&csky_regset_general, NULL, cb_data);
@@ -185,17 +304,17 @@ csky_linux_iterate_over_regset_sections (struct gdbarch *gdbarch,
static void
csky_linux_rt_sigreturn_init (const struct tramp_frame *self,
- struct frame_info *this_frame,
- struct trad_frame_cache *this_cache,
- CORE_ADDR func)
+ struct frame_info *this_frame,
+ struct trad_frame_cache *this_cache,
+ CORE_ADDR func)
{
int i;
CORE_ADDR sp = get_frame_register_unsigned (this_frame, 14);
CORE_ADDR base = sp + CSKY_SIGINFO_OFFSET + CSKY_SIGINFO_SIZE
- + CSKY_UCONTEXT_SIGCONTEXT
- + CSKY_SIGCONTEXT_SC_USP
- + CSKY_SIGCONTEXT_SC_A0;
+ + CSKY_UCONTEXT_SIGCONTEXT
+ + CSKY_SIGCONTEXT_SC_USP
+ + CSKY_SIGCONTEXT_SC_A0;
/* Set addrs of R0 ~ R13. */
for (i = 0; i < 14; i++)
@@ -239,11 +358,11 @@ csky_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
set_gdbarch_skip_trampoline_code (gdbarch, find_solib_trampoline_target);
set_gdbarch_skip_solib_resolver (gdbarch, glibc_skip_solib_resolver);
set_solib_svr4_fetch_link_map_offsets (gdbarch,
- linux_ilp32_fetch_link_map_offsets);
+ linux_ilp32_fetch_link_map_offsets);
/* Enable TLS support. */
set_gdbarch_fetch_tls_load_module_address (gdbarch,
- svr4_fetch_objfile_link_map);
+ svr4_fetch_objfile_link_map);
/* Core file support. */
set_gdbarch_iterate_over_regset_sections (
@@ -252,7 +371,7 @@ csky_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
/* Append tramp frame unwinder for SIGNAL. */
tramp_frame_prepend_unwinder (gdbarch,
- &csky_linux_rt_sigreturn_tramp_frame);
+ &csky_linux_rt_sigreturn_tramp_frame);
}
void _initialize_csky_linux_tdep ();
@@ -260,5 +379,5 @@ void
_initialize_csky_linux_tdep ()
{
gdbarch_register_osabi (bfd_arch_csky, 0, GDB_OSABI_LINUX,
- csky_linux_init_abi);
+ csky_linux_init_abi);
}
--
2.25.1
next reply other threads:[~2022-07-22 5:54 UTC|newest]
Thread overview: 2+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-07-22 5:54 Jiangshuai Li [this message]
2022-07-23 21:42 ` Kevin Buettner
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20220722055446.2836-1-jiangshuai_li@linux.alibaba.com \
--to=jiangshuai_li@linux.alibaba.com \
--cc=gdb-patches@sourceware.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).