gdb/ppc-ravenscar-thread.c - gdb

Global variables defined

Data types defined

Functions defined

Macros defined

Source code

  1. /* Ravenscar PowerPC target support.

  2.    Copyright (C) 2011-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 "gdbcore.h"
  16. #include "regcache.h"
  17. #include "ppc-tdep.h"
  18. #include "inferior.h"
  19. #include "ravenscar-thread.h"
  20. #include "ppc-ravenscar-thread.h"

  21. #define NO_OFFSET -1

  22. /* See ppc-tdep.h for register numbers.  */

  23. static const int powerpc_context_offsets[] =
  24. {
  25.   /* R0 - R32 */
  26.   NO_OFFSET, 0,         4,         NO_OFFSET,
  27.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
  28.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
  29.   NO_OFFSET, 8,         12,        16,
  30.   20,        24,        28,        32,
  31.   36,        40,        44,        48,
  32.   52,        56,        60,        64,
  33.   68,        72,        76,        80,

  34.   /* F0 - F31 */
  35.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
  36.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
  37.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
  38.   NO_OFFSET, NO_OFFSET, 96,        104,
  39.   112,       120,       128,       136,
  40.   144,       152,       160,       168,
  41.   176,       184,       192,       200,
  42.   208,       216,       224,       232,

  43.   /* PC, MSR, CR, LR */
  44.   88,        NO_OFFSET, 84,        NO_OFFSET,

  45.   /* CTR, XER, FPSCR  */
  46.   NO_OFFSET, NO_OFFSET, 240
  47. };

  48. static const int e500_context_offsets[] =
  49. {
  50.   /* R0 - R32 */
  51.   NO_OFFSET, 4,         12,        NO_OFFSET,
  52.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
  53.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
  54.   NO_OFFSET, 20,        28,        36,
  55.   44,        52,        60,        68,
  56.   76,        84,        92,        100,
  57.   108,       116,       124,       132,
  58.   140,       148,       156,       164,

  59.   /* F0 - F31 */
  60.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
  61.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
  62.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
  63.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
  64.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
  65.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
  66.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
  67.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,

  68.   /* PC, MSR, CR, LR */
  69.   172,       NO_OFFSET, 168,       NO_OFFSET,

  70.   /* CTR, XER, FPSCR, MQ  */
  71.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,

  72.   /* Upper R0-R32.  */
  73.   NO_OFFSET, 0,         8,        NO_OFFSET,
  74.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
  75.   NO_OFFSET, NO_OFFSET, NO_OFFSET, NO_OFFSET,
  76.   NO_OFFSET, 16,        24,        32,
  77.   40,        48,        56,        64,
  78.   72,        80,        88,        96,
  79.   104,       112,       120,       128,
  80.   136,       144,       152,       160,

  81.   /* ACC, FSCR */
  82.   NO_OFFSET, 176
  83. };

  84. /* The register layout info.  */

  85. struct ravenscar_reg_info
  86. {
  87.   /* A table providing the offset relative to the context structure
  88.      where each register is saved.  */
  89.   const int *context_offsets;

  90.   /* The number of elements in the context_offsets table above.  */
  91.   int context_offsets_size;
  92. };

  93. /* supply register REGNUM, which has been saved on REGISTER_ADDR, to the
  94.    regcache.  */

  95. static void
  96. supply_register_at_address (struct regcache *regcache, int regnum,
  97.                             CORE_ADDR register_addr)
  98. {
  99.   struct gdbarch *gdbarch = get_regcache_arch (regcache);
  100.   int buf_size = register_size (gdbarch, regnum);
  101.   gdb_byte *buf;

  102.   buf = alloca (buf_size);
  103.   read_memory (register_addr, buf, buf_size);
  104.   regcache_raw_supply (regcache, regnum, buf);
  105. }

  106. /* Return true if, for a non-running thread, REGNUM has been saved on the
  107.    Thread_Descriptor.  */

  108. static int
  109. register_in_thread_descriptor_p (const struct ravenscar_reg_info *reg_info,
  110.                                  int regnum)
  111. {
  112.   return (regnum < reg_info->context_offsets_size
  113.           && reg_info->context_offsets[regnum] != NO_OFFSET);
  114. }

  115. /* to_fetch_registers when inferior_ptid is different from the running
  116.    thread.  */

  117. static void
  118. ppc_ravenscar_generic_fetch_registers
  119.   (const struct ravenscar_reg_info *reg_info,
  120.    struct regcache *regcache, int regnum)
  121. {
  122.   struct gdbarch *gdbarch = get_regcache_arch (regcache);
  123.   const int sp_regnum = gdbarch_sp_regnum (gdbarch);
  124.   const int num_regs = gdbarch_num_regs (gdbarch);
  125.   int current_regnum;
  126.   CORE_ADDR current_address;
  127.   CORE_ADDR thread_descriptor_address;

  128.   /* The tid is the thread_id field, which is a pointer to the thread.  */
  129.   thread_descriptor_address = (CORE_ADDR) ptid_get_tid (inferior_ptid);

  130.   /* Read registers.  */
  131.   for (current_regnum = 0; current_regnum < num_regs; current_regnum++)
  132.     {
  133.       if (register_in_thread_descriptor_p (reg_info, current_regnum))
  134.         {
  135.           current_address = thread_descriptor_address
  136.             + reg_info->context_offsets[current_regnum];
  137.           supply_register_at_address (regcache, current_regnum,
  138.                                       current_address);
  139.         }
  140.     }
  141. }

  142. /* to_prepare_to_store when inferior_ptid is different from the running
  143.    thread.  */

  144. static void
  145. ppc_ravenscar_generic_prepare_to_store (struct regcache *regcache)
  146. {
  147.   /* Nothing to do.  */
  148. }

  149. /* to_store_registers when inferior_ptid is different from the running
  150.    thread.  */

  151. static void
  152. ppc_ravenscar_generic_store_registers
  153.   (const struct ravenscar_reg_info *reg_info,
  154.    struct regcache *regcache, int regnum)
  155. {
  156.   struct gdbarch *gdbarch = get_regcache_arch (regcache);
  157.   int buf_size = register_size (gdbarch, regnum);
  158.   gdb_byte buf[buf_size];
  159.   ULONGEST register_address;

  160.   if (register_in_thread_descriptor_p (reg_info, regnum))
  161.     register_address
  162.       = ptid_get_tid (inferior_ptid) + reg_info->context_offsets [regnum];
  163.   else
  164.     return;

  165.   regcache_raw_collect (regcache, regnum, buf);
  166.   write_memory (register_address,
  167.                 buf,
  168.                 buf_size);
  169. }

  170. /* The ravenscar_reg_info for most PowerPC targets.  */

  171. static const struct ravenscar_reg_info ppc_reg_info =
  172. {
  173.   powerpc_context_offsets,
  174.   ARRAY_SIZE (powerpc_context_offsets),
  175. };

  176. /* Implement the to_fetch_registers ravenscar_arch_ops method
  177.    for most PowerPC targets.  */

  178. static void
  179. ppc_ravenscar_powerpc_fetch_registers (struct regcache *regcache, int regnum)
  180. {
  181.   ppc_ravenscar_generic_fetch_registers (&ppc_reg_info, regcache, regnum);
  182. }

  183. /* Implement the to_store_registers ravenscar_arch_ops method
  184.    for most PowerPC targets.  */

  185. static void
  186. ppc_ravenscar_powerpc_store_registers (struct regcache *regcache, int regnum)
  187. {
  188.   ppc_ravenscar_generic_store_registers (&ppc_reg_info, regcache, regnum);
  189. }

  190. /* The ravenscar_arch_ops vector for most PowerPC targets.  */

  191. static struct ravenscar_arch_ops ppc_ravenscar_powerpc_ops =
  192. {
  193.   ppc_ravenscar_powerpc_fetch_registers,
  194.   ppc_ravenscar_powerpc_store_registers,
  195.   ppc_ravenscar_generic_prepare_to_store
  196. };

  197. /* Register ppc_ravenscar_powerpc_ops in GDBARCH.  */

  198. void
  199. register_ppc_ravenscar_ops (struct gdbarch *gdbarch)
  200. {
  201.   set_gdbarch_ravenscar_ops (gdbarch, &ppc_ravenscar_powerpc_ops);
  202. }

  203. /* The ravenscar_reg_info for E500 targets.  */

  204. static const struct ravenscar_reg_info e500_reg_info =
  205. {
  206.   e500_context_offsets,
  207.   ARRAY_SIZE (e500_context_offsets),
  208. };

  209. /* Implement the to_fetch_registers ravenscar_arch_ops method
  210.    for E500 targets.  */

  211. static void
  212. ppc_ravenscar_e500_fetch_registers (struct regcache *regcache, int regnum)
  213. {
  214.   ppc_ravenscar_generic_fetch_registers (&e500_reg_info, regcache, regnum);
  215. }

  216. /* Implement the to_store_registers ravenscar_arch_ops method
  217.    for E500 targets.  */

  218. static void
  219. ppc_ravenscar_e500_store_registers (struct regcache *regcache, int regnum)
  220. {
  221.   ppc_ravenscar_generic_store_registers (&e500_reg_info, regcache, regnum);
  222. }

  223. /* The ravenscar_arch_ops vector for E500 targets.  */

  224. static struct ravenscar_arch_ops ppc_ravenscar_e500_ops =
  225. {
  226.   ppc_ravenscar_e500_fetch_registers,
  227.   ppc_ravenscar_e500_store_registers,
  228.   ppc_ravenscar_generic_prepare_to_store
  229. };

  230. /* Register ppc_ravenscar_e500_ops in GDBARCH.  */

  231. void
  232. register_e500_ravenscar_ops (struct gdbarch *gdbarch)
  233. {
  234.   set_gdbarch_ravenscar_ops (gdbarch, &ppc_ravenscar_e500_ops);
  235. }