diff options
Diffstat (limited to 'gdb/arm-linux-nat.c')
-rw-r--r-- | gdb/arm-linux-nat.c | 694 |
1 files changed, 0 insertions, 694 deletions
diff --git a/gdb/arm-linux-nat.c b/gdb/arm-linux-nat.c deleted file mode 100644 index 4d3249167f2..00000000000 --- a/gdb/arm-linux-nat.c +++ /dev/null @@ -1,694 +0,0 @@ -/* GNU/Linux on ARM native support. - Copyright 1999, 2000, 2001 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 2 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, write to the Free Software - Foundation, Inc., 59 Temple Place - Suite 330, - Boston, MA 02111-1307, USA. */ - -#include "defs.h" -#include "inferior.h" -#include "gdbcore.h" -#include "gdb_string.h" -#include "regcache.h" - -#include <sys/user.h> -#include <sys/ptrace.h> -#include <sys/utsname.h> -#include <sys/procfs.h> - -/* Prototypes for supply_gregset etc. */ -#include "gregset.h" - -extern int arm_apcs_32; - -#define typeNone 0x00 -#define typeSingle 0x01 -#define typeDouble 0x02 -#define typeExtended 0x03 -#define FPWORDS 28 -#define CPSR_REGNUM 16 - -typedef union tagFPREG - { - unsigned int fSingle; - unsigned int fDouble[2]; - unsigned int fExtended[3]; - } -FPREG; - -typedef struct tagFPA11 - { - FPREG fpreg[8]; /* 8 floating point registers */ - unsigned int fpsr; /* floating point status register */ - unsigned int fpcr; /* floating point control register */ - unsigned char fType[8]; /* type of floating point value held in - floating point registers. */ - int initflag; /* NWFPE initialization flag. */ - } -FPA11; - -/* The following variables are used to determine the version of the - underlying Linux operating system. Examples: - - Linux 2.0.35 Linux 2.2.12 - os_version = 0x00020023 os_version = 0x0002020c - os_major = 2 os_major = 2 - os_minor = 0 os_minor = 2 - os_release = 35 os_release = 12 - - Note: os_version = (os_major << 16) | (os_minor << 8) | os_release - - These are initialized using get_linux_version() from - _initialize_arm_linux_nat(). */ - -static unsigned int os_version, os_major, os_minor, os_release; - -/* On Linux, threads are implemented as pseudo-processes, in which - case we may be tracing more than one process at a time. In that - case, inferior_ptid will contain the main process ID and the - individual thread (process) ID. get_thread_id () is used to - get the thread id if it's available, and the process id otherwise. */ - -int -get_thread_id (ptid_t ptid) -{ - int tid = TIDGET (ptid); - if (0 == tid) - tid = PIDGET (ptid); - return tid; -} -#define GET_THREAD_ID(PTID) get_thread_id ((PTID)); - -static void -fetch_nwfpe_single (unsigned int fn, FPA11 * fpa11) -{ - unsigned int mem[3]; - - mem[0] = fpa11->fpreg[fn].fSingle; - mem[1] = 0; - mem[2] = 0; - supply_register (F0_REGNUM + fn, (char *) &mem[0]); -} - -static void -fetch_nwfpe_double (unsigned int fn, FPA11 * fpa11) -{ - unsigned int mem[3]; - - mem[0] = fpa11->fpreg[fn].fDouble[1]; - mem[1] = fpa11->fpreg[fn].fDouble[0]; - mem[2] = 0; - supply_register (F0_REGNUM + fn, (char *) &mem[0]); -} - -static void -fetch_nwfpe_none (unsigned int fn) -{ - unsigned int mem[3] = - {0, 0, 0}; - - supply_register (F0_REGNUM + fn, (char *) &mem[0]); -} - -static void -fetch_nwfpe_extended (unsigned int fn, FPA11 * fpa11) -{ - unsigned int mem[3]; - - mem[0] = fpa11->fpreg[fn].fExtended[0]; /* sign & exponent */ - mem[1] = fpa11->fpreg[fn].fExtended[2]; /* ls bits */ - mem[2] = fpa11->fpreg[fn].fExtended[1]; /* ms bits */ - supply_register (F0_REGNUM + fn, (char *) &mem[0]); -} - -static void -fetch_nwfpe_register (int regno, FPA11 * fpa11) -{ - int fn = regno - F0_REGNUM; - - switch (fpa11->fType[fn]) - { - case typeSingle: - fetch_nwfpe_single (fn, fpa11); - break; - - case typeDouble: - fetch_nwfpe_double (fn, fpa11); - break; - - case typeExtended: - fetch_nwfpe_extended (fn, fpa11); - break; - - default: - fetch_nwfpe_none (fn); - } -} - -static void -store_nwfpe_single (unsigned int fn, FPA11 * fpa11) -{ - unsigned int mem[3]; - - read_register_gen (F0_REGNUM + fn, (char *) &mem[0]); - fpa11->fpreg[fn].fSingle = mem[0]; - fpa11->fType[fn] = typeSingle; -} - -static void -store_nwfpe_double (unsigned int fn, FPA11 * fpa11) -{ - unsigned int mem[3]; - - read_register_gen (F0_REGNUM + fn, (char *) &mem[0]); - fpa11->fpreg[fn].fDouble[1] = mem[0]; - fpa11->fpreg[fn].fDouble[0] = mem[1]; - fpa11->fType[fn] = typeDouble; -} - -void -store_nwfpe_extended (unsigned int fn, FPA11 * fpa11) -{ - unsigned int mem[3]; - - read_register_gen (F0_REGNUM + fn, (char *) &mem[0]); - fpa11->fpreg[fn].fExtended[0] = mem[0]; /* sign & exponent */ - fpa11->fpreg[fn].fExtended[2] = mem[1]; /* ls bits */ - fpa11->fpreg[fn].fExtended[1] = mem[2]; /* ms bits */ - fpa11->fType[fn] = typeDouble; -} - -void -store_nwfpe_register (int regno, FPA11 * fpa11) -{ - if (register_cached (regno)) - { - unsigned int fn = regno - F0_REGNUM; - switch (fpa11->fType[fn]) - { - case typeSingle: - store_nwfpe_single (fn, fpa11); - break; - - case typeDouble: - store_nwfpe_double (fn, fpa11); - break; - - case typeExtended: - store_nwfpe_extended (fn, fpa11); - break; - } - } -} - - -/* Get the value of a particular register from the floating point - state of the process and store it into regcache. */ - -static void -fetch_fpregister (int regno) -{ - int ret, tid; - FPA11 fp; - - /* Get the thread id for the ptrace call. */ - tid = GET_THREAD_ID (inferior_ptid); - - /* Read the floating point state. */ - ret = ptrace (PT_GETFPREGS, tid, 0, &fp); - if (ret < 0) - { - warning ("Unable to fetch floating point register."); - return; - } - - /* Fetch fpsr. */ - if (FPS_REGNUM == regno) - supply_register (FPS_REGNUM, (char *) &fp.fpsr); - - /* Fetch the floating point register. */ - if (regno >= F0_REGNUM && regno <= F7_REGNUM) - { - int fn = regno - F0_REGNUM; - - switch (fp.fType[fn]) - { - case typeSingle: - fetch_nwfpe_single (fn, &fp); - break; - - case typeDouble: - fetch_nwfpe_double (fn, &fp); - break; - - case typeExtended: - fetch_nwfpe_extended (fn, &fp); - break; - - default: - fetch_nwfpe_none (fn); - } - } -} - -/* Get the whole floating point state of the process and store it - into regcache. */ - -static void -fetch_fpregs (void) -{ - int ret, regno, tid; - FPA11 fp; - - /* Get the thread id for the ptrace call. */ - tid = GET_THREAD_ID (inferior_ptid); - - /* Read the floating point state. */ - ret = ptrace (PT_GETFPREGS, tid, 0, &fp); - if (ret < 0) - { - warning ("Unable to fetch the floating point registers."); - return; - } - - /* Fetch fpsr. */ - supply_register (FPS_REGNUM, (char *) &fp.fpsr); - - /* Fetch the floating point registers. */ - for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++) - { - int fn = regno - F0_REGNUM; - - switch (fp.fType[fn]) - { - case typeSingle: - fetch_nwfpe_single (fn, &fp); - break; - - case typeDouble: - fetch_nwfpe_double (fn, &fp); - break; - - case typeExtended: - fetch_nwfpe_extended (fn, &fp); - break; - - default: - fetch_nwfpe_none (fn); - } - } -} - -/* Save a particular register into the floating point state of the - process using the contents from regcache. */ - -static void -store_fpregister (int regno) -{ - int ret, tid; - FPA11 fp; - - /* Get the thread id for the ptrace call. */ - tid = GET_THREAD_ID (inferior_ptid); - - /* Read the floating point state. */ - ret = ptrace (PT_GETFPREGS, tid, 0, &fp); - if (ret < 0) - { - warning ("Unable to fetch the floating point registers."); - return; - } - - /* Store fpsr. */ - if (FPS_REGNUM == regno && register_cached (FPS_REGNUM)) - read_register_gen (FPS_REGNUM, (char *) &fp.fpsr); - - /* Store the floating point register. */ - if (regno >= F0_REGNUM && regno <= F7_REGNUM) - { - store_nwfpe_register (regno, &fp); - } - - ret = ptrace (PTRACE_SETFPREGS, tid, 0, &fp); - if (ret < 0) - { - warning ("Unable to store floating point register."); - return; - } -} - -/* Save the whole floating point state of the process using - the contents from regcache. */ - -static void -store_fpregs (void) -{ - int ret, regno, tid; - FPA11 fp; - - /* Get the thread id for the ptrace call. */ - tid = GET_THREAD_ID (inferior_ptid); - - /* Read the floating point state. */ - ret = ptrace (PT_GETFPREGS, tid, 0, &fp); - if (ret < 0) - { - warning ("Unable to fetch the floating point registers."); - return; - } - - /* Store fpsr. */ - if (register_cached (FPS_REGNUM)) - read_register_gen (FPS_REGNUM, (char *) &fp.fpsr); - - /* Store the floating point registers. */ - for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++) - { - fetch_nwfpe_register (regno, &fp); - } - - ret = ptrace (PTRACE_SETFPREGS, tid, 0, &fp); - if (ret < 0) - { - warning ("Unable to store floating point registers."); - return; - } -} - -/* Fetch a general register of the process and store into - regcache. */ - -static void -fetch_register (int regno) -{ - int ret, tid; - elf_gregset_t regs; - - /* Get the thread id for the ptrace call. */ - tid = GET_THREAD_ID (inferior_ptid); - - ret = ptrace (PTRACE_GETREGS, tid, 0, ®s); - if (ret < 0) - { - warning ("Unable to fetch general register."); - return; - } - - if (regno >= A1_REGNUM && regno < PC_REGNUM) - supply_register (regno, (char *) ®s[regno]); - - if (PS_REGNUM == regno) - { - if (arm_apcs_32) - supply_register (PS_REGNUM, (char *) ®s[CPSR_REGNUM]); - else - supply_register (PS_REGNUM, (char *) ®s[PC_REGNUM]); - } - - if (PC_REGNUM == regno) - { - regs[PC_REGNUM] = ADDR_BITS_REMOVE (regs[PC_REGNUM]); - supply_register (PC_REGNUM, (char *) ®s[PC_REGNUM]); - } -} - -/* Fetch all general registers of the process and store into - regcache. */ - -static void -fetch_regs (void) -{ - int ret, regno, tid; - elf_gregset_t regs; - - /* Get the thread id for the ptrace call. */ - tid = GET_THREAD_ID (inferior_ptid); - - ret = ptrace (PTRACE_GETREGS, tid, 0, ®s); - if (ret < 0) - { - warning ("Unable to fetch general registers."); - return; - } - - for (regno = A1_REGNUM; regno < PC_REGNUM; regno++) - supply_register (regno, (char *) ®s[regno]); - - if (arm_apcs_32) - supply_register (PS_REGNUM, (char *) ®s[CPSR_REGNUM]); - else - supply_register (PS_REGNUM, (char *) ®s[PC_REGNUM]); - - regs[PC_REGNUM] = ADDR_BITS_REMOVE (regs[PC_REGNUM]); - supply_register (PC_REGNUM, (char *) ®s[PC_REGNUM]); -} - -/* Store all general registers of the process from the values in - regcache. */ - -static void -store_register (int regno) -{ - int ret, tid; - elf_gregset_t regs; - - if (!register_cached (regno)) - return; - - /* Get the thread id for the ptrace call. */ - tid = GET_THREAD_ID (inferior_ptid); - - /* Get the general registers from the process. */ - ret = ptrace (PTRACE_GETREGS, tid, 0, ®s); - if (ret < 0) - { - warning ("Unable to fetch general registers."); - return; - } - - if (regno >= A1_REGNUM && regno <= PC_REGNUM) - read_register_gen (regno, (char *) ®s[regno]); - - ret = ptrace (PTRACE_SETREGS, tid, 0, ®s); - if (ret < 0) - { - warning ("Unable to store general register."); - return; - } -} - -static void -store_regs (void) -{ - int ret, regno, tid; - elf_gregset_t regs; - - /* Get the thread id for the ptrace call. */ - tid = GET_THREAD_ID (inferior_ptid); - - /* Fetch the general registers. */ - ret = ptrace (PTRACE_GETREGS, tid, 0, ®s); - if (ret < 0) - { - warning ("Unable to fetch general registers."); - return; - } - - for (regno = A1_REGNUM; regno <= PC_REGNUM; regno++) - { - if (register_cached (regno)) - read_register_gen (regno, (char *) ®s[regno]); - } - - ret = ptrace (PTRACE_SETREGS, tid, 0, ®s); - - if (ret < 0) - { - warning ("Unable to store general registers."); - return; - } -} - -/* Fetch registers from the child process. Fetch all registers if - regno == -1, otherwise fetch all general registers or all floating - point registers depending upon the value of regno. */ - -void -fetch_inferior_registers (int regno) -{ - if (-1 == regno) - { - fetch_regs (); - fetch_fpregs (); - } - else - { - if (regno < F0_REGNUM || regno > FPS_REGNUM) - fetch_register (regno); - - if (regno >= F0_REGNUM && regno <= FPS_REGNUM) - fetch_fpregister (regno); - } -} - -/* Store registers back into the inferior. Store all registers if - regno == -1, otherwise store all general registers or all floating - point registers depending upon the value of regno. */ - -void -store_inferior_registers (int regno) -{ - if (-1 == regno) - { - store_regs (); - store_fpregs (); - } - else - { - if ((regno < F0_REGNUM) || (regno > FPS_REGNUM)) - store_register (regno); - - if ((regno >= F0_REGNUM) && (regno <= FPS_REGNUM)) - store_fpregister (regno); - } -} - -/* Fill register regno (if it is a general-purpose register) in - *gregsetp with the appropriate value from GDB's register array. - If regno is -1, do this for all registers. */ - -void -fill_gregset (gdb_gregset_t *gregsetp, int regno) -{ - if (-1 == regno) - { - int regnum; - for (regnum = A1_REGNUM; regnum <= PC_REGNUM; regnum++) - read_register_gen (regnum, (char *) &(*gregsetp)[regnum]); - } - else if (regno >= A1_REGNUM && regno <= PC_REGNUM) - read_register_gen (regno, (char *) &(*gregsetp)[regno]); - - if (PS_REGNUM == regno || -1 == regno) - { - if (arm_apcs_32) - read_register_gen (PS_REGNUM, (char *) &(*gregsetp)[CPSR_REGNUM]); - else - read_register_gen (PC_REGNUM, (char *) &(*gregsetp)[PC_REGNUM]); - } -} - -/* Fill GDB's register array with the general-purpose register values - in *gregsetp. */ - -void -supply_gregset (gdb_gregset_t *gregsetp) -{ - int regno, reg_pc; - - for (regno = A1_REGNUM; regno < PC_REGNUM; regno++) - supply_register (regno, (char *) &(*gregsetp)[regno]); - - if (arm_apcs_32) - supply_register (PS_REGNUM, (char *) &(*gregsetp)[CPSR_REGNUM]); - else - supply_register (PS_REGNUM, (char *) &(*gregsetp)[PC_REGNUM]); - - reg_pc = ADDR_BITS_REMOVE ((CORE_ADDR)(*gregsetp)[PC_REGNUM]); - supply_register (PC_REGNUM, (char *) ®_pc); -} - -/* Fill register regno (if it is a floating-point register) in - *fpregsetp with the appropriate value from GDB's register array. - If regno is -1, do this for all registers. */ - -void -fill_fpregset (gdb_fpregset_t *fpregsetp, int regno) -{ - FPA11 *fp = (FPA11 *) fpregsetp; - - if (-1 == regno) - { - int regnum; - for (regnum = F0_REGNUM; regnum <= F7_REGNUM; regnum++) - store_nwfpe_register (regnum, fp); - } - else if (regno >= F0_REGNUM && regno <= F7_REGNUM) - { - store_nwfpe_register (regno, fp); - return; - } - - /* Store fpsr. */ - if (FPS_REGNUM == regno || -1 == regno) - read_register_gen (FPS_REGNUM, (char *) &fp->fpsr); -} - -/* Fill GDB's register array with the floating-point register values - in *fpregsetp. */ - -void -supply_fpregset (gdb_fpregset_t *fpregsetp) -{ - int regno; - FPA11 *fp = (FPA11 *) fpregsetp; - - /* Fetch fpsr. */ - supply_register (FPS_REGNUM, (char *) &fp->fpsr); - - /* Fetch the floating point registers. */ - for (regno = F0_REGNUM; regno <= F7_REGNUM; regno++) - { - fetch_nwfpe_register (regno, fp); - } -} - -int -arm_linux_kernel_u_size (void) -{ - return (sizeof (struct user)); -} - -static unsigned int -get_linux_version (unsigned int *vmajor, - unsigned int *vminor, - unsigned int *vrelease) -{ - struct utsname info; - char *pmajor, *pminor, *prelease, *tail; - - if (-1 == uname (&info)) - { - warning ("Unable to determine Linux version."); - return -1; - } - - pmajor = strtok (info.release, "."); - pminor = strtok (NULL, "."); - prelease = strtok (NULL, "."); - - *vmajor = (unsigned int) strtoul (pmajor, &tail, 0); - *vminor = (unsigned int) strtoul (pminor, &tail, 0); - *vrelease = (unsigned int) strtoul (prelease, &tail, 0); - - return ((*vmajor << 16) | (*vminor << 8) | *vrelease); -} - -void -_initialize_arm_linux_nat (void) -{ - os_version = get_linux_version (&os_major, &os_minor, &os_release); -} |