GDB (xrefs)
Loading...
Searching...
No Matches
loongarch-linux-nat.c
Go to the documentation of this file.
1/* Native-dependent code for GNU/Linux on LoongArch processors.
2
3 Copyright (C) 2022-2023 Free Software Foundation, Inc.
4 Contributed by Loongson Ltd.
5
6 This file is part of GDB.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20
21#include "defs.h"
22#include "elf/common.h"
23#include "gregset.h"
24#include "inferior.h"
25#include "linux-nat-trad.h"
26#include "loongarch-tdep.h"
27#include "nat/gdb_ptrace.h"
28#include "target-descriptions.h"
29
30#include <asm/ptrace.h>
31
32/* LoongArch Linux native additions to the default Linux support. */
33
35{
36public:
37 /* Add our register access methods. */
38 void fetch_registers (struct regcache *, int) override;
39 void store_registers (struct regcache *, int) override;
40
41protected:
42 /* Override linux_nat_trad_target methods. */
43 CORE_ADDR register_u_offset (struct gdbarch *gdbarch, int regnum,
44 int store_p) override;
45};
46
47/* Fill GDB's register array with the general-purpose, orig_a0, pc and badv
48 register values from the current thread. */
49
50static void
52{
53 elf_gregset_t regset;
54
55 if (regnum == -1 || (regnum >= 0 && regnum < 32)
59 {
60 struct iovec iov;
61
62 iov.iov_base = &regset;
63 iov.iov_len = sizeof (regset);
64
65 if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, (long) &iov) < 0)
66 perror_with_name (_("Couldn't get NT_PRSTATUS registers"));
67 else
69 &regset, sizeof (regset));
70 }
71}
72
73/* Store to the current thread the valid general-purpose, orig_a0, pc and badv
74 register values in the GDB's register array. */
75
76static void
78{
79 elf_gregset_t regset;
80
81 if (regnum == -1 || (regnum >= 0 && regnum < 32)
85 {
86 struct iovec iov;
87
88 iov.iov_base = &regset;
89 iov.iov_len = sizeof (regset);
90
91 if (ptrace (PTRACE_GETREGSET, tid, NT_PRSTATUS, (long) &iov) < 0)
92 perror_with_name (_("Couldn't get NT_PRSTATUS registers"));
93 else
94 {
96 &regset, sizeof (regset));
97 if (ptrace (PTRACE_SETREGSET, tid, NT_PRSTATUS, (long) &iov) < 0)
98 perror_with_name (_("Couldn't set NT_PRSTATUS registers"));
99 }
100 }
101}
102
103/* Fill GDB's register array with the fp, fcc and fcsr
104 register values from the current thread. */
105
106static void
108{
109 elf_fpregset_t regset;
110
111 if ((regnum == -1)
113 {
114 struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };
115
116 if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, (long) &iovec) < 0)
117 perror_with_name (_("Couldn't get NT_FPREGSET registers"));
118 else
120 &regset, sizeof (regset));
121 }
122}
123
124/* Store to the current thread the valid fp, fcc and fcsr
125 register values in the GDB's register array. */
126
127static void
129{
130 elf_fpregset_t regset;
131
132 if ((regnum == -1)
134 {
135 struct iovec iovec = { .iov_base = &regset, .iov_len = sizeof (regset) };
136
137 if (ptrace (PTRACE_GETREGSET, tid, NT_FPREGSET, (long) &iovec) < 0)
138 perror_with_name (_("Couldn't get NT_FPREGSET registers"));
139 else
140 {
142 &regset, sizeof (regset));
143 if (ptrace (PTRACE_SETREGSET, tid, NT_FPREGSET, (long) &iovec) < 0)
144 perror_with_name (_("Couldn't set NT_FPREGSET registers"));
145 }
146 }
147}
148
149/* Implement the "fetch_registers" target_ops method. */
150
151void
160
161/* Implement the "store_registers" target_ops method. */
162
163void
172
173/* Return the address in the core dump or inferior of register REGNO. */
174
175CORE_ADDR
177 int regnum, int store_p)
178{
179 if (regnum >= 0 && regnum < 32)
180 return regnum;
181 else if (regnum == LOONGARCH_PC_REGNUM)
182 return LOONGARCH_PC_REGNUM;
183 else
184 return -1;
185}
186
188
189/* Wrapper functions. These are only used by libthread_db. */
190
191void
193{
194 loongarch_gregset.supply_regset (nullptr, regcache, -1, gregset,
195 sizeof (gdb_gregset_t));
196}
197
198void
200 int regnum)
201{
203 sizeof (gdb_gregset_t));
204}
205
206void
208{
209 loongarch_fpregset.supply_regset (nullptr, regcache, -1, fpregset,
210 sizeof (gdb_fpregset_t));
211}
212
213void
215 int regnum)
216{
218 sizeof (gdb_fpregset_t));
219}
220
221/* Initialize LoongArch Linux native support. */
222
224void
int regnum
void fetch_registers(struct regcache *, int) override
void store_registers(struct regcache *, int) override
CORE_ADDR register_u_offset(struct gdbarch *gdbarch, int regnum, int store_p) override
ptid_t ptid() const
Definition regcache.h:408
#define ptrace(request, pid, addr, data)
Definition gdb_ptrace.h:141
GDB_FPREGSET_T gdb_fpregset_t
Definition gregset.h:35
GDB_GREGSET_T gdb_gregset_t
Definition gregset.h:34
void add_inf_child_target(inf_child_target *target)
Definition inf-child.c:418
pid_t get_ptrace_pid(ptid_t ptid)
Definition inf-ptrace.c:238
struct linux_nat_target * linux_target
Definition linux-nat.c:189
#define PTRACE_SETREGSET
#define PTRACE_GETREGSET
static void fetch_gregs_from_thread(struct regcache *regcache, int regnum, pid_t tid)
static void fetch_fpregs_from_thread(struct regcache *regcache, int regnum, pid_t tid)
static loongarch_linux_nat_target the_loongarch_linux_nat_target
static void store_gregs_to_thread(struct regcache *regcache, int regnum, pid_t tid)
void _initialize_loongarch_linux_nat()
void supply_gregset(struct regcache *regcache, const gdb_gregset_t *gregset)
void supply_fpregset(struct regcache *regcache, const gdb_fpregset_t *fpregset)
static void store_fpregs_to_thread(struct regcache *regcache, int regnum, pid_t tid)
void fill_gregset(const struct regcache *regcache, gdb_gregset_t *gregset, int regnum)
void fill_fpregset(const struct regcache *regcache, gdb_fpregset_t *fpregset, int regnum)
const struct regset loongarch_gregset
const struct regset loongarch_fpregset
@ LOONGARCH_FIRST_FP_REGNUM
Definition loongarch.h:39
@ LOONGARCH_PC_REGNUM
Definition loongarch.h:34
@ LOONGARCH_FCSR_REGNUM
Definition loongarch.h:43
@ LOONGARCH_ORIG_A0_REGNUM
Definition loongarch.h:33
@ LOONGARCH_BADV_REGNUM
Definition loongarch.h:35
collect_regset_ftype * collect_regset
Definition regset.h:45
supply_regset_ftype * supply_regset
Definition regset.h:42