1 /* GNU/Linux on ARM native support.
2 Copyright 1999, 2000 Free Software Foundation, Inc.
4 This file is part of GDB.
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
24 #include "gdb_string.h"
27 #include <sys/ptrace.h>
28 #include <sys/utsname.h>
29 #include <sys/procfs.h>
31 extern int arm_apcs_32;
34 #define typeSingle 0x01
35 #define typeDouble 0x02
36 #define typeExtended 0x03
38 #define CPSR_REGNUM 16
40 typedef union tagFPREG
43 unsigned int fDouble[2];
44 unsigned int fExtended[3];
48 typedef struct tagFPA11
50 FPREG fpreg[8]; /* 8 floating point registers */
51 unsigned int fpsr; /* floating point status register */
52 unsigned int fpcr; /* floating point control register */
53 unsigned char fType[8]; /* type of floating point value held in
54 floating point registers. */
55 int initflag; /* NWFPE initialization flag. */
59 /* The following variables are used to determine the version of the
60 underlying Linux operating system. Examples:
62 Linux 2.0.35 Linux 2.2.12
63 os_version = 0x00020023 os_version = 0x0002020c
64 os_major = 2 os_major = 2
65 os_minor = 0 os_minor = 2
66 os_release = 35 os_release = 12
68 Note: os_version = (os_major << 16) | (os_minor << 8) | os_release
70 These are initialized using get_linux_version() from
71 _initialize_arm_linux_nat(). */
73 static unsigned int os_version, os_major, os_minor, os_release;
75 /* On Linux, threads are implemented as pseudo-processes, in which
76 case we may be tracing more than one process at a time. In that
77 case, inferior_pid will contain the main process ID and the
78 individual thread (process) ID mashed together. These macros are
79 used to separate them out. These definitions should be overridden
80 if thread support is included. */
82 #if !defined (PIDGET) /* Default definition for PIDGET/TIDGET. */
83 #define PIDGET(PID) PID
88 get_thread_id (int inferior_pid)
90 int tid = TIDGET (inferior_pid);
91 if (0 == tid) tid = inferior_pid;
94 #define GET_THREAD_ID(PID) get_thread_id ((PID));
97 fetch_nwfpe_single (unsigned int fn, FPA11 * fpa11)
101 mem[0] = fpa11->fpreg[fn].fSingle;
104 supply_register (F0_REGNUM + fn, (char *) &mem[0]);
108 fetch_nwfpe_double (unsigned int fn, FPA11 * fpa11)
112 mem[0] = fpa11->fpreg[fn].fDouble[1];
113 mem[1] = fpa11->fpreg[fn].fDouble[0];
115 supply_register (F0_REGNUM + fn, (char *) &mem[0]);
119 fetch_nwfpe_none (unsigned int fn)
121 unsigned int mem[3] =
124 supply_register (F0_REGNUM + fn, (char *) &mem[0]);
128 fetch_nwfpe_extended (unsigned int fn, FPA11 * fpa11)
132 mem[0] = fpa11->fpreg[fn].fExtended[0]; /* sign & exponent */
133 mem[1] = fpa11->fpreg[fn].fExtended[2]; /* ls bits */
134 mem[2] = fpa11->fpreg[fn].fExtended[1]; /* ms bits */
135 supply_register (F0_REGNUM + fn, (char *) &mem[0]);
139 fetch_nwfpe_register (int regno, FPA11 * fpa11)
141 int fn = regno - F0_REGNUM;
143 switch (fpa11->fType[fn])
146 fetch_nwfpe_single (fn, fpa11);
150 fetch_nwfpe_double (fn, fpa11);
154 fetch_nwfpe_extended (fn, fpa11);
158 fetch_nwfpe_none (fn);
163 store_nwfpe_single (unsigned int fn, FPA11 * fpa11)
167 read_register_gen (F0_REGNUM + fn, (char *) &mem[0]);
168 fpa11->fpreg[fn].fSingle = mem[0];
169 fpa11->fType[fn] = typeSingle;
173 store_nwfpe_double (unsigned int fn, FPA11 * fpa11)
177 read_register_gen (F0_REGNUM + fn, (char *) &mem[0]);
178 fpa11->fpreg[fn].fDouble[1] = mem[0];
179 fpa11->fpreg[fn].fDouble[0] = mem[1];
180 fpa11->fType[fn] = typeDouble;
184 store_nwfpe_extended (unsigned int fn, FPA11 * fpa11)
188 read_register_gen (F0_REGNUM + fn, (char *) &mem[0]);
189 fpa11->fpreg[fn].fExtended[0] = mem[0]; /* sign & exponent */
190 fpa11->fpreg[fn].fExtended[2] = mem[1]; /* ls bits */
191 fpa11->fpreg[fn].fExtended[1] = mem[2]; /* ms bits */
192 fpa11->fType[fn] = typeDouble;
196 store_nwfpe_register (int regno, FPA11 * fpa11)
198 if (register_valid[regno])
200 unsigned int fn = regno - F0_REGNUM;
201 switch (fpa11->fType[fn])
204 store_nwfpe_single (fn, fpa11);
208 store_nwfpe_double (fn, fpa11);
212 store_nwfpe_extended (fn, fpa11);
219 /* Get the value of a particular register from the floating point
220 state of the process and store it into registers[]. */
223 fetch_fpregister (int regno)
228 /* Get the thread id for the ptrace call. */
229 tid = GET_THREAD_ID (inferior_pid);
231 /* Read the floating point state. */
232 ret = ptrace (PT_GETFPREGS, tid, 0, &fp);
235 warning ("Unable to fetch floating point register.");
240 if (FPS_REGNUM == regno)
241 supply_register (FPS_REGNUM, (char *) &fp.fpsr);
243 /* Fetch the floating point register. */
244 if (regno >= F0_REGNUM && regno <= F7_REGNUM)
246 int fn = regno - F0_REGNUM;
248 switch (fp.fType[fn])
251 fetch_nwfpe_single (fn, &fp);
255 fetch_nwfpe_double (fn, &fp);
259 fetch_nwfpe_extended (fn, &fp);
263 fetch_nwfpe_none (fn);
268 /* Get the whole floating point state of the process and store it
277 /* Get the thread id for the ptrace call. */
278 tid = GET_THREAD_ID (inferior_pid);
280 /* Read the floating point state. */
281 ret = ptrace (PT_GETFPREGS, tid, 0, &fp);
284 warning ("Unable to fetch the floating point registers.");
289 supply_register (FPS_REGNUM, (char *) &fp.fpsr);
291 /* Fetch the floating point registers. */
292 for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++)
294 int fn = regno - F0_REGNUM;
296 switch (fp.fType[fn])
299 fetch_nwfpe_single (fn, &fp);
303 fetch_nwfpe_double (fn, &fp);
307 fetch_nwfpe_extended (fn, &fp);
311 fetch_nwfpe_none (fn);
316 /* Save a particular register into the floating point state of the
317 process using the contents from registers[]. */
320 store_fpregister (int regno)
325 /* Get the thread id for the ptrace call. */
326 tid = GET_THREAD_ID (inferior_pid);
328 /* Read the floating point state. */
329 ret = ptrace (PT_GETFPREGS, tid, 0, &fp);
332 warning ("Unable to fetch the floating point registers.");
337 if (FPS_REGNUM == regno && register_valid[FPS_REGNUM])
338 read_register_gen (FPS_REGNUM, (char *) &fp.fpsr);
340 /* Store the floating point register. */
341 if (regno >= F0_REGNUM && regno <= F7_REGNUM)
343 store_nwfpe_register (regno, &fp);
346 ret = ptrace (PTRACE_SETFPREGS, tid, 0, &fp);
349 warning ("Unable to store floating point register.");
354 /* Save the whole floating point state of the process using
355 the contents from registers[]. */
363 /* Get the thread id for the ptrace call. */
364 tid = GET_THREAD_ID (inferior_pid);
366 /* Read the floating point state. */
367 ret = ptrace (PT_GETFPREGS, tid, 0, &fp);
370 warning ("Unable to fetch the floating point registers.");
375 if (register_valid[FPS_REGNUM])
376 read_register_gen (FPS_REGNUM, (char *) &fp.fpsr);
378 /* Store the floating point registers. */
379 for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++)
381 fetch_nwfpe_register (regno, &fp);
384 ret = ptrace (PTRACE_SETFPREGS, tid, 0, &fp);
387 warning ("Unable to store floating point registers.");
392 /* Fetch a general register of the process and store into
396 fetch_register (int regno)
401 /* Get the thread id for the ptrace call. */
402 tid = GET_THREAD_ID (inferior_pid);
404 ret = ptrace (PTRACE_GETREGS, tid, 0, ®s);
407 warning ("Unable to fetch general register.");
411 if (regno >= A1_REGNUM && regno < PC_REGNUM)
412 supply_register (regno, (char *) ®s.uregs[regno]);
414 if (PS_REGNUM == regno)
417 supply_register (PS_REGNUM, (char *) ®s.uregs[CPSR_REGNUM]);
419 supply_register (PS_REGNUM, (char *) ®s.uregs[PC_REGNUM]);
422 if (PC_REGNUM == regno)
424 regs.uregs[PC_REGNUM] = ADDR_BITS_REMOVE (regs.uregs[PC_REGNUM]);
425 supply_register (PC_REGNUM, (char *) ®s.uregs[PC_REGNUM]);
429 /* Fetch all general registers of the process and store into
438 /* Get the thread id for the ptrace call. */
439 tid = GET_THREAD_ID (inferior_pid);
441 ret = ptrace (PTRACE_GETREGS, tid, 0, ®s);
444 warning ("Unable to fetch general registers.");
448 for (regno = A1_REGNUM; regno < PC_REGNUM; regno++)
449 supply_register (regno, (char *) ®s.uregs[regno]);
452 supply_register (PS_REGNUM, (char *) ®s.uregs[CPSR_REGNUM]);
454 supply_register (PS_REGNUM, (char *) ®s.uregs[PC_REGNUM]);
456 regs.uregs[PC_REGNUM] = ADDR_BITS_REMOVE (regs.uregs[PC_REGNUM]);
457 supply_register (PC_REGNUM, (char *) ®s.uregs[PC_REGNUM]);
460 /* Store all general registers of the process from the values in
464 store_register (int regno)
469 if (!register_valid[regno])
472 /* Get the thread id for the ptrace call. */
473 tid = GET_THREAD_ID (inferior_pid);
475 /* Get the general registers from the process. */
476 ret = ptrace (PTRACE_GETREGS, tid, 0, ®s);
479 warning ("Unable to fetch general registers.");
483 if (regno >= A1_REGNUM && regno <= PC_REGNUM)
484 read_register_gen (regno, (char *) ®s.uregs[regno]);
486 ret = ptrace (PTRACE_SETREGS, tid, 0, ®s);
489 warning ("Unable to store general register.");
500 /* Get the thread id for the ptrace call. */
501 tid = GET_THREAD_ID (inferior_pid);
503 /* Fetch the general registers. */
504 ret = ptrace (PTRACE_GETREGS, tid, 0, ®s);
507 warning ("Unable to fetch general registers.");
511 for (regno = A1_REGNUM; regno <= PC_REGNUM; regno++)
513 if (register_valid[regno])
514 read_register_gen (regno, (char *) ®s.uregs[regno]);
517 ret = ptrace (PTRACE_SETREGS, tid, 0, ®s);
521 warning ("Unable to store general registers.");
526 /* Fetch registers from the child process. Fetch all registers if
527 regno == -1, otherwise fetch all general registers or all floating
528 point registers depending upon the value of regno. */
531 fetch_inferior_registers (int regno)
540 if (regno < F0_REGNUM || regno > FPS_REGNUM)
541 fetch_register (regno);
543 if (regno >= F0_REGNUM && regno <= FPS_REGNUM)
544 fetch_fpregister (regno);
548 /* Store registers back into the inferior. Store all registers if
549 regno == -1, otherwise store all general registers or all floating
550 point registers depending upon the value of regno. */
553 store_inferior_registers (int regno)
562 if ((regno < F0_REGNUM) || (regno > FPS_REGNUM))
563 store_register (regno);
565 if ((regno >= F0_REGNUM) && (regno <= FPS_REGNUM))
566 store_fpregister (regno);
570 /* Fill register regno (if it is a general-purpose register) in
571 *gregsetp with the appropriate value from GDB's register array.
572 If regno is -1, do this for all registers. */
575 fill_gregset (gregset_t *gregsetp, int regno)
580 for (regnum = A1_REGNUM; regnum <= PC_REGNUM; regnum++)
581 if (register_valid[regnum])
582 read_register_gen (regnum, (char *) &(*gregsetp)[regnum]);
584 else if (regno >= A1_REGNUM && regno <= PC_REGNUM)
586 if (register_valid[regno])
587 read_register_gen (regno, (char *) &(*gregsetp)[regno]);
590 if (PS_REGNUM == regno || -1 == regno)
592 if (register_valid[regno] || -1 == regno)
595 read_register_gen (PS_REGNUM, (char *) &(*gregsetp)[CPSR_REGNUM]);
597 read_register_gen (PC_REGNUM, (char *) &(*gregsetp)[PC_REGNUM]);
603 /* Fill GDB's register array with the general-purpose register values
607 supply_gregset (gregset_t *gregsetp)
611 for (regno = A1_REGNUM; regno < PC_REGNUM; regno++)
612 supply_register (regno, (char *) &(*gregsetp)[regno]);
615 supply_register (PS_REGNUM, (char *) &(*gregsetp)[CPSR_REGNUM]);
617 supply_register (PS_REGNUM, (char *) &(*gregsetp)[PC_REGNUM]);
619 reg_pc = ADDR_BITS_REMOVE ((CORE_ADDR)(*gregsetp)[PC_REGNUM]);
620 supply_register (PC_REGNUM, (char *) ®_pc);
623 /* Fill register regno (if it is a floating-point register) in
624 *fpregsetp with the appropriate value from GDB's register array.
625 If regno is -1, do this for all registers. */
628 fill_fpregset (fpregset_t *fpregsetp, int regno)
630 FPA11 *fp = (FPA11 *) fpregsetp;
635 for (regnum = F0_REGNUM; regnum <= F7_REGNUM; regnum++)
636 store_nwfpe_register (regnum, fp);
638 else if (regno >= F0_REGNUM && regno <= F7_REGNUM)
640 store_nwfpe_register (regno, fp);
645 if (register_valid[FPS_REGNUM])
646 if (FPS_REGNUM == regno || -1 == regno)
647 read_register_gen (FPS_REGNUM, (char *) &fp->fpsr);
650 /* Fill GDB's register array with the floating-point register values
654 supply_fpregset (fpregset_t *fpregsetp)
657 FPA11 *fp = (FPA11 *) fpregsetp;
660 supply_register (FPS_REGNUM, (char *) &fp->fpsr);
662 /* Fetch the floating point registers. */
663 for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++)
665 fetch_nwfpe_register (regno, fp);
670 arm_linux_kernel_u_size (void)
672 return (sizeof (struct user));
676 get_linux_version (unsigned int *vmajor,
677 unsigned int *vminor,
678 unsigned int *vrelease)
681 char *pmajor, *pminor, *prelease, *tail;
683 if (-1 == uname (&info))
685 warning ("Unable to determine Linux version.");
689 pmajor = strtok (info.release, ".");
690 pminor = strtok (NULL, ".");
691 prelease = strtok (NULL, ".");
693 *vmajor = (unsigned int) strtoul (pmajor, &tail, 0);
694 *vminor = (unsigned int) strtoul (pminor, &tail, 0);
695 *vrelease = (unsigned int) strtoul (prelease, &tail, 0);
697 return ((*vmajor << 16) | (*vminor << 8) | *vrelease);
701 _initialize_arm_linux_nat (void)
703 os_version = get_linux_version (&os_major, &os_minor, &os_release);