gdb/gdbserver/linux-nios2-low.c - gdb

Global variables defined

Data types defined

Functions defined

Macros defined

Source code

  1. /* GNU/Linux/Nios II specific low level interface, for the remote server for
  2.    GDB.
  3.    Copyright (C) 2008-2015 Free Software Foundation, Inc.

  4.    Contributed by Mentor Graphics, Inc.

  5.    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 3 of the License, or
  9.    (at your option) any later version.

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

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

  16. #include "server.h"
  17. #include "linux-low.h"
  18. #include <sys/ptrace.h>
  19. #include <endian.h>
  20. #include "gdb_proc_service.h"
  21. #include <asm/ptrace.h>

  22. #ifndef PTRACE_GET_THREAD_AREA
  23. #define PTRACE_GET_THREAD_AREA 25
  24. #endif

  25. /* The following definition must agree with the number of registers
  26.    defined in "struct user_regs" in GLIBC
  27.    (ports/sysdeps/unix/sysv/linux/nios2/sys/user.h), and also with
  28.    NIOS2_NUM_REGS in GDB proper.  */

  29. #define nios2_num_regs 49

  30. /* Defined in auto-generated file nios2-linux.c.  */

  31. void init_registers_nios2_linux (void);
  32. extern const struct target_desc *tdesc_nios2_linux;

  33. /* This union is used to convert between int and byte buffer
  34.    representations of register contents.  */

  35. union nios2_register
  36. {
  37.   unsigned char buf[4];
  38.   int reg32;
  39. };

  40. /* Return the ptrace ``address'' of register REGNO. */

  41. static int nios2_regmap[] = {
  42.   -11234567,
  43.   8910, 11, 12, 13, 14, 15,
  44.   16, 17, 18, 19, 20, 21, 22, 23,
  45.   24, 25, 26, 27, 28, 29, 30, 31,
  46.   32, 33, 34, 35, 36, 37, 38, 39,
  47.   40, 41, 42, 43, 44, 45, 46, 47,
  48.   48,
  49.   0
  50. };

  51. /* Implement the arch_setup linux_target_ops method.  */

  52. static void
  53. nios2_arch_setup (void)
  54. {
  55.   current_process ()->tdesc = tdesc_nios2_linux;
  56. }

  57. /* Implement the cannot_fetch_register linux_target_ops method.  */

  58. static int
  59. nios2_cannot_fetch_register (int regno)
  60. {
  61.   if (nios2_regmap[regno] == -1)
  62.     return 1;

  63.   return 0;
  64. }

  65. /* Implement the cannot_store_register linux_target_ops method.  */

  66. static int
  67. nios2_cannot_store_register (int regno)
  68. {
  69.   if (nios2_regmap[regno] == -1)
  70.     return 1;

  71.   return 0;
  72. }

  73. /* Implement the get_pc linux_target_ops method.  */

  74. static CORE_ADDR
  75. nios2_get_pc (struct regcache *regcache)
  76. {
  77.   union nios2_register pc;

  78.   collect_register_by_name (regcache, "pc", pc.buf);
  79.   return pc.reg32;
  80. }

  81. /* Implement the set_pc linux_target_ops method.  */

  82. static void
  83. nios2_set_pc (struct regcache *regcache, CORE_ADDR pc)
  84. {
  85.   union nios2_register newpc;

  86.   newpc.reg32 = pc;
  87.   supply_register_by_name (regcache, "pc", newpc.buf);
  88. }

  89. /* Breakpoint support.  */

  90. static const unsigned int nios2_breakpoint = 0x003b6ffa;
  91. #define nios2_breakpoint_len 4

  92. /* Implement the breakpoint_reinsert_addr linux_target_ops method.  */

  93. static CORE_ADDR
  94. nios2_reinsert_addr (void)
  95. {
  96.   union nios2_register ra;
  97.   struct regcache *regcache = get_thread_regcache (current_thread, 1);

  98.   collect_register_by_name (regcache, "ra", ra.buf);
  99.   return ra.reg32;
  100. }

  101. /* Implement the breakpoint_at linux_target_ops method.  */

  102. static int
  103. nios2_breakpoint_at (CORE_ADDR where)
  104. {
  105.   unsigned int insn;

  106.   (*the_target->read_memory) (where, (unsigned char *) &insn, 4);
  107.   if (insn == nios2_breakpoint)
  108.     return 1;
  109.   return 0;
  110. }

  111. /* Fetch the thread-local storage pointer for libthread_db.  */

  112. ps_err_e
  113. ps_get_thread_area (const struct ps_prochandle *ph,
  114.                     lwpid_t lwpid, int idx, void **base)
  115. {
  116.   if (ptrace (PTRACE_GET_THREAD_AREA, lwpid, NULL, base) != 0)
  117.     return PS_ERR;

  118.   /* IDX is the bias from the thread pointer to the beginning of the
  119.      thread descriptor.  It has to be subtracted due to implementation
  120.      quirks in libthread_db.  */
  121.   *base = (void *) ((char *) *base - idx);

  122.   return PS_OK;
  123. }

  124. #ifdef HAVE_PTRACE_GETREGS

  125. /* Helper functions to collect/supply a single register REGNO.  */

  126. static void
  127. nios2_collect_register (struct regcache *regcache, int regno,
  128.                         union nios2_register *reg)
  129. {
  130.   union nios2_register tmp_reg;

  131.   collect_register (regcache, regno, &tmp_reg.reg32);
  132.   reg->reg32 = tmp_reg.reg32;
  133. }

  134. static void
  135. nios2_supply_register (struct regcache *regcache, int regno,
  136.                        const union nios2_register *reg)
  137. {
  138.   supply_register (regcache, regno, reg->buf);
  139. }

  140. /* We have only a single register set on Nios II.  */

  141. static void
  142. nios2_fill_gregset (struct regcache *regcache, void *buf)
  143. {
  144.   union nios2_register *regset = buf;
  145.   int i;

  146.   for (i = 1; i < nios2_num_regs; i++)
  147.     nios2_collect_register (regcache, i, regset + i);
  148. }

  149. static void
  150. nios2_store_gregset (struct regcache *regcache, const void *buf)
  151. {
  152.   const union nios2_register *regset = buf;
  153.   int i;

  154.   for (i = 0; i < nios2_num_regs; i++)
  155.     nios2_supply_register (regcache, i, regset + i);
  156. }
  157. #endif /* HAVE_PTRACE_GETREGS */

  158. static struct regset_info nios2_regsets[] =
  159. {
  160. #ifdef HAVE_PTRACE_GETREGS
  161.   { PTRACE_GETREGS, PTRACE_SETREGS, 0, nios2_num_regs * 4, GENERAL_REGS,
  162.     nios2_fill_gregset, nios2_store_gregset },
  163. #endif /* HAVE_PTRACE_GETREGS */
  164.   { 0, 0, 0, -1, -1, NULL, NULL }
  165. };

  166. static struct regsets_info nios2_regsets_info =
  167.   {
  168.     nios2_regsets, /* regsets */
  169.     0, /* num_regsets */
  170.     NULL, /* disabled_regsets */
  171.   };

  172. static struct usrregs_info nios2_usrregs_info =
  173.   {
  174.     nios2_num_regs,
  175.     nios2_regmap,
  176.   };

  177. static struct regs_info regs_info =
  178.   {
  179.     NULL, /* regset_bitmap */
  180.     &nios2_usrregs_info,
  181.     &nios2_regsets_info
  182.   };

  183. static const struct regs_info *
  184. nios2_regs_info (void)
  185. {
  186.   return &regs_info;
  187. }

  188. struct linux_target_ops the_low_target =
  189. {
  190.   nios2_arch_setup,
  191.   nios2_regs_info,
  192.   nios2_cannot_fetch_register,
  193.   nios2_cannot_store_register,
  194.   NULL,
  195.   nios2_get_pc,
  196.   nios2_set_pc,
  197.   (const unsigned char *) &nios2_breakpoint,
  198.   nios2_breakpoint_len,
  199.   nios2_reinsert_addr,
  200.   0,
  201.   nios2_breakpoint_at,
  202. };

  203. void
  204. initialize_low_arch (void)
  205. {
  206.   init_registers_nios2_linux ();

  207.   initialize_regsets_info (&nios2_regsets_info);
  208. }