gdb/bfin-linux-tdep.c - gdb

Global variables defined

Functions defined

Macros defined

Source code

  1. /* Target-dependent code for Analog Devices Blackfin processor, for GDB.

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

  3.    Contributed by Analog Devices, 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 "arch-utils.h"
  17. #include "regcache.h"
  18. #include "tramp-frame.h"
  19. #include "trad-frame.h"
  20. #include "osabi.h"
  21. #include "xml-syscall.h"
  22. #include "linux-tdep.h"
  23. #include "bfin-tdep.h"

  24. /* From <asm/sigcontext.h>.  */

  25. #define SIGCONTEXT_OFFSET        168

  26. static const int bfin_linux_sigcontext_reg_offset[BFIN_NUM_REGS] =
  27. {
  28.   0 * 4,        /* %r0 */
  29.   1 * 4,        /* %r1 */
  30.   2 * 4,        /* %r2 */
  31.   3 * 4,        /* %r3 */
  32.   4 * 4,        /* %r4 */
  33.   5 * 4,        /* %r5 */
  34.   6 * 4,        /* %r6 */
  35.   7 * 4,        /* %r7 */
  36.   8 * 4,        /* %p0 */
  37.   9 * 4,        /* %p1 */
  38.   10 * 4,        /* %p2 */
  39.   11 * 4,        /* %p3 */
  40.   12 * 4,        /* %p4 */
  41.   13 * 4,        /* %p5 */
  42.   14 * 4,        /* %sp */
  43.   23 * 4,        /* %fp */
  44.   24 * 4,        /* %i0 */
  45.   25 * 4,        /* %i1 */
  46.   26 * 4,        /* %i2 */
  47.   27 * 4,        /* %i3 */
  48.   28 * 4,        /* %m0 */
  49.   29 * 4,        /* %m1 */
  50.   30 * 4,        /* %m2 */
  51.   31 * 4,        /* %m3 */
  52.   36 * 4,        /* %b0 */
  53.   37 * 4,        /* %b1 */
  54.   38 * 4,        /* %b2 */
  55.   39 * 4,        /* %b3 */
  56.   32 * 4,        /* %l0 */
  57.   33 * 4,        /* %l1 */
  58.   34 * 4,        /* %l2 */
  59.   35 * 4,        /* %l3 */
  60.   17 * 4,        /* %a0x */
  61.   15 * 4,        /* %a0w */
  62.   18 * 4,        /* %a1x */
  63.   16 * 4,        /* %a1w */
  64.   19 * 4,        /* %astat */
  65.   20 * 4,        /* %rets */
  66.   40 * 4,        /* %lc0 */
  67.   42 * 4,        /* %lt0 */
  68.   44 * 4,        /* %lb0 */
  69.   41 * 4,        /* %lc1 */
  70.   43 * 4,        /* %lt1 */
  71.   45 * 4,        /* %lb1 */
  72.   -1,                /* %cycles */
  73.   -1,                /* %cycles2 */
  74.   -1,                /* %usp */
  75.   46 * 4,        /* %seqstat */
  76.   -1,                /* syscfg */
  77.   21 * 4,        /* %reti */
  78.   22 * 4,        /* %retx */
  79.   -1,                /* %retn */
  80.   -1,                /* %rete */
  81.   21 * 4,        /* %pc */
  82. };

  83. /* Signal trampolines.  */

  84. static void
  85. bfin_linux_sigframe_init (const struct tramp_frame *self,
  86.                           struct frame_info *this_frame,
  87.                           struct trad_frame_cache *this_cache,
  88.                           CORE_ADDR func)
  89. {
  90.   struct gdbarch *gdbarch = get_frame_arch (this_frame);
  91.   CORE_ADDR sp = get_frame_sp (this_frame);
  92.   CORE_ADDR pc = get_frame_pc (this_frame);
  93.   CORE_ADDR sigcontext = sp + SIGCONTEXT_OFFSET;
  94.   const int *reg_offset = bfin_linux_sigcontext_reg_offset;
  95.   int i;

  96.   for (i = 0; i < BFIN_NUM_REGS; i++)
  97.     if (reg_offset[i] != -1)
  98.       trad_frame_set_reg_addr (this_cache, i, sigcontext + reg_offset[i]);

  99.   /* This would come after the LINK instruction in the ret_from_signal
  100.      function, hence the frame id would be SP + 8.  */
  101.   trad_frame_set_id (this_cache, frame_id_build (sp + 8, pc));
  102. }

  103. static const struct tramp_frame bfin_linux_sigframe =
  104. {
  105.   SIGTRAMP_FRAME,
  106.   4,
  107.   {
  108.     { 0x00ADE128, 0xffffffff },        /* P0 = __NR_rt_sigreturn; */
  109.     { 0x00A0, 0xffff },                /* EXCPT 0; */
  110.     { TRAMP_SENTINEL_INSN, -1 },
  111.   },
  112.   bfin_linux_sigframe_init,
  113. };

  114. static LONGEST
  115. bfin_linux_get_syscall_number (struct gdbarch *gdbarch,
  116.                                ptid_t ptid)
  117. {
  118.   struct regcache *regcache = get_thread_regcache (ptid);
  119.   enum bfd_endian byte_order = gdbarch_byte_order (gdbarch);
  120.   /* The content of a register.  */
  121.   gdb_byte buf[4];
  122.   /* The result.  */
  123.   LONGEST ret;

  124.   /* Getting the system call number from the register.
  125.      When dealing with Blackfin architecture, this information
  126.      is stored at %p0 register.  */
  127.   regcache_cooked_read (regcache, BFIN_P0_REGNUM, buf);

  128.   ret = extract_signed_integer (buf, 4, byte_order);

  129.   return ret;
  130. }

  131. static void
  132. bfin_linux_init_abi (struct gdbarch_info info, struct gdbarch *gdbarch)
  133. {
  134.   linux_init_abi (info, gdbarch);

  135.   /* Set the sigtramp frame sniffer.  */
  136.   tramp_frame_prepend_unwinder (gdbarch, &bfin_linux_sigframe);

  137.   /* Functions for 'catch syscall'.  */
  138.   set_xml_syscall_file_name (gdbarch, "syscalls/bfin-linux.xml");
  139.   set_gdbarch_get_syscall_number (gdbarch,
  140.                                   bfin_linux_get_syscall_number);
  141. }

  142. /* Provide a prototype to silence -Wmissing-prototypes.  */
  143. extern initialize_file_ftype _initialize_bfin_linux_tdep;

  144. void
  145. _initialize_bfin_linux_tdep (void)
  146. {
  147.   gdbarch_register_osabi (bfd_arch_bfin, 0, GDB_OSABI_LINUX,
  148.                           bfin_linux_init_abi);
  149. }