]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/m32r-linux-nat.c
PR31692, objdump fails .debug_info size check
[thirdparty/binutils-gdb.git] / gdb / m32r-linux-nat.c
CommitLineData
9b32d526
KI
1/* Native-dependent code for GNU/Linux m32r.
2
1d506c26 3 Copyright (C) 2004-2024 Free Software Foundation, Inc.
9b32d526
KI
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
9b32d526
KI
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
9b32d526 19
9b32d526
KI
20#include "inferior.h"
21#include "gdbcore.h"
22#include "regcache.h"
23#include "linux-nat.h"
10d6c8cd 24#include "target.h"
5826e159 25#include "nat/gdb_ptrace.h"
9b32d526
KI
26#include <sys/user.h>
27#include <sys/procfs.h>
bcc0c096 28#include "inf-ptrace.h"
9b32d526
KI
29
30/* Prototypes for supply_gregset etc. */
31#include "gregset.h"
32
33#include "m32r-tdep.h"
34\f
35
f6ac5f3d
PA
36class m32r_linux_nat_target final : public linux_nat_target
37{
38public:
39 /* Add our register access methods. */
40 void fetch_registers (struct regcache *, int) override;
41 void store_registers (struct regcache *, int) override;
42};
9b32d526 43
f6ac5f3d 44static m32r_linux_nat_target the_m32r_linux_nat_target;
9b32d526
KI
45
46/* Since EVB register is not available for native debug, we reduce
47 the number of registers. */
48#define M32R_LINUX_NUM_REGS (M32R_NUM_REGS - 1)
49
50/* Mapping between the general-purpose registers in `struct user'
51 format and GDB's register array layout. */
52static int regmap[] = {
53 4, 5, 6, 7, 0, 1, 2, 8,
54 9, 10, 11, 12, 13, 24, 25, 23,
55 19, 19, 26, 23, 22, 20, 16, 15
56};
57
58#define PSW_REGMAP 19
59#define BBPSW_REGMAP 21
60#define SPU_REGMAP 23
61#define SPI_REGMAP 26
62
025bb325
MS
63/* Doee (??) apply to the corresponding SET requests as well. */
64#define GETREGS_SUPPLIES(regno) (0 <= (regno) \
65 && (regno) <= M32R_LINUX_NUM_REGS)
9b32d526
KI
66\f
67
68
69/* Transfering the general-purpose registers between GDB, inferiors
70 and core files. */
71
72/* Fill GDB's register array with the general-purpose register values
73 in *GREGSETP. */
74
75void
7f7fe91e 76supply_gregset (struct regcache *regcache, const elf_gregset_t * gregsetp)
9b32d526 77{
7f7fe91e 78 const elf_greg_t *regp = (const elf_greg_t *) gregsetp;
9b32d526
KI
79 int i;
80 unsigned long psw, bbpsw;
81
82 psw = *(regp + PSW_REGMAP);
83 bbpsw = *(regp + BBPSW_REGMAP);
84
85 for (i = 0; i < M32R_LINUX_NUM_REGS; i++)
86 {
d817e083
UW
87 elf_greg_t regval;
88
9b32d526
KI
89 switch (i)
90 {
91 case PSW_REGNUM:
d817e083 92 regval = ((0x00c1 & bbpsw) << 8) | ((0xc100 & psw) >> 8);
9b32d526
KI
93 break;
94 case CBR_REGNUM:
d817e083
UW
95 regval = ((psw >> 8) & 1);
96 break;
97 default:
98 regval = *(regp + regmap[i]);
9b32d526
KI
99 break;
100 }
101
102 if (i != M32R_SP_REGNUM)
73e1c03f 103 regcache->raw_supply (i, &regval);
9b32d526 104 else if (psw & 0x8000)
73e1c03f 105 regcache->raw_supply (i, regp + SPU_REGMAP);
9b32d526 106 else
73e1c03f 107 regcache->raw_supply (i, regp + SPI_REGMAP);
9b32d526
KI
108 }
109}
110
111/* Fetch all general-purpose registers from process/thread TID and
112 store their values in GDB's register array. */
113
114static void
56be3814 115fetch_regs (struct regcache *regcache, int tid)
9b32d526
KI
116{
117 elf_gregset_t regs;
118
119 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 120 perror_with_name (_("Couldn't get registers"));
9b32d526 121
56be3814 122 supply_gregset (regcache, (const elf_gregset_t *) &regs);
9b32d526
KI
123}
124
125/* Fill register REGNO (if it is a general-purpose register) in
126 *GREGSETPS with the value in GDB's register array. If REGNO is -1,
127 do this for all registers. */
128
129void
7f7fe91e
UW
130fill_gregset (const struct regcache *regcache,
131 elf_gregset_t * gregsetp, int regno)
9b32d526
KI
132{
133 elf_greg_t *regp = (elf_greg_t *) gregsetp;
134 int i;
135 unsigned long psw, bbpsw, tmp;
136
137 psw = *(regp + PSW_REGMAP);
138 bbpsw = *(regp + BBPSW_REGMAP);
139
140 for (i = 0; i < M32R_LINUX_NUM_REGS; i++)
141 {
142 if (regno != -1 && regno != i)
143 continue;
144
145 if (i == CBR_REGNUM || i == PSW_REGNUM)
146 continue;
147
148 if (i == SPU_REGNUM || i == SPI_REGNUM)
149 continue;
150
151 if (i != M32R_SP_REGNUM)
34a79281 152 regcache->raw_collect (i, regp + regmap[i]);
9b32d526 153 else if (psw & 0x8000)
34a79281 154 regcache->raw_collect (i, regp + SPU_REGMAP);
9b32d526 155 else
34a79281 156 regcache->raw_collect (i, regp + SPI_REGMAP);
9b32d526
KI
157 }
158}
159
160/* Store all valid general-purpose registers in GDB's register array
161 into the process/thread specified by TID. */
162
163static void
56be3814 164store_regs (const struct regcache *regcache, int tid, int regno)
9b32d526
KI
165{
166 elf_gregset_t regs;
167
168 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 169 perror_with_name (_("Couldn't get registers"));
9b32d526 170
56be3814 171 fill_gregset (regcache, &regs, regno);
9b32d526
KI
172
173 if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 174 perror_with_name (_("Couldn't write registers"));
9b32d526
KI
175}
176\f
177
178
179/* Transfering floating-point registers between GDB, inferiors and cores.
180 Since M32R has no floating-point registers, these functions do nothing. */
181
182void
7f7fe91e 183supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregs)
9b32d526
KI
184{
185}
186
187void
7f7fe91e
UW
188fill_fpregset (const struct regcache *regcache,
189 gdb_fpregset_t *fpregs, int regno)
9b32d526
KI
190{
191}
192\f
193
194
195/* Transferring arbitrary registers between GDB and inferior. */
196
197/* Fetch register REGNO from the child process. If REGNO is -1, do
198 this for all registers (including the floating point and SSE
199 registers). */
200
f6ac5f3d
PA
201void
202m32r_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
9b32d526 203{
222312d3 204 pid_t tid = get_ptrace_pid (regcache->ptid ());
9b32d526
KI
205
206 /* Use the PTRACE_GETREGS request whenever possible, since it
207 transfers more registers in one system call, and we'll cache the
208 results. */
209 if (regno == -1 || GETREGS_SUPPLIES (regno))
210 {
56be3814 211 fetch_regs (regcache, tid);
9b32d526
KI
212 return;
213 }
214
f34652de 215 internal_error (_("Got request for bad register number %d."), regno);
9b32d526
KI
216}
217
218/* Store register REGNO back into the child process. If REGNO is -1,
219 do this for all registers (including the floating point and SSE
220 registers). */
f6ac5f3d
PA
221void
222m32r_linux_nat_target::store_registers (struct regcache *regcache, int regno)
9b32d526 223{
222312d3 224 pid_t tid = get_ptrace_pid (regcache->ptid ());
9b32d526
KI
225
226 /* Use the PTRACE_SETREGS request whenever possible, since it
227 transfers more registers in one system call. */
228 if (regno == -1 || GETREGS_SUPPLIES (regno))
229 {
56be3814 230 store_regs (regcache, tid, regno);
9b32d526
KI
231 return;
232 }
233
f34652de 234 internal_error (_("Got request to store bad register number %d."), regno);
9b32d526 235}
10d6c8cd 236
6c265988 237void _initialize_m32r_linux_nat ();
10d6c8cd 238void
6c265988 239_initialize_m32r_linux_nat ()
10d6c8cd 240{
10d6c8cd 241 /* Register the target. */
f6ac5f3d 242 linux_target = &the_m32r_linux_nat_target;
d9f719f1 243 add_inf_child_target (&the_m32r_linux_nat_target);
10d6c8cd 244}