gdb/ppcnbsd-tdep.c - gdb

Global variables defined

Functions defined

Source code

  1. /* Target-dependent code for NetBSD/powerpc.

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

  3.    Contributed by Wasabi Systems, Inc.

  4.    This file is part of GDB.

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

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

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

  15. #include "defs.h"
  16. #include "gdbtypes.h"
  17. #include "osabi.h"
  18. #include "regcache.h"
  19. #include "regset.h"
  20. #include "trad-frame.h"
  21. #include "tramp-frame.h"

  22. #include "ppc-tdep.h"
  23. #include "ppcnbsd-tdep.h"
  24. #include "solib-svr4.h"

  25. /* Register offsets from <machine/reg.h>.  */
  26. struct ppc_reg_offsets ppcnbsd_reg_offsets;


  27. /* Core file support.  */

  28. /* NetBSD/powerpc register sets.  */

  29. const struct regset ppcnbsd_gregset =
  30. {
  31.   &ppcnbsd_reg_offsets,
  32.   ppc_supply_gregset
  33. };

  34. const struct regset ppcnbsd_fpregset =
  35. {
  36.   &ppcnbsd_reg_offsets,
  37.   ppc_supply_fpregset
  38. };

  39. /* Iterate over core file register note sections.  */

  40. static void
  41. ppcnbsd_iterate_over_regset_sections (struct gdbarch *gdbarch,
  42.                                       iterate_over_regset_sections_cb *cb,
  43.                                       void *cb_data,
  44.                                       const struct regcache *regcache)
  45. {
  46.   cb (".reg", 148, &ppcnbsd_gregset, NULL, cb_data);
  47.   cb (".reg2", 264, &ppcnbsd_fpregset, NULL, cb_data);
  48. }


  49. /* NetBSD is confused.  It appears that 1.5 was using the correct SVR4
  50.    convention but, 1.6 switched to the below broken convention.  For
  51.    the moment use the broken convention.  Ulgh!  */

  52. static enum return_value_convention
  53. ppcnbsd_return_value (struct gdbarch *gdbarch, struct value *function,
  54.                       struct type *valtype, struct regcache *regcache,
  55.                       gdb_byte *readbuf, const gdb_byte *writebuf)
  56. {
  57. #if 0
  58.   if ((TYPE_CODE (valtype) == TYPE_CODE_STRUCT
  59.        || TYPE_CODE (valtype) == TYPE_CODE_UNION)
  60.       && !((TYPE_LENGTH (valtype) == 16 || TYPE_LENGTH (valtype) == 8)
  61.             && TYPE_VECTOR (valtype))
  62.       && !(TYPE_LENGTH (valtype) == 1
  63.            || TYPE_LENGTH (valtype) == 2
  64.            || TYPE_LENGTH (valtype) == 4
  65.            || TYPE_LENGTH (valtype) == 8))
  66.     return RETURN_VALUE_STRUCT_CONVENTION;
  67.   else
  68. #endif
  69.     return ppc_sysv_abi_broken_return_value (gdbarch, function, valtype,
  70.                                              regcache, readbuf, writebuf);
  71. }


  72. /* Signal trampolines.  */

  73. static const struct tramp_frame ppcnbsd2_sigtramp;

  74. static void
  75. ppcnbsd_sigtramp_cache_init (const struct tramp_frame *self,
  76.                              struct frame_info *this_frame,
  77.                              struct trad_frame_cache *this_cache,
  78.                              CORE_ADDR func)
  79. {
  80.   struct gdbarch *gdbarch = get_frame_arch (this_frame);
  81.   struct gdbarch_tdep *tdep = gdbarch_tdep (gdbarch);
  82.   CORE_ADDR addr, base;
  83.   int i;

  84.   base = get_frame_register_unsigned (this_frame,
  85.                                       gdbarch_sp_regnum (gdbarch));
  86.   if (self == &ppcnbsd2_sigtramp)
  87.     addr = base + 0x10 + 2 * tdep->wordsize;
  88.   else
  89.     addr = base + 0x18 + 2 * tdep->wordsize;
  90.   for (i = 0; i < ppc_num_gprs; i++, addr += tdep->wordsize)
  91.     {
  92.       int regnum = i + tdep->ppc_gp0_regnum;
  93.       trad_frame_set_reg_addr (this_cache, regnum, addr);
  94.     }
  95.   trad_frame_set_reg_addr (this_cache, tdep->ppc_lr_regnum, addr);
  96.   addr += tdep->wordsize;
  97.   trad_frame_set_reg_addr (this_cache, tdep->ppc_cr_regnum, addr);
  98.   addr += tdep->wordsize;
  99.   trad_frame_set_reg_addr (this_cache, tdep->ppc_xer_regnum, addr);
  100.   addr += tdep->wordsize;
  101.   trad_frame_set_reg_addr (this_cache, tdep->ppc_ctr_regnum, addr);
  102.   addr += tdep->wordsize;
  103.   trad_frame_set_reg_addr (this_cache, gdbarch_pc_regnum (gdbarch),
  104.                            addr); /* SRR0?  */
  105.   addr += tdep->wordsize;

  106.   /* Construct the frame ID using the function start.  */
  107.   trad_frame_set_id (this_cache, frame_id_build (base, func));
  108. }

  109. static const struct tramp_frame ppcnbsd_sigtramp =
  110. {
  111.   SIGTRAMP_FRAME,
  112.   4,
  113.   {
  114.     { 0x3821fff0, -1 },                /* add r1,r1,-16 */
  115.     { 0x4e800021, -1 },                /* blrl */
  116.     { 0x38610018, -1 },                /* addi r3,r1,24 */
  117.     { 0x38000127, -1 },                /* li r0,295 */
  118.     { 0x44000002, -1 },                /* sc */
  119.     { 0x38000001, -1 },                /* li r0,1 */
  120.     { 0x44000002, -1 },                /* sc */
  121.     { TRAMP_SENTINEL_INSN, -1 }
  122.   },
  123.   ppcnbsd_sigtramp_cache_init
  124. };

  125. /* NetBSD 2.0 introduced a slightly different signal trampoline.  */

  126. static const struct tramp_frame ppcnbsd2_sigtramp =
  127. {
  128.   SIGTRAMP_FRAME,
  129.   4,
  130.   {
  131.     { 0x3821fff0, -1 },                /* add r1,r1,-16 */
  132.     { 0x4e800021, -1 },                /* blrl */
  133.     { 0x38610010, -1 },                /* addi r3,r1,16 */
  134.     { 0x38000127, -1 },                /* li r0,295 */
  135.     { 0x44000002, -1 },                /* sc */
  136.     { 0x38000001, -1 },                /* li r0,1 */
  137.     { 0x44000002, -1 },                /* sc */
  138.     { TRAMP_SENTINEL_INSN, -1 }
  139.   },
  140.   ppcnbsd_sigtramp_cache_init
  141. };


  142. static void
  143. ppcnbsd_init_abi (struct gdbarch_info info,
  144.                   struct gdbarch *gdbarch)
  145. {
  146.   /* For NetBSD, this is an on again, off again thing.  Some systems
  147.      do use the broken struct convention, and some don't.  */
  148.   set_gdbarch_return_value (gdbarch, ppcnbsd_return_value);

  149.   /* NetBSD uses SVR4-style shared libraries.  */
  150.   set_solib_svr4_fetch_link_map_offsets
  151.     (gdbarch, svr4_ilp32_fetch_link_map_offsets);

  152.   set_gdbarch_iterate_over_regset_sections
  153.     (gdbarch, ppcnbsd_iterate_over_regset_sections);

  154.   tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd_sigtramp);
  155.   tramp_frame_prepend_unwinder (gdbarch, &ppcnbsd2_sigtramp);
  156. }


  157. /* Provide a prototype to silence -Wmissing-prototypes.  */
  158. void _initialize_ppcnbsd_tdep (void);

  159. void
  160. _initialize_ppcnbsd_tdep (void)
  161. {
  162.   gdbarch_register_osabi (bfd_arch_powerpc, 0, GDB_OSABI_NETBSD_ELF,
  163.                           ppcnbsd_init_abi);

  164.   /* Avoid initializing the register offsets again if they were
  165.      already initailized by ppcnbsd-nat.c.  */
  166.   if (ppcnbsd_reg_offsets.pc_offset == 0)
  167.     {
  168.       /* General-purpose registers.  */
  169.       ppcnbsd_reg_offsets.r0_offset = 0;
  170.       ppcnbsd_reg_offsets.gpr_size = 4;
  171.       ppcnbsd_reg_offsets.xr_size = 4;
  172.       ppcnbsd_reg_offsets.lr_offset = 128;
  173.       ppcnbsd_reg_offsets.cr_offset = 132;
  174.       ppcnbsd_reg_offsets.xer_offset = 136;
  175.       ppcnbsd_reg_offsets.ctr_offset = 140;
  176.       ppcnbsd_reg_offsets.pc_offset = 144;
  177.       ppcnbsd_reg_offsets.ps_offset = -1;
  178.       ppcnbsd_reg_offsets.mq_offset = -1;

  179.       /* Floating-point registers.  */
  180.       ppcnbsd_reg_offsets.f0_offset = 0;
  181.       ppcnbsd_reg_offsets.fpscr_offset = 256;
  182.       ppcnbsd_reg_offsets.fpscr_size = 4;

  183.       /* AltiVec registers.  */
  184.       ppcnbsd_reg_offsets.vr0_offset = 0;
  185.       ppcnbsd_reg_offsets.vrsave_offset = 512;
  186.       ppcnbsd_reg_offsets.vscr_offset = 524;
  187.     }
  188. }