gdb/m32r-linux-nat.c - gdb

Global variables defined

Functions defined

Macros defined

Source code

  1. /* Native-dependent code for GNU/Linux m32r.

  2.    Copyright (C) 2004-2015 Free Software Foundation, Inc.

  3.    This file is part of GDB.

  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 3 of the License, or
  7.    (at your option) any later version.

  8.    This program is distributed in the hope that it will be useful,
  9.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  10.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  11.    GNU General Public License for more details.

  12.    You should have received a copy of the GNU General Public License
  13.    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

  14. #include "defs.h"
  15. #include "inferior.h"
  16. #include "gdbcore.h"
  17. #include "regcache.h"
  18. #include "linux-nat.h"
  19. #include "target.h"
  20. #include <sys/ptrace.h>
  21. #include <sys/user.h>
  22. #include <sys/procfs.h>

  23. /* Prototypes for supply_gregset etc.  */
  24. #include "gregset.h"

  25. #include "m32r-tdep.h"




  26. /* Since EVB register is not available for native debug, we reduce
  27.    the number of registers.  */
  28. #define M32R_LINUX_NUM_REGS (M32R_NUM_REGS - 1)

  29. /* Mapping between the general-purpose registers in `struct user'
  30.    format and GDB's register array layout.  */
  31. static int regmap[] = {
  32.   4, 5, 6, 7, 0, 1, 2, 8,
  33.   9, 10, 11, 12, 13, 24, 25, 23,
  34.   19, 19, 26, 23, 22, 20, 16, 15
  35. };

  36. #define PSW_REGMAP 19
  37. #define BBPSW_REGMAP 21
  38. #define SPU_REGMAP 23
  39. #define SPI_REGMAP 26

  40. /* Doee (??) apply to the corresponding SET requests as well.  */
  41. #define GETREGS_SUPPLIES(regno) (0 <= (regno) \
  42.                                  && (regno) <= M32R_LINUX_NUM_REGS)



  43. /* Transfering the general-purpose registers between GDB, inferiors
  44.    and core files.  */

  45. /* Fill GDB's register array with the general-purpose register values
  46.    in *GREGSETP.  */

  47. void
  48. supply_gregset (struct regcache *regcache, const elf_gregset_t * gregsetp)
  49. {
  50.   const elf_greg_t *regp = (const elf_greg_t *) gregsetp;
  51.   int i;
  52.   unsigned long psw, bbpsw;

  53.   psw = *(regp + PSW_REGMAP);
  54.   bbpsw = *(regp + BBPSW_REGMAP);

  55.   for (i = 0; i < M32R_LINUX_NUM_REGS; i++)
  56.     {
  57.       elf_greg_t regval;

  58.       switch (i)
  59.         {
  60.         case PSW_REGNUM:
  61.           regval = ((0x00c1 & bbpsw) << 8) | ((0xc100 & psw) >> 8);
  62.           break;
  63.         case CBR_REGNUM:
  64.           regval = ((psw >> 8) & 1);
  65.           break;
  66.         default:
  67.           regval = *(regp + regmap[i]);
  68.           break;
  69.         }

  70.       if (i != M32R_SP_REGNUM)
  71.         regcache_raw_supply (regcache, i, &regval);
  72.       else if (psw & 0x8000)
  73.         regcache_raw_supply (regcache, i, regp + SPU_REGMAP);
  74.       else
  75.         regcache_raw_supply (regcache, i, regp + SPI_REGMAP);
  76.     }
  77. }

  78. /* Fetch all general-purpose registers from process/thread TID and
  79.    store their values in GDB's register array.  */

  80. static void
  81. fetch_regs (struct regcache *regcache, int tid)
  82. {
  83.   elf_gregset_t regs;

  84.   if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
  85.     perror_with_name (_("Couldn't get registers"));

  86.   supply_gregset (regcache, (const elf_gregset_t *) &regs);
  87. }

  88. /* Fill register REGNO (if it is a general-purpose register) in
  89.    *GREGSETPS with the value in GDB's register array.  If REGNO is -1,
  90.    do this for all registers.  */

  91. void
  92. fill_gregset (const struct regcache *regcache,
  93.               elf_gregset_t * gregsetp, int regno)
  94. {
  95.   elf_greg_t *regp = (elf_greg_t *) gregsetp;
  96.   int i;
  97.   unsigned long psw, bbpsw, tmp;

  98.   psw = *(regp + PSW_REGMAP);
  99.   bbpsw = *(regp + BBPSW_REGMAP);

  100.   for (i = 0; i < M32R_LINUX_NUM_REGS; i++)
  101.     {
  102.       if (regno != -1 && regno != i)
  103.         continue;

  104.       if (i == CBR_REGNUM || i == PSW_REGNUM)
  105.         continue;

  106.       if (i == SPU_REGNUM || i == SPI_REGNUM)
  107.         continue;

  108.       if (i != M32R_SP_REGNUM)
  109.         regcache_raw_collect (regcache, i, regp + regmap[i]);
  110.       else if (psw & 0x8000)
  111.         regcache_raw_collect (regcache, i, regp + SPU_REGMAP);
  112.       else
  113.         regcache_raw_collect (regcache, i, regp + SPI_REGMAP);
  114.     }
  115. }

  116. /* Store all valid general-purpose registers in GDB's register array
  117.    into the process/thread specified by TID.  */

  118. static void
  119. store_regs (const struct regcache *regcache, int tid, int regno)
  120. {
  121.   elf_gregset_t regs;

  122.   if (ptrace (PTRACE_GETREGS, tid, 0, (int) &regs) < 0)
  123.     perror_with_name (_("Couldn't get registers"));

  124.   fill_gregset (regcache, &regs, regno);

  125.   if (ptrace (PTRACE_SETREGS, tid, 0, (int) &regs) < 0)
  126.     perror_with_name (_("Couldn't write registers"));
  127. }



  128. /* Transfering floating-point registers between GDB, inferiors and cores.
  129.    Since M32R has no floating-point registers, these functions do nothing.  */

  130. void
  131. supply_fpregset (struct regcache *regcache, const gdb_fpregset_t *fpregs)
  132. {
  133. }

  134. void
  135. fill_fpregset (const struct regcache *regcache,
  136.                gdb_fpregset_t *fpregs, int regno)
  137. {
  138. }



  139. /* Transferring arbitrary registers between GDB and inferior.  */

  140. /* Fetch register REGNO from the child process.  If REGNO is -1, do
  141.    this for all registers (including the floating point and SSE
  142.    registers).  */

  143. static void
  144. m32r_linux_fetch_inferior_registers (struct target_ops *ops,
  145.                                      struct regcache *regcache, int regno)
  146. {
  147.   int tid;

  148.   /* GNU/Linux LWP ID's are process ID's.  */
  149.   tid = ptid_get_lwp (inferior_ptid);
  150.   if (tid == 0)
  151.     tid = ptid_get_pid (inferior_ptid);        /* Not a threaded program.  */

  152.   /* Use the PTRACE_GETREGS request whenever possible, since it
  153.      transfers more registers in one system call, and we'll cache the
  154.      results.  */
  155.   if (regno == -1 || GETREGS_SUPPLIES (regno))
  156.     {
  157.       fetch_regs (regcache, tid);
  158.       return;
  159.     }

  160.   internal_error (__FILE__, __LINE__,
  161.                   _("Got request for bad register number %d."), regno);
  162. }

  163. /* Store register REGNO back into the child process.  If REGNO is -1,
  164.    do this for all registers (including the floating point and SSE
  165.    registers).  */
  166. static void
  167. m32r_linux_store_inferior_registers (struct target_ops *ops,
  168.                                      struct regcache *regcache, int regno)
  169. {
  170.   int tid;

  171.   /* GNU/Linux LWP ID's are process ID's.  */
  172.   if ((tid = ptid_get_lwp (inferior_ptid)) == 0)
  173.     tid = ptid_get_pid (inferior_ptid);        /* Not a threaded program.  */

  174.   /* Use the PTRACE_SETREGS request whenever possible, since it
  175.      transfers more registers in one system call.  */
  176.   if (regno == -1 || GETREGS_SUPPLIES (regno))
  177.     {
  178.       store_regs (regcache, tid, regno);
  179.       return;
  180.     }

  181.   internal_error (__FILE__, __LINE__,
  182.                   _("Got request to store bad register number %d."), regno);
  183. }

  184. void _initialize_m32r_linux_nat (void);

  185. void
  186. _initialize_m32r_linux_nat (void)
  187. {
  188.   struct target_ops *t;

  189.   /* Fill in the generic GNU/Linux methods.  */
  190.   t = linux_target ();

  191.   /* Add our register access methods.  */
  192.   t->to_fetch_registers = m32r_linux_fetch_inferior_registers;
  193.   t->to_store_registers = m32r_linux_store_inferior_registers;

  194.   /* Register the target.  */
  195.   linux_nat_add_target (t);
  196. }