Sync 2203 loongarch64 support patch file

Signed-off-by: yangchenguang <yangchenguang@kylinsec.com.cn>
(cherry picked from commit 6d10caf6da2fd566b2d4ed52ebc1b89aa22628f0)
This commit is contained in:
yangchenguang 2023-04-23 15:14:16 +08:00 committed by openeuler-sync-bot
parent 98d023b8e9
commit 1c176507d2
6 changed files with 15649 additions and 1 deletions

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,372 @@
From 33b7b2b05fc32dc81e7f69bc0799aae55fde8255 Mon Sep 17 00:00:00 2001
From: Qing Zhang <zhangqing@loongson.cn>
Date: Thu, 2 Jun 2022 17:14:39 +0800
Subject: [PATCH 4/5] gdbserver-Add LoongArch port support
Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
---
gdb/arch/loongarch.c | 2 -
gdb/arch/loongarch.h | 2 -
gdbserver/Makefile.in | 2 +
gdbserver/configure.srv | 7 +
gdbserver/linux-loongarch-low.cc | 284 +++++++++++++++++++++++++++++++
5 files changed, 293 insertions(+), 4 deletions(-)
create mode 100644 gdbserver/linux-loongarch-low.cc
diff --git a/gdb/arch/loongarch.c b/gdb/arch/loongarch.c
index 007c638..34307f5 100644
--- a/gdb/arch/loongarch.c
+++ b/gdb/arch/loongarch.c
@@ -19,8 +19,6 @@
#include "gdbsupport/common-regcache.h"
#include "arch/loongarch.h"
-const char *loongarch_expedite_regs[] = { "r3", "pc", NULL };
-
unsigned int loongarch_debug = 0;
#include <../features/loongarch/base32.c>
diff --git a/gdb/arch/loongarch.h b/gdb/arch/loongarch.h
index 9d9f65b..dfe011f 100644
--- a/gdb/arch/loongarch.h
+++ b/gdb/arch/loongarch.h
@@ -26,8 +26,6 @@ extern unsigned int loongarch_debug;
struct target_desc;
-extern const char *loongarch_expedite_regs[];
-
extern struct target_desc *loongarch_get_base_target_description (int rlen);
extern struct target_desc *
diff --git a/gdbserver/Makefile.in b/gdbserver/Makefile.in
index 12e9b27..ddd52ec 100644
--- a/gdbserver/Makefile.in
+++ b/gdbserver/Makefile.in
@@ -192,6 +192,7 @@ SFILES = \
$(srcdir)/linux-arc-low.cc \
$(srcdir)/linux-arm-low.cc \
$(srcdir)/linux-ia64-low.cc \
+ $(srcdir)/linux-loongarch-low.cc \
$(srcdir)/linux-low.cc \
$(srcdir)/linux-m68k-low.cc \
$(srcdir)/linux-mips-low.cc \
@@ -226,6 +227,7 @@ SFILES = \
$(srcdir)/../gdb/arch/arm.c \
$(srcdir)/../gdb/arch/arm-get-next-pcs.c \
$(srcdir)/../gdb/arch/arm-linux.c \
+ $(srcdir)/../gdb/arch/loongarch.c \
$(srcdir)/../gdb/arch/ppc-linux-common.c \
$(srcdir)/../gdb/arch/riscv.c \
$(srcdir)/../gdb/nat/aarch64-mte-linux-ptrace.c \
diff --git a/gdbserver/configure.srv b/gdbserver/configure.srv
index 971f537..136be26 100644
--- a/gdbserver/configure.srv
+++ b/gdbserver/configure.srv
@@ -125,6 +125,13 @@ case "${gdbserver_host}" in
srv_tgtobj="$srv_linux_obj linux-ia64-low.o"
srv_linux_usrregs=yes
;;
+ loongarch*-*-linux*) srv_tgtobj="arch/loongarch.o arch/loongarch-linux-nat.o"
+ srv_tgtobj="${srv_tgtobj} linux-loongarch-low.o"
+ srv_tgtobj="${srv_tgtobj} ${srv_linux_obj}"
+ srv_linux_regsets=yes
+ srv_linux_usrregs=yes
+ srv_linux_thread_db=yes
+ ;;
m68*-*-linux*) if test "$gdb_cv_m68k_is_coldfire" = yes; then
srv_regobj=reg-cf.o
else
diff --git a/gdbserver/linux-loongarch-low.cc b/gdbserver/linux-loongarch-low.cc
new file mode 100644
index 0000000..cd8ad6e
--- /dev/null
+++ b/gdbserver/linux-loongarch-low.cc
@@ -0,0 +1,284 @@
+/* GNU/Linux/LoongArch specific low level interface, for the remote server
+ for GDB.
+ Copyright (C) 2022 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 "server.h"
+#include "linux-low.h"
+#include "tdesc.h"
+#include "elf/common.h"
+#include "arch/loongarch-linux-nat.h"
+
+/* Linux target op definitions for the LoongArch architecture. */
+
+class loongarch_target : public linux_process_target
+{
+public:
+
+ const regs_info *get_regs_info () override;
+
+ int breakpoint_kind_from_pc (CORE_ADDR *pcptr) override;
+
+ const gdb_byte *sw_breakpoint_from_kind (int kind, int *size) override;
+
+protected:
+
+ void low_arch_setup () override;
+
+ bool low_cannot_fetch_register (int regno) override;
+
+ bool low_cannot_store_register (int regno) override;
+
+ bool low_fetch_register (regcache *regcache, int regno) override;
+
+ bool low_supports_breakpoints () override;
+
+ CORE_ADDR low_get_pc (regcache *regcache) override;
+
+ void low_set_pc (regcache *regcache, CORE_ADDR newpc) override;
+
+ bool low_breakpoint_at (CORE_ADDR pc) override;
+};
+
+/* The singleton target ops object. */
+
+static loongarch_target the_loongarch_target;
+
+bool
+loongarch_target::low_cannot_fetch_register (int regno)
+{
+ gdb_assert_not_reached ("linux target op low_cannot_fetch_register "
+ "is not implemented by the target");
+}
+
+bool
+loongarch_target::low_cannot_store_register (int regno)
+{
+ gdb_assert_not_reached ("linux target op low_cannot_store_register "
+ "is not implemented by the target");
+}
+
+/* Implementation of linux target ops method "low_arch_setup". */
+
+void
+loongarch_target::low_arch_setup ()
+{
+ static const char *expedite_regs[] = { "r3", "pc", NULL };
+ int pid = lwpid_of (current_thread);
+ struct target_desc *tdesc = loongarch_linux_read_description_runtime (pid);
+
+ if (!tdesc->expedite_regs)
+ init_target_desc (tdesc, expedite_regs);
+ current_process ()->tdesc = tdesc;
+}
+
+/* Collect GPRs from REGCACHE into BUF. */
+
+static void
+loongarch_fill_gregset (struct regcache *regcache, void *buf)
+{
+ const struct target_desc *tdesc = regcache->tdesc;
+ elf_gregset_t *regset = (elf_gregset_t *) buf;
+ int regno = find_regno (tdesc, "r0");
+ int i;
+
+ for (i = 1; i < 32; i++)
+ collect_register (regcache, regno + i, *regset + i);
+ collect_register_by_name (regcache, "orig_a0", *regset + 32);
+ collect_register_by_name (regcache, "pc", *regset + 33);
+ collect_register_by_name (regcache, "badv", *regset + 34);
+}
+
+/* Supply GPRs from BUF into REGCACHE. */
+
+static void
+loongarch_store_gregset (struct regcache *regcache, const void *buf)
+{
+ const struct target_desc *tdesc = regcache->tdesc;
+ const elf_gregset_t *regset = (const elf_gregset_t *) buf;
+ int regno = find_regno (tdesc, "r0");
+ int i;
+
+ supply_register_zeroed (regcache, regno);
+ for (i = 1; i < 32; i++)
+ supply_register (regcache, regno + i, *regset + i);
+ supply_register_by_name (regcache, "orig_a0", *regset + 32);
+ supply_register_by_name (regcache, "pc", *regset + 33);
+ supply_register_by_name (regcache, "badv", *regset + 34);
+}
+
+/* Collect FPRs from REGCACHE into BUF. */
+
+static void
+loongarch_fill_fpregset (struct regcache *regcache, void *buf)
+{
+ const struct target_desc *tdesc = regcache->tdesc;
+ int f = find_regno (tdesc, "f0");
+ int fcc = find_regno (tdesc, "fcc0");
+ int flen = register_size (regcache->tdesc, f);
+ gdb_byte *regbuf = (gdb_byte *) buf;
+ int i;
+
+ for (i = 0; i < ELF_NFPREG - 2; i++, regbuf += flen)
+ collect_register (regcache, f + i, regbuf);
+ for (i = 0; i < 8; i++)
+ collect_register (regcache, fcc + i, regbuf++);
+ collect_register_by_name (regcache, "fcsr", regbuf);
+}
+
+/* Supply FPRs from BUF into REGCACHE. */
+
+static void
+loongarch_store_fpregset (struct regcache *regcache, const void *buf)
+{
+ const struct target_desc *tdesc = regcache->tdesc;
+ int f = find_regno (tdesc, "f0");
+ int fcc = find_regno (tdesc, "fcc0");
+ int flen = register_size (regcache->tdesc, f);
+ const gdb_byte *regbuf = (const gdb_byte *) buf;
+ int i;
+
+ for (i = 0; i < ELF_NFPREG - 2; i++, regbuf += flen)
+ supply_register (regcache, f + i, regbuf);
+ for (i = 0; i < 8; i++)
+ supply_register (regcache, fcc + i, regbuf++);
+ supply_register_by_name (regcache, "fcsr", regbuf);
+}
+
+/* LoongArch/Linux regsets. */
+static struct regset_info loongarch_regsets[] = {
+ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_PRSTATUS, sizeof (elf_gregset_t),
+ GENERAL_REGS, loongarch_fill_gregset, loongarch_store_gregset },
+ { PTRACE_GETREGSET, PTRACE_SETREGSET, NT_FPREGSET, sizeof (elf_fpregset_t),
+ FP_REGS, loongarch_fill_fpregset, loongarch_store_fpregset },
+ NULL_REGSET
+};
+
+/* LoongArch/Linux regset information. */
+static struct regsets_info loongarch_regsets_info =
+ {
+ loongarch_regsets, /* regsets */
+ 0, /* num_regsets */
+ NULL, /* disabled_regsets */
+ };
+
+/* Definition of linux_target_ops data member "regs_info". */
+static struct regs_info loongarch_regs =
+ {
+ NULL, /* regset_bitmap */
+ NULL, /* usrregs */
+ &loongarch_regsets_info,
+ };
+
+/* Implementation of linux target ops method "get_regs_info". */
+
+const regs_info *
+loongarch_target::get_regs_info ()
+{
+ return &loongarch_regs;
+}
+
+/* Implementation of linux target ops method "low_fetch_register". */
+
+bool
+loongarch_target::low_fetch_register (regcache *regcache, int regno)
+{
+ const struct target_desc *tdesc = regcache->tdesc;
+
+ if (regno != find_regno (tdesc, "r0"))
+ return false;
+ supply_register_zeroed (regcache, regno);
+ return true;
+}
+
+bool
+loongarch_target::low_supports_breakpoints ()
+{
+ return true;
+}
+
+/* Implementation of linux target ops method "low_get_pc". */
+
+CORE_ADDR
+loongarch_target::low_get_pc (regcache *regcache)
+{
+ if (register_size (regcache->tdesc, 0) == 8)
+ return linux_get_pc_64bit (regcache);
+ else
+ return linux_get_pc_32bit (regcache);
+}
+
+/* Implementation of linux target ops method "low_set_pc". */
+
+void
+loongarch_target::low_set_pc (regcache *regcache, CORE_ADDR newpc)
+{
+ if (register_size (regcache->tdesc, 0) == 8)
+ linux_set_pc_64bit (regcache, newpc);
+ else
+ linux_set_pc_32bit (regcache, newpc);
+}
+
+#define loongarch_breakpoint_len 4
+
+/* LoongArch BRK software debug mode instruction.
+ This instruction needs to match gdb/loongarch-tdep.c
+ (loongarch_default_breakpoint). */
+static const gdb_byte loongarch_breakpoint[] = {0x05, 0x00, 0x2a, 0x00};
+
+/* Implementation of target ops method "breakpoint_kind_from_pc". */
+
+int
+loongarch_target::breakpoint_kind_from_pc (CORE_ADDR *pcptr)
+{
+ return loongarch_breakpoint_len;
+}
+
+/* Implementation of target ops method "sw_breakpoint_from_kind". */
+
+const gdb_byte *
+loongarch_target::sw_breakpoint_from_kind (int kind, int *size)
+{
+ *size = loongarch_breakpoint_len;
+ return (const gdb_byte *) &loongarch_breakpoint;
+}
+
+/* Implementation of linux target ops method "low_breakpoint_at". */
+
+bool
+loongarch_target::low_breakpoint_at (CORE_ADDR pc)
+{
+ gdb_byte insn[loongarch_breakpoint_len];
+
+ read_memory (pc, (unsigned char *) &insn, loongarch_breakpoint_len);
+ if (memcmp (insn, loongarch_breakpoint, loongarch_breakpoint_len) == 0)
+ return true;
+
+ return false;
+}
+
+/* The linux target ops object. */
+
+linux_process_target *the_linux_target = &the_loongarch_target;
+
+/* Initialize the LoongArch/Linux target. */
+
+void
+initialize_low_arch ()
+{
+ initialize_regsets_info (&loongarch_regsets_info);
+}
--
2.36.0

View File

@ -0,0 +1,423 @@
From a7e8aa01fceed4213a2b9677a6ad4cf3d80d3a37 Mon Sep 17 00:00:00 2001
From: Qing Zhang <zhangqing@loongson.cn>
Date: Fri, 23 Sep 2022 14:04:19 +0800
Subject: [PATCH 5/5] gdb-Add LoongArch clfs system
Signed-off-by: Qing Zhang <zhangqing@loongson.cn>
---
gdb/arch/loongarch-linux-nat.c | 15 ++++----
gdb/arch/loongarch.c | 18 ++++------
gdb/arch/loongarch.h | 4 +--
gdb/features/loongarch/base32.c | 3 +-
gdb/features/loongarch/base32.xml | 3 +-
gdb/features/loongarch/base64.c | 3 +-
gdb/features/loongarch/base64.xml | 3 +-
gdb/loongarch-linux-nat.c | 10 +++---
gdb/loongarch-linux-tdep.c | 58 ++++++++++++++++++-------------
gdb/loongarch-linux-tdep.h | 4 +--
gdb/loongarch-tdep.c | 14 +++++---
gdb/loongarch-tdep.h | 3 +-
12 files changed, 76 insertions(+), 62 deletions(-)
diff --git a/gdb/arch/loongarch-linux-nat.c b/gdb/arch/loongarch-linux-nat.c
index 70bf742..baf59f8 100644
--- a/gdb/arch/loongarch-linux-nat.c
+++ b/gdb/arch/loongarch-linux-nat.c
@@ -43,23 +43,23 @@ loongarch_cpucfg_may_ptrace (uint64_t rj, int tid)
struct target_desc *
loongarch_linux_read_description_runtime (int tid)
{
- int rlen, fpu32, fpu64, lbt, lsx, lasx;
+ int rlen, flen, lbt, lsx, lasx;
uint32_t cpucfg1 = loongarch_cpucfg_may_ptrace (1, tid);
rlen = cpucfg1 & 0x2 /* LA64 */ ? 64 : 32;
uint32_t cpucfg2 = loongarch_cpucfg_may_ptrace (2, tid);
- fpu32 = 0, fpu64 = 0;
+ flen = 0;
if (cpucfg2 & 0x4 /* FP_DP */)
- fpu64 = 1;
+ flen = 64;
else if (cpucfg2 & 0x2 /* FP_SP */)
- fpu32 = 1;
- if (fpu32 || fpu64)
+ flen = 32;
+ if (flen)
{
loongarch_elf_fpregset_t regset;
struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };
if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, &iovec) < 0)
- fpu32 = 0, fpu64 = 0;
+ flen = 0;
}
lbt = 0;
@@ -89,6 +89,5 @@ loongarch_linux_read_description_runtime (int tid)
lasx = 1;
}
- return loongarch_create_target_description (rlen, fpu32, fpu64, lbt, lsx,
- lasx);
+ return loongarch_create_target_description (rlen, flen, lbt, lsx, lasx);
}
diff --git a/gdb/arch/loongarch.c b/gdb/arch/loongarch.c
index 34307f5..9eab0aa 100644
--- a/gdb/arch/loongarch.c
+++ b/gdb/arch/loongarch.c
@@ -31,7 +31,7 @@ unsigned int loongarch_debug = 0;
#include <../features/loongarch/lasx.c>
target_desc *
-loongarch_create_target_description (int rlen, int fpu32, int fpu64, int lbt,
+loongarch_create_target_description (int rlen, int flen, int lbt,
int lsx, int lasx)
{
gdb_assert (rlen == 32 || rlen == 64);
@@ -50,10 +50,10 @@ loongarch_create_target_description (int rlen, int fpu32, int fpu64, int lbt,
else
gdb_assert_not_reached ("rlen unknown");
- if (fpu32)
- regnum = create_feature_loongarch_fpu32 (tdesc.get (), regnum);
- else if (fpu64)
+ if (flen == 64)
regnum = create_feature_loongarch_fpu64 (tdesc.get (), regnum);
+ else if (flen == 32)
+ regnum = create_feature_loongarch_fpu32 (tdesc.get (), regnum);
if (lbt && rlen == 32)
regnum = create_feature_loongarch_lbt32 (tdesc.get (), regnum);
@@ -70,13 +70,7 @@ loongarch_create_target_description (int rlen, int fpu32, int fpu64, int lbt,
}
target_desc *
-loongarch_get_base_target_description (int rlen)
+loongarch_get_base_target_description (int rlen, int flen)
{
- if (rlen == 64)
- return loongarch_create_target_description (64, 0, 0, 0, 0, 0);
- else if (rlen == 32)
- return loongarch_create_target_description (32, 0, 0, 0, 0, 0);
- else
- gdb_assert_not_reached ("rlen unknown");
- return NULL;
+ return loongarch_create_target_description (rlen, flen, 0, 0, 0);
}
diff --git a/gdb/arch/loongarch.h b/gdb/arch/loongarch.h
index dfe011f..997afab 100644
--- a/gdb/arch/loongarch.h
+++ b/gdb/arch/loongarch.h
@@ -26,10 +26,10 @@ extern unsigned int loongarch_debug;
struct target_desc;
-extern struct target_desc *loongarch_get_base_target_description (int rlen);
+extern struct target_desc *loongarch_get_base_target_description (int rlen, int flen);
extern struct target_desc *
-loongarch_create_target_description (int rlen, int fpu32, int fpu64, int lbt,
+loongarch_create_target_description (int rlen, int flen, int lbt,
int lsx, int lasx);
#endif
diff --git a/gdb/features/loongarch/base32.c b/gdb/features/loongarch/base32.c
index b6f2d06..3fb35ef 100644
--- a/gdb/features/loongarch/base32.c
+++ b/gdb/features/loongarch/base32.c
@@ -41,7 +41,8 @@ create_feature_loongarch_base32 (struct target_desc *result, long regnum)
tdesc_create_reg (feature, "r29", regnum++, 1, "general", 32, "uint32");
tdesc_create_reg (feature, "r30", regnum++, 1, "general", 32, "uint32");
tdesc_create_reg (feature, "r31", regnum++, 1, "general", 32, "uint32");
+ tdesc_create_reg (feature, "orig_a0", regnum++, 1, "general", 32, "uint32");
tdesc_create_reg (feature, "pc", regnum++, 1, "general", 32, "code_ptr");
- tdesc_create_reg (feature, "badvaddr", regnum++, 1, "general", 32, "code_ptr");
+ tdesc_create_reg (feature, "badv", regnum++, 1, "general", 32, "code_ptr");
return regnum;
}
diff --git a/gdb/features/loongarch/base32.xml b/gdb/features/loongarch/base32.xml
index 0afe81b..4c44dbe 100644
--- a/gdb/features/loongarch/base32.xml
+++ b/gdb/features/loongarch/base32.xml
@@ -40,6 +40,7 @@
<reg name="r29" bitsize="32" type="uint32" group="general"/>
<reg name="r30" bitsize="32" type="uint32" group="general"/>
<reg name="r31" bitsize="32" type="uint32" group="general"/>
+ <reg name="orig_a0" bitsize="32" type="uint32" group="general"/>
<reg name="pc" bitsize="32" type="code_ptr" group="general"/>
- <reg name="badvaddr" bitsize="32" type="code_ptr" group="general"/>
+ <reg name="badv" bitsize="32" type="code_ptr" group="general"/>
</feature>
diff --git a/gdb/features/loongarch/base64.c b/gdb/features/loongarch/base64.c
index 3ee2d9a..d84d425 100644
--- a/gdb/features/loongarch/base64.c
+++ b/gdb/features/loongarch/base64.c
@@ -41,7 +41,8 @@ create_feature_loongarch_base64 (struct target_desc *result, long regnum)
tdesc_create_reg (feature, "r29", regnum++, 1, "general", 64, "uint64");
tdesc_create_reg (feature, "r30", regnum++, 1, "general", 64, "uint64");
tdesc_create_reg (feature, "r31", regnum++, 1, "general", 64, "uint64");
+ tdesc_create_reg (feature, "orig_a0", regnum++, 1, "general", 64, "uint64");
tdesc_create_reg (feature, "pc", regnum++, 1, "general", 64, "code_ptr");
- tdesc_create_reg (feature, "badvaddr", regnum++, 1, "general", 64, "code_ptr");
+ tdesc_create_reg (feature, "badv", regnum++, 1, "general", 64, "code_ptr");
return regnum;
}
diff --git a/gdb/features/loongarch/base64.xml b/gdb/features/loongarch/base64.xml
index b53479f..05d766e 100644
--- a/gdb/features/loongarch/base64.xml
+++ b/gdb/features/loongarch/base64.xml
@@ -40,6 +40,7 @@
<reg name="r29" bitsize="64" type="uint64" group="general"/>
<reg name="r30" bitsize="64" type="uint64" group="general"/>
<reg name="r31" bitsize="64" type="uint64" group="general"/>
+ <reg name="orig_a0" bitsize="64" type="uint64" group="general"/>
<reg name="pc" bitsize="64" type="code_ptr" group="general"/>
- <reg name="badvaddr" bitsize="64" type="code_ptr" group="general"/>
+ <reg name="badv" bitsize="64" type="code_ptr" group="general"/>
</feature>
diff --git a/gdb/loongarch-linux-nat.c b/gdb/loongarch-linux-nat.c
index f31eff4..e79b660 100644
--- a/gdb/loongarch-linux-nat.c
+++ b/gdb/loongarch-linux-nat.c
@@ -89,7 +89,7 @@ loongarch_linux_nat_target::read_description ()
return loongarch_linux_read_description_runtime (inferior_ptid.pid ());
}
-/* Fill GDB's register array with the general-purpose, pc and badvaddr
+/* Fill GDB's register array with the general-purpose, orig_a0, pc and badv
register values from the current thread. */
static void
@@ -99,7 +99,8 @@ fetch_gregs_from_thread (struct regcache *regcache, int regno, pid_t tid)
loongarch_elf_gregset_t regset;
if ((regno == -1) || (regs->r <= regno && regno < regs->r + 32) ||
- (regs->pc == regno) || (regs->badvaddr == regno))
+ (regs->orig_a0 == regno) || (regs->pc == regno) ||
+ (regs->badv == regno))
{
struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };
@@ -111,7 +112,7 @@ fetch_gregs_from_thread (struct regcache *regcache, int regno, pid_t tid)
}
}
-/* Store to the current thread the valid general-purpose, pc and badvaddr
+/* Store to the current thread the valid general-purpose, orig_a0, pc and badv
register values in the GDB's register array. */
static void
@@ -121,7 +122,8 @@ store_gregs_to_thread (struct regcache *regcache, int regno, pid_t tid)
loongarch_elf_gregset_t regset;
if ((regno == -1) || (regs->r <= regno && regno < regs->r + 32) ||
- (regs->pc == regno) || (regs->badvaddr == regno))
+ (regs->orig_a0 == regno) || (regs->pc == regno) ||
+ (regs->badv == regno))
{
struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };
diff --git a/gdb/loongarch-linux-tdep.c b/gdb/loongarch-linux-tdep.c
index 1145d9e..7b4b9fa 100644
--- a/gdb/loongarch-linux-tdep.c
+++ b/gdb/loongarch-linux-tdep.c
@@ -63,19 +63,24 @@ loongarch_supply_elf_gregset (const struct regset *r,
regcache->raw_supply (regs->r + i, (const void *)buf);
}
+ /* Size base (orig_a0) = regsize * regs->orig_a0. */
+ buf = (const gdb_byte*)gprs + regsize * regs->orig_a0;
+ regcache->raw_supply (regs->orig_a0, (const void *)buf);
+
/* Size base (pc) = regsize * regs->pc. */
buf = (const gdb_byte*)gprs + regsize * regs->pc;
regcache->raw_supply (regs->pc, (const void *)buf);
- /* Size base (badvaddr) = regsize * regs->badvaddr. */
- buf = (const gdb_byte*)gprs + regsize * regs->badvaddr;
- regcache->raw_supply (regs->badvaddr, (const void *)buf);
+ /* Size base (badv) = regsize * regs->badv. */
+ buf = (const gdb_byte*)gprs + regsize * regs->badv;
+ regcache->raw_supply (regs->badv, (const void *)buf);
}
else if (regs->r == regno)
regcache->raw_supply_zeroed (regno);
else if ((regs->r < regno && regno < regs->r + 32)
+ || (regs->orig_a0 == regno)
|| (regs->pc == regno)
- || (regs->badvaddr == regno))
+ || (regs->badv == regno))
{
/* Offset offset (regno) = regsize * (regno - regs->r). */
buf = (const gdb_byte*)gprs + regsize * (regno - regs->r);
@@ -101,17 +106,22 @@ loongarch_fill_elf_gregset (const struct regset *r,
regcache->raw_collect (regs->r + i, (void *)buf);
}
+ /* Size base (orig_a0) = regsize * regs->orig_a0. */
+ buf = (gdb_byte *)gprs + regsize * regs->orig_a0;
+ regcache->raw_collect (regs->orig_a0, (void *)buf);
+
/* Size base (pc) = regsize * regs->pc. */
buf = (gdb_byte *)gprs + regsize * regs->pc;
regcache->raw_collect (regs->pc, (void *)buf);
- /* Size base (badvaddr) = regsize * regs->badvaddr. */
- buf = (gdb_byte *)gprs + regsize * regs->badvaddr;
- regcache->raw_collect (regs->badvaddr, (void *)buf);
+ /* Size base (badv) = regsize * regs->badv. */
+ buf = (gdb_byte *)gprs + regsize * regs->badv;
+ regcache->raw_collect (regs->badv, (void *)buf);
}
else if ((regs->r <= regno && regno < regs->r + 32)
+ ||(regs->orig_a0 == regno)
||(regs->pc == regno)
- ||(regs->badvaddr == regno))
+ ||(regs->badv == regno))
{
/* Offset offset (regno) = regsize * (regno - regs->r). */
buf = (gdb_byte *)gprs + regsize * (regno - regs->r);
@@ -541,42 +551,42 @@ static const struct target_desc *
loongarch_linux_core_read_description (struct gdbarch *gdbarch,
struct target_ops *target, bfd *abfd)
{
- int rlen, fpu32, fpu64, lbt, lsx, lasx;
+ int rlen, flen, fpu64, lbt, lsx, lasx;
rlen = 64;
- fpu32 = 0;
fpu64 = !!bfd_get_section_by_name (abfd, ".reg2");
lbt = !!bfd_get_section_by_name (abfd, ".reg-loongarch-lbt");
lsx = !!bfd_get_section_by_name (abfd, ".reg-loongarch-lsx");
lasx = !!bfd_get_section_by_name (abfd, ".reg-loongarch-lasx");
- return loongarch_create_target_description (rlen, fpu32, fpu64, lbt, lsx,
- lasx);
+ if (fpu64)
+ flen = 64;
+ else
+ flen = 0;
+
+ return loongarch_create_target_description (rlen, flen, lbt, lsx, lasx);
}
/* The RT signal frames look like this:
struct rt_sigframe {
- u32 rs_ass[4];
- u32 rs_pad[2];
struct siginfo rs_info;
- struct ucontext rs_uc;
+ struct ucontext rs_uctx;
};
struct ucontext {
unsigned long uc_flags;
struct ucontext *uc_link;
stack_t uc_stack;
- struct sigcontext uc_mcontext;
sigset_t uc_sigmask;
- unsigned long long uc_extcontext[0];
- }; */
-
-#define RTSIGFRAME_SIGINFO_SIZE 136
-#define RTSIGFRAME_SIGINFO_OFFSET (6 * 4)
-#define UCONTEXT_SIGCONTEXT_OFFSET 64
-#define RTSIGFRAME_SIGCONTEXT_OFFSET (RTSIGFRAME_SIGINFO_OFFSET \
- + RTSIGFRAME_SIGINFO_SIZE \
+ _u8 __unused[1024 / 8 - sizeof(sigset_t)];
+ struct sigcontext uc_mcontext;
+ };
+}; */
+
+#define RTSIGFRAME_SIGINFO_SIZE 128
+#define UCONTEXT_SIGCONTEXT_OFFSET 176
+#define RTSIGFRAME_SIGCONTEXT_OFFSET (RTSIGFRAME_SIGINFO_SIZE \
+ UCONTEXT_SIGCONTEXT_OFFSET)
static void
diff --git a/gdb/loongarch-linux-tdep.h b/gdb/loongarch-linux-tdep.h
index e3456a8..bb70043 100644
--- a/gdb/loongarch-linux-tdep.h
+++ b/gdb/loongarch-linux-tdep.h
@@ -26,10 +26,10 @@
#define ELF_NGREG 45
#define ELF_NFPREG 34
-typedef uint64_t loongarch_elf_gregset_t[ELF_NGREG];
+typedef unsigned long loongarch_elf_gregset_t[ELF_NGREG];
extern const struct regset loongarch_elf_gregset;
-typedef uint64_t loongarch_elf_fpregset_t[ELF_NFPREG];
+typedef double loongarch_elf_fpregset_t[ELF_NFPREG];
extern const struct regset loongarch_elf_fpregset;
/* Regset variable size. */
diff --git a/gdb/loongarch-tdep.c b/gdb/loongarch-tdep.c
index 87331bd..d306bbc 100644
--- a/gdb/loongarch-tdep.c
+++ b/gdb/loongarch-tdep.c
@@ -1383,7 +1383,8 @@ loongarch_register_reggroup_p (struct gdbarch *gdbarch, int regnum,
return 1;
if (group == general_reggroup
- && (regs->pc == regnum || regs->badvaddr == regnum
+ && (regs->orig_a0 == regnum || regs->pc == regnum
+ || regs->badv == regnum
|| (regs->r <= regnum && regnum < regs->r + 32)))
return 1;
@@ -1561,8 +1562,8 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
memset (tdep, 0, sizeof (*tdep));
memset (&tdep->regs, -1, sizeof (tdep->regs));
- /* If abfd is nullptr then a EF_LOONGARCH_ABI_LP64 is returned in
- its default state. */
+ /* If abfd is nullptr then a EF_LOONGARCH_ABI_LP64 | EF_LOONGARCH_FLOAT_ABI_DOUBLE
+ is returned in its default state. */
if (info.abfd != NULL
&& bfd_get_flavour (info.abfd) == bfd_target_elf_flavour)
{
@@ -1587,7 +1588,8 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
/* Check any target description for validity. */
if (!tdesc_has_registers (tdesc))
tdesc = loongarch_get_base_target_description (
- EF_LOONGARCH_IS_ILP32 (tdep->ef_abi) ? 32 : 64);
+ EF_LOONGARCH_IS_ILP32 (tdep->ef_abi) ? 32 : 64,
+ EF_LOONGARCH_IS_SINGLE_FLOAT (tdep->ef_abi) ? 32 : 64);
int valid_p = 1;
const struct tdesc_feature *feature;
@@ -1602,11 +1604,13 @@ loongarch_gdbarch_init (struct gdbarch_info info, struct gdbarch_list *arches)
for (i = 0; i < 32; i++)
valid_p &= tdesc_numbered_register (feature, tdesc_data.get (), regnum++,
loongarch_r_normal_name[i] + 1);
+ valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
+ tdep->regs.orig_a0 = regnum++, "orig_a0");
valid_p &= tdesc_numbered_register (feature, tdesc_data.get (),
tdep->regs.pc = regnum++, "pc");
valid_p
&= tdesc_numbered_register (feature, tdesc_data.get (),
- tdep->regs.badvaddr = regnum++, "badvaddr");
+ tdep->regs.badv = regnum++, "badv");
if ((feature = tdesc_find_feature (tdesc, "org.gnu.gdb.loongarch.fpu")))
{
diff --git a/gdb/loongarch-tdep.h b/gdb/loongarch-tdep.h
index c673c9e..12bc78e 100644
--- a/gdb/loongarch-tdep.h
+++ b/gdb/loongarch-tdep.h
@@ -37,8 +37,9 @@ struct gdbarch_tdep
int r;
int ra;
int sp;
+ int orig_a0;
int pc;
- int badvaddr;
+ int badv;
int f;
int fcc;
--
2.36.0

View File

@ -1,6 +1,6 @@
Name: gdb
Version: 11.1
Release: 3
Release: 4
License: GPLv3+ and GPLv3+ with exceptions and GPLv2+ and GPLv2+ with exceptions and GPL+ and LGPLv2+ and LGPLv3+ and BSD and Public Domain and GFDL-1.3
Source: ftp://sourceware.org/pub/gdb/releases/gdb-%{version}.tar.xz
@ -95,6 +95,14 @@ Patch81: gdb-rhbz2022177-dprintf-2.patch
Patch82: 0001-Make-c-exp.y-work-with-Bison-3.8.patch
%ifarch loongarch64
Patch83: 0001-gdb-Add-LoongArch-bfd-support.patch
Patch84: 0002-gdb-Add-LoongArch-opcodes-support.patch
Patch85: 0003-gdb-Add-LoongArch-gdb-support.patch
Patch86: 0004-gdbserver-Add-LoongArch-port-support.patch
Patch87: 0005-gdb-Add-LoongArch-clfs-system.patch
%endif
%global gdb_src gdb-%{version}
%global gdb_build build-%{_target_platform}
%global __python %{__python3}
@ -230,7 +238,9 @@ export CXXFLAGS="$CFLAGS"
--with-lzma \
--without-libunwind \
--enable-64-bit-bfd \
%ifnarch loongarch64
--enable-inprocess-agent \
%endif
--with-system-zlib \
%ifarch %{ix86} x86_64
--with-intel-pt \
@ -350,8 +360,10 @@ rm -f $RPM_BUILD_ROOT%{_datadir}/gdb/python/gdb/command/backtrace.py
%files gdbserver
%ifnarch riscv64
%{_bindir}/gdbserver
%ifnarch loongarch64
%{_libdir}/libinproctrace.so
%endif
%endif
%files help
%{_mandir}/*/gcore.1*
@ -366,6 +378,9 @@ rm -f $RPM_BUILD_ROOT%{_datadir}/gdb/python/gdb/command/backtrace.py
%{_infodir}/gdb.info*
%changelog
* Sun Apr 23 2023 yangchenguang <yangchenguang@kylinsec.com.cn> - 11.1-4
- Sync 2203 loongarch64 support patch file
* Wed Nov 23 2022 Wenyu Liu <liuwenyu7@huawei.com> - 11.1-3
- Eliminate hard coding issues for vendor name in gdb/version.in