From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from out30-44.freemail.mail.aliyun.com (out30-44.freemail.mail.aliyun.com [115.124.30.44]) by sourceware.org (Postfix) with ESMTPS id A024D3835839 for ; Fri, 22 Jul 2022 05:54:57 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.1 sourceware.org A024D3835839 X-Alimail-AntiSpam: AC=PASS; BC=-1|-1; BR=01201311R221e4; CH=green; DM=||false|; DS=||; FP=0|-1|-1|-1|0|-1|-1|-1; HT=ay29a033018046049; MF=jiangshuai_li@linux.alibaba.com; NM=1; PH=DS; RN=2; SR=0; TI=SMTPD_---0VK3rkmf_1658469291; Received: from lijsh-VirtualBox.hz.ali.com(mailfrom:jiangshuai_li@linux.alibaba.com fp:SMTPD_---0VK3rkmf_1658469291) by smtp.aliyun-inc.com; Fri, 22 Jul 2022 13:54:52 +0800 From: Jiangshuai Li To: gdb-patches@sourceware.org Cc: Jiangshuai Li Subject: [PATCH] gdb/csky support .reg2 for kernel 4.x and later Date: Fri, 22 Jul 2022 13:54:46 +0800 Message-Id: <20220722055446.2836-1-jiangshuai_li@linux.alibaba.com> X-Mailer: git-send-email 2.25.1 MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Spam-Status: No, score=-21.4 required=5.0 tests=BAYES_00, ENV_AND_HDR_SPF_MATCH, GIT_PATCH_0, KAM_DMARC_STATUS, RCVD_IN_DNSWL_NONE, SPF_HELO_NONE, SPF_PASS, TXREP, UNPARSEABLE_RELAY, USER_IN_DEF_SPF_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 22 Jul 2022 05:55:00 -0000 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