]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/m68k-linux-nat.c
Add --section-ordering command line option to the bfd linker.
[thirdparty/binutils-gdb.git] / gdb / m68k-linux-nat.c
CommitLineData
a4b6fc86
AC
1/* Motorola m68k native support for GNU/Linux.
2
1d506c26 3 Copyright (C) 1996-2024 Free Software Foundation, Inc.
c906108c 4
c5aa993b 5 This file is part of GDB.
c906108c 6
c5aa993b
JM
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
c5aa993b 10 (at your option) any later version.
c906108c 11
c5aa993b
JM
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.
c906108c 16
c5aa993b 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/>. */
c906108c 19
c906108c
SS
20#include "frame.h"
21#include "inferior.h"
22#include "language.h"
23#include "gdbcore.h"
4e052eda 24#include "regcache.h"
10d6c8cd
DJ
25#include "target.h"
26#include "linux-nat.h"
a7cdaa91 27#include "gdbarch.h"
c906108c 28
32eeb91a
AS
29#include "m68k-tdep.h"
30
c906108c
SS
31#include <sys/dir.h>
32#include <signal.h>
5826e159 33#include "nat/gdb_ptrace.h"
c906108c
SS
34#include <sys/user.h>
35#include <sys/ioctl.h>
36#include <fcntl.h>
37#include <sys/procfs.h>
38
0280a90a
AS
39#ifdef HAVE_SYS_REG_H
40#include <sys/reg.h>
41#endif
42
c906108c 43#include <sys/file.h>
53ce3c39 44#include <sys/stat.h>
c906108c
SS
45
46#include "floatformat.h"
47
025bb325 48/* Prototypes for supply_gregset etc. */
3e00823e 49#include "gregset.h"
7b8b6d6d
AS
50
51/* Defines ps_err_e, struct ps_prochandle. */
52#include "gdb_proc_service.h"
53
bcc0c096
SM
54#include "inf-ptrace.h"
55
7b8b6d6d
AS
56#ifndef PTRACE_GET_THREAD_AREA
57#define PTRACE_GET_THREAD_AREA 25
58#endif
c906108c 59\f
f6ac5f3d
PA
60
61class m68k_linux_nat_target final : public linux_nat_target
62{
63public:
64 /* Add our register access methods. */
65 void fetch_registers (struct regcache *, int) override;
66 void store_registers (struct regcache *, int) override;
67};
68
69static m68k_linux_nat_target the_m68k_linux_nat_target;
70
c9f4d572 71/* This table must line up with gdbarch_register_name in "m68k-tdep.c". */
c5aa993b 72static const int regmap[] =
c906108c
SS
73{
74 PT_D0, PT_D1, PT_D2, PT_D3, PT_D4, PT_D5, PT_D6, PT_D7,
75 PT_A0, PT_A1, PT_A2, PT_A3, PT_A4, PT_A5, PT_A6, PT_USP,
76 PT_SR, PT_PC,
77 /* PT_FP0, ..., PT_FP7 */
78 21, 24, 27, 30, 33, 36, 39, 42,
79 /* PT_FPCR, PT_FPSR, PT_FPIAR */
80 45, 46, 47
81};
82
0280a90a
AS
83/* Which ptrace request retrieves which registers?
84 These apply to the corresponding SET requests as well. */
85#define NUM_GREGS (18)
86#define MAX_NUM_REGS (NUM_GREGS + 11)
87
0c13fc49 88static int
0280a90a
AS
89getregs_supplies (int regno)
90{
91 return 0 <= regno && regno < NUM_GREGS;
92}
93
0c13fc49 94static int
0280a90a
AS
95getfpregs_supplies (int regno)
96{
4ed226fe 97 return M68K_FP0_REGNUM <= regno && regno <= M68K_FPI_REGNUM;
0280a90a
AS
98}
99
100/* Does the current host support the GETREGS request? */
0c13fc49 101static int have_ptrace_getregs =
0280a90a
AS
102#ifdef HAVE_PTRACE_GETREGS
103 1
104#else
105 0
106#endif
107;
108
109\f
110
0280a90a
AS
111/* Fetching registers directly from the U area, one at a time. */
112
0280a90a
AS
113/* Fetch one register. */
114
115static void
56be3814 116fetch_register (struct regcache *regcache, int regno)
0280a90a 117{
ac7936df 118 struct gdbarch *gdbarch = regcache->arch ();
89e028e2 119 long regaddr, val;
52f0bd74 120 int i;
975c21ab 121 gdb_byte buf[M68K_MAX_REGISTER_SIZE];
222312d3 122 pid_t tid = get_ptrace_pid (regcache->ptid ());
0280a90a 123
de732108 124 regaddr = 4 * regmap[regno];
335d71d6 125 for (i = 0; i < register_size (gdbarch, regno); i += sizeof (long))
0280a90a
AS
126 {
127 errno = 0;
89e028e2
AS
128 val = ptrace (PTRACE_PEEKUSER, tid, regaddr, 0);
129 memcpy (&buf[i], &val, sizeof (long));
335d71d6 130 regaddr += sizeof (long);
0280a90a 131 if (errno != 0)
335d71d6
AS
132 error (_("Couldn't read register %s (#%d): %s."),
133 gdbarch_register_name (gdbarch, regno),
134 regno, safe_strerror (errno));
0280a90a 135 }
73e1c03f 136 regcache->raw_supply (regno, buf);
0280a90a
AS
137}
138
139/* Fetch register values from the inferior.
140 If REGNO is negative, do this for all registers.
025bb325 141 Otherwise, REGNO specifies which register (so we can save time). */
c906108c 142
10d6c8cd 143static void
56be3814 144old_fetch_inferior_registers (struct regcache *regcache, int regno)
0280a90a
AS
145{
146 if (regno >= 0)
147 {
56be3814 148 fetch_register (regcache, regno);
0280a90a
AS
149 }
150 else
151 {
c984b7ff 152 for (regno = 0;
ac7936df 153 regno < gdbarch_num_regs (regcache->arch ());
c984b7ff 154 regno++)
0280a90a 155 {
56be3814 156 fetch_register (regcache, regno);
0280a90a
AS
157 }
158 }
159}
160
025bb325 161/* Store one register. */
0280a90a
AS
162
163static void
56be3814 164store_register (const struct regcache *regcache, int regno)
0280a90a 165{
ac7936df 166 struct gdbarch *gdbarch = regcache->arch ();
89e028e2 167 long regaddr, val;
52f0bd74 168 int i;
975c21ab 169 gdb_byte buf[M68K_MAX_REGISTER_SIZE];
222312d3 170 pid_t tid = get_ptrace_pid (regcache->ptid ());
0280a90a 171
de732108 172 regaddr = 4 * regmap[regno];
9852326a 173
025bb325 174 /* Put the contents of regno into a local buffer. */
34a79281 175 regcache->raw_collect (regno, buf);
9852326a 176
025bb325 177 /* Store the local buffer into the inferior a chunk at the time. */
335d71d6 178 for (i = 0; i < register_size (gdbarch, regno); i += sizeof (long))
0280a90a
AS
179 {
180 errno = 0;
89e028e2
AS
181 memcpy (&val, &buf[i], sizeof (long));
182 ptrace (PTRACE_POKEUSER, tid, regaddr, val);
335d71d6 183 regaddr += sizeof (long);
0280a90a 184 if (errno != 0)
335d71d6
AS
185 error (_("Couldn't write register %s (#%d): %s."),
186 gdbarch_register_name (gdbarch, regno),
187 regno, safe_strerror (errno));
0280a90a
AS
188 }
189}
190
191/* Store our register values back into the inferior.
192 If REGNO is negative, do this for all registers.
193 Otherwise, REGNO specifies which register (so we can save time). */
194
10d6c8cd 195static void
56be3814 196old_store_inferior_registers (const struct regcache *regcache, int regno)
0280a90a
AS
197{
198 if (regno >= 0)
199 {
56be3814 200 store_register (regcache, regno);
0280a90a
AS
201 }
202 else
203 {
c984b7ff 204 for (regno = 0;
ac7936df 205 regno < gdbarch_num_regs (regcache->arch ());
c984b7ff 206 regno++)
0280a90a 207 {
56be3814 208 store_register (regcache, regno);
0280a90a
AS
209 }
210 }
211}
212\f
f175af98
DJ
213/* Given a pointer to a general register set in /proc format
214 (elf_gregset_t *), unpack the register contents and supply
025bb325 215 them as gdb's idea of the current register values. */
c906108c 216
c906108c 217void
7f7fe91e 218supply_gregset (struct regcache *regcache, const elf_gregset_t *gregsetp)
c906108c 219{
ac7936df 220 struct gdbarch *gdbarch = regcache->arch ();
7f7fe91e 221 const elf_greg_t *regp = (const elf_greg_t *) gregsetp;
c906108c
SS
222 int regi;
223
3e8c568d 224 for (regi = M68K_D0_REGNUM;
c984b7ff 225 regi <= gdbarch_sp_regnum (gdbarch);
3e8c568d 226 regi++)
73e1c03f
SM
227 regcache->raw_supply (regi, &regp[regmap[regi]]);
228 regcache->raw_supply (gdbarch_ps_regnum (gdbarch), &regp[PT_SR]);
229 regcache->raw_supply (gdbarch_pc_regnum (gdbarch), &regp[PT_PC]);
0280a90a
AS
230}
231
232/* Fill register REGNO (if it is a general-purpose register) in
233 *GREGSETPS with the value in GDB's register array. If REGNO is -1,
234 do this for all registers. */
235void
7f7fe91e
UW
236fill_gregset (const struct regcache *regcache,
237 elf_gregset_t *gregsetp, int regno)
0280a90a
AS
238{
239 elf_greg_t *regp = (elf_greg_t *) gregsetp;
240 int i;
241
242 for (i = 0; i < NUM_GREGS; i++)
8de307e0 243 if (regno == -1 || regno == i)
34a79281 244 regcache->raw_collect (i, regp + regmap[i]);
0280a90a
AS
245}
246
247#ifdef HAVE_PTRACE_GETREGS
248
249/* Fetch all general-purpose registers from process/thread TID and
250 store their values in GDB's register array. */
251
252static void
56be3814 253fetch_regs (struct regcache *regcache, int tid)
0280a90a
AS
254{
255 elf_gregset_t regs;
256
257 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
258 {
259 if (errno == EIO)
260 {
261 /* The kernel we're running on doesn't support the GETREGS
dda83cd7 262 request. Reset `have_ptrace_getregs'. */
0280a90a
AS
263 have_ptrace_getregs = 0;
264 return;
265 }
266
e2e0b3e5 267 perror_with_name (_("Couldn't get registers"));
0280a90a
AS
268 }
269
56be3814 270 supply_gregset (regcache, (const elf_gregset_t *) &regs);
c906108c
SS
271}
272
0280a90a
AS
273/* Store all valid general-purpose registers in GDB's register array
274 into the process/thread specified by TID. */
275
276static void
56be3814 277store_regs (const struct regcache *regcache, int tid, int regno)
0280a90a
AS
278{
279 elf_gregset_t regs;
280
281 if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 282 perror_with_name (_("Couldn't get registers"));
0280a90a 283
56be3814 284 fill_gregset (regcache, &regs, regno);
0280a90a
AS
285
286 if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
e2e0b3e5 287 perror_with_name (_("Couldn't write registers"));
0280a90a
AS
288}
289
290#else
291
025bb325
MS
292static void fetch_regs (struct regcache *regcache, int tid)
293{
294}
295
296static void store_regs (const struct regcache *regcache, int tid, int regno)
297{
298}
0280a90a
AS
299
300#endif
301
302\f
303/* Transfering floating-point registers between GDB, inferiors and cores. */
304
305/* What is the address of fpN within the floating-point register set F? */
7f7fe91e 306#define FPREG_ADDR(f, n) (&(f)->fpregs[(n) * 3])
0280a90a
AS
307
308/* Fill GDB's register array with the floating-point register values in
309 *FPREGSETP. */
c906108c 310
c5aa993b 311void
7f7fe91e 312supply_fpregset (struct regcache *regcache, const elf_fpregset_t *fpregsetp)
c906108c 313{
ac7936df 314 struct gdbarch *gdbarch = regcache->arch ();
c906108c
SS
315 int regi;
316
c984b7ff
UW
317 for (regi = gdbarch_fp0_regnum (gdbarch);
318 regi < gdbarch_fp0_regnum (gdbarch) + 8; regi++)
73e1c03f
SM
319 regcache->raw_supply
320 (regi, FPREG_ADDR (fpregsetp, regi - gdbarch_fp0_regnum (gdbarch)));
321 regcache->raw_supply (M68K_FPC_REGNUM, &fpregsetp->fpcntl[0]);
322 regcache->raw_supply (M68K_FPS_REGNUM, &fpregsetp->fpcntl[1]);
323 regcache->raw_supply (M68K_FPI_REGNUM, &fpregsetp->fpcntl[2]);
c906108c
SS
324}
325
0280a90a
AS
326/* Fill register REGNO (if it is a floating-point register) in
327 *FPREGSETP with the value in GDB's register array. If REGNO is -1,
328 do this for all registers. */
329
330void
7f7fe91e
UW
331fill_fpregset (const struct regcache *regcache,
332 elf_fpregset_t *fpregsetp, int regno)
0280a90a 333{
ac7936df 334 struct gdbarch *gdbarch = regcache->arch ();
0280a90a
AS
335 int i;
336
337 /* Fill in the floating-point registers. */
c984b7ff
UW
338 for (i = gdbarch_fp0_regnum (gdbarch);
339 i < gdbarch_fp0_regnum (gdbarch) + 8; i++)
0280a90a 340 if (regno == -1 || regno == i)
34a79281
SM
341 regcache->raw_collect
342 (i, FPREG_ADDR (fpregsetp, i - gdbarch_fp0_regnum (gdbarch)));
0280a90a
AS
343
344 /* Fill in the floating-point control registers. */
32eeb91a 345 for (i = M68K_FPC_REGNUM; i <= M68K_FPI_REGNUM; i++)
0280a90a 346 if (regno == -1 || regno == i)
34a79281 347 regcache->raw_collect (i, &fpregsetp->fpcntl[i - M68K_FPC_REGNUM]);
0280a90a
AS
348}
349
350#ifdef HAVE_PTRACE_GETREGS
351
352/* Fetch all floating-point registers from process/thread TID and store
353 thier values in GDB's register array. */
354
355static void
56be3814 356fetch_fpregs (struct regcache *regcache, int tid)
0280a90a
AS
357{
358 elf_fpregset_t fpregs;
359
360 if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 361 perror_with_name (_("Couldn't get floating point status"));
0280a90a 362
56be3814 363 supply_fpregset (regcache, (const elf_fpregset_t *) &fpregs);
0280a90a
AS
364}
365
366/* Store all valid floating-point registers in GDB's register array
367 into the process/thread specified by TID. */
368
369static void
56be3814 370store_fpregs (const struct regcache *regcache, int tid, int regno)
0280a90a
AS
371{
372 elf_fpregset_t fpregs;
373
374 if (ptrace (PTRACE_GETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 375 perror_with_name (_("Couldn't get floating point status"));
0280a90a 376
56be3814 377 fill_fpregset (regcache, &fpregs, regno);
0280a90a
AS
378
379 if (ptrace (PTRACE_SETFPREGS, tid, 0, (int) &fpregs) < 0)
e2e0b3e5 380 perror_with_name (_("Couldn't write floating point status"));
0280a90a
AS
381}
382
383#else
384
025bb325
MS
385static void fetch_fpregs (struct regcache *regcache, int tid)
386{
387}
388
389static void store_fpregs (const struct regcache *regcache, int tid, int regno)
390{
391}
0280a90a 392
c906108c 393#endif
0280a90a
AS
394\f
395/* Transferring arbitrary registers between GDB and inferior. */
396
397/* Fetch register REGNO from the child process. If REGNO is -1, do
398 this for all registers (including the floating point and SSE
399 registers). */
400
f6ac5f3d
PA
401void
402m68k_linux_nat_target::fetch_registers (struct regcache *regcache, int regno)
0280a90a 403{
bcc0c096 404 pid_t tid;
0280a90a
AS
405
406 /* Use the old method of peeking around in `struct user' if the
407 GETREGS request isn't available. */
408 if (! have_ptrace_getregs)
409 {
56be3814 410 old_fetch_inferior_registers (regcache, regno);
0280a90a
AS
411 return;
412 }
413
222312d3 414 tid = get_ptrace_pid (regcache->ptid ());
f175af98 415
0280a90a
AS
416 /* Use the PTRACE_GETFPXREGS request whenever possible, since it
417 transfers more registers in one system call, and we'll cache the
418 results. But remember that fetch_fpxregs can fail, and return
419 zero. */
420 if (regno == -1)
421 {
56be3814 422 fetch_regs (regcache, tid);
0280a90a
AS
423
424 /* The call above might reset `have_ptrace_getregs'. */
425 if (! have_ptrace_getregs)
426 {
56be3814 427 old_fetch_inferior_registers (regcache, -1);
0280a90a
AS
428 return;
429 }
430
56be3814 431 fetch_fpregs (regcache, tid);
0280a90a
AS
432 return;
433 }
434
435 if (getregs_supplies (regno))
436 {
56be3814 437 fetch_regs (regcache, tid);
0280a90a
AS
438 return;
439 }
440
441 if (getfpregs_supplies (regno))
442 {
56be3814 443 fetch_fpregs (regcache, tid);
0280a90a
AS
444 return;
445 }
446
f34652de 447 internal_error (_("Got request for bad register number %d."), regno);
0280a90a
AS
448}
449
450/* Store register REGNO back into the child process. If REGNO is -1,
451 do this for all registers (including the floating point and SSE
452 registers). */
f6ac5f3d
PA
453void
454m68k_linux_nat_target::store_registers (struct regcache *regcache, int regno)
0280a90a 455{
bcc0c096 456 pid_t tid;
0280a90a
AS
457
458 /* Use the old method of poking around in `struct user' if the
459 SETREGS request isn't available. */
460 if (! have_ptrace_getregs)
461 {
56be3814 462 old_store_inferior_registers (regcache, regno);
0280a90a
AS
463 return;
464 }
465
222312d3 466 tid = get_ptrace_pid (regcache->ptid ());
0280a90a
AS
467
468 /* Use the PTRACE_SETFPREGS requests whenever possible, since it
469 transfers more registers in one system call. But remember that
470 store_fpregs can fail, and return zero. */
471 if (regno == -1)
472 {
56be3814
UW
473 store_regs (regcache, tid, regno);
474 store_fpregs (regcache, tid, regno);
0280a90a
AS
475 return;
476 }
477
478 if (getregs_supplies (regno))
479 {
56be3814 480 store_regs (regcache, tid, regno);
0280a90a
AS
481 return;
482 }
483
484 if (getfpregs_supplies (regno))
485 {
56be3814 486 store_fpregs (regcache, tid, regno);
0280a90a
AS
487 return;
488 }
489
f34652de 490 internal_error (_("Got request to store bad register number %d."), regno);
0280a90a 491}
f175af98 492\f
c5aa993b 493
7b8b6d6d
AS
494/* Fetch the thread-local storage pointer for libthread_db. */
495
496ps_err_e
754653a7 497ps_get_thread_area (struct ps_prochandle *ph,
7b8b6d6d
AS
498 lwpid_t lwpid, int idx, void **base)
499{
500 if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) < 0)
501 return PS_ERR;
502
503 /* IDX is the bias from the thread pointer to the beginning of the
504 thread descriptor. It has to be subtracted due to implementation
505 quirks in libthread_db. */
506 *base = (char *) *base - idx;
507
508 return PS_OK;
509}
10d6c8cd 510
6c265988 511void _initialize_m68k_linux_nat ();
f175af98 512void
6c265988 513_initialize_m68k_linux_nat ()
f175af98 514{
10d6c8cd 515 /* Register the target. */
f6ac5f3d 516 linux_target = &the_m68k_linux_nat_target;
d9f719f1 517 add_inf_child_target (&the_m68k_linux_nat_target);
f175af98 518}