Home | History | Annotate | Download | only in m_gdbserver
      1 /* Low level interface to valgrind, for the remote server for GDB integrated
      2    in valgrind.
      3    Copyright (C) 2012
      4    Free Software Foundation, Inc.
      5 
      6    This file is part of VALGRIND.
      7    It has been inspired from a file from gdbserver in gdb 6.6.
      8 
      9    This program is free software; you can redistribute it and/or modify
     10    it under the terms of the GNU General Public License as published by
     11    the Free Software Foundation; either version 2 of the License, or
     12    (at your option) any later version.
     13 
     14    This program is distributed in the hope that it will be useful,
     15    but WITHOUT ANY WARRANTY; without even the implied warranty of
     16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     17    GNU General Public License for more details.
     18 
     19    You should have received a copy of the GNU General Public License
     20    along with this program; if not, write to the Free Software
     21    Foundation, Inc., 51 Franklin Street, Fifth Floor,
     22    Boston, MA 02110-1301, USA. */
     23 
     24 #include "server.h"
     25 #include "target.h"
     26 #include "regdef.h"
     27 #include "regcache.h"
     28 
     29 #include "pub_core_aspacemgr.h"
     30 #include "pub_core_threadstate.h"
     31 #include "pub_core_transtab.h"
     32 #include "pub_core_gdbserver.h"
     33 
     34 #include "valgrind_low.h"
     35 
     36 #include "libvex_guest_tilegx.h"
     37 #define  REG_ONE(_n)  { "r"#_n, 64 * (_n), 64 }
     38 #define  REG_ONE_NAME(_n, _name) { _name, 64 * (_n), 64 }
     39 
     40 static struct reg regs[] = {
     41   REG_ONE(0),
     42   REG_ONE(1),
     43   REG_ONE(2),
     44   REG_ONE(3),
     45   REG_ONE(4),
     46   REG_ONE(5),
     47   REG_ONE(6),
     48   REG_ONE(7),
     49   REG_ONE(8),
     50   REG_ONE(9),
     51 
     52   REG_ONE(10),
     53   REG_ONE(11),
     54   REG_ONE(12),
     55   REG_ONE(13),
     56   REG_ONE(14),
     57   REG_ONE(15),
     58   REG_ONE(16),
     59   REG_ONE(17),
     60   REG_ONE(18),
     61   REG_ONE(19),
     62 
     63   REG_ONE(20),
     64   REG_ONE(21),
     65   REG_ONE(22),
     66   REG_ONE(23),
     67   REG_ONE(24),
     68   REG_ONE(25),
     69   REG_ONE(26),
     70   REG_ONE(27),
     71   REG_ONE(28),
     72   REG_ONE(29),
     73 
     74   REG_ONE(30),
     75   REG_ONE(31),
     76   REG_ONE(32),
     77   REG_ONE(33),
     78   REG_ONE(34),
     79   REG_ONE(35),
     80   REG_ONE(36),
     81   REG_ONE(37),
     82   REG_ONE(38),
     83   REG_ONE(39),
     84 
     85   REG_ONE(40),
     86   REG_ONE(41),
     87   REG_ONE(42),
     88   REG_ONE(43),
     89   REG_ONE(44),
     90   REG_ONE(45),
     91   REG_ONE(46),
     92   REG_ONE(47),
     93   REG_ONE(48),
     94   REG_ONE(49),
     95 
     96   REG_ONE(50),
     97   REG_ONE(51),
     98   REG_ONE(52),
     99   REG_ONE(53),
    100 
    101   REG_ONE_NAME(54, "sp"),
    102   REG_ONE_NAME(55, "lr"),
    103   REG_ONE(56),
    104   REG_ONE(57),
    105   REG_ONE(58),
    106   REG_ONE(59),
    107 
    108   REG_ONE(60),
    109   REG_ONE(61),
    110   REG_ONE(62),
    111   REG_ONE_NAME(63, "zero"),
    112   REG_ONE_NAME(64, "pc"),
    113 };
    114 
    115 #define num_regs (sizeof (regs) / sizeof (regs[0]))
    116 
    117 static const char *expedite_regs[] = { "sp", "pc", 0 };
    118 
    119 static
    120 CORE_ADDR get_pc (void)
    121 {
    122   unsigned long pc;
    123 
    124   collect_register_by_name ("pc", &pc);
    125 
    126   dlog(1, "stop pc is %p\n", (void *) pc);
    127   return pc;
    128 }
    129 
    130 static
    131 void set_pc ( CORE_ADDR newpc )
    132 {
    133   Bool mod;
    134   supply_register_by_name ("pc", &newpc, &mod);
    135   if (mod)
    136     dlog(1, "set pc to %p\n", C2v (newpc));
    137   else
    138     dlog(1, "set pc not changed %p\n", C2v (newpc));
    139 }
    140 
    141 /* store registers in the guest state (gdbserver_to_valgrind)
    142    or fetch register from the guest state (valgrind_to_gdbserver). */
    143 static
    144 void transfer_register ( ThreadId tid, int abs_regno, void * buf,
    145                          transfer_direction dir, int size, Bool *mod )
    146 {
    147   ThreadState* tst = VG_(get_ThreadState)(tid);
    148   int set = abs_regno / num_regs;
    149   int regno = abs_regno % num_regs;
    150   *mod = False;
    151 
    152   VexGuestTILEGXState* tilegx = (VexGuestTILEGXState*) get_arch (set, tst);
    153 
    154   switch (regno) {
    155   case 0: VG_(transfer) (&tilegx->guest_r0, buf, dir, size, mod); break;
    156   case 1: VG_(transfer) (&tilegx->guest_r1, buf, dir, size, mod); break;
    157   case 2: VG_(transfer) (&tilegx->guest_r2, buf, dir, size, mod); break;
    158   case 3: VG_(transfer) (&tilegx->guest_r3, buf, dir, size, mod); break;
    159   case 4: VG_(transfer) (&tilegx->guest_r4, buf, dir, size, mod); break;
    160   case 5: VG_(transfer) (&tilegx->guest_r5, buf, dir, size, mod); break;
    161   case 6: VG_(transfer) (&tilegx->guest_r6, buf, dir, size, mod); break;
    162   case 7: VG_(transfer) (&tilegx->guest_r7, buf, dir, size, mod); break;
    163   case 8: VG_(transfer) (&tilegx->guest_r8, buf, dir, size, mod); break;
    164   case 9: VG_(transfer) (&tilegx->guest_r9, buf, dir, size, mod); break;
    165   case 10: VG_(transfer) (&tilegx->guest_r10, buf, dir, size, mod); break;
    166   case 11: VG_(transfer) (&tilegx->guest_r11, buf, dir, size, mod); break;
    167   case 12: VG_(transfer) (&tilegx->guest_r12, buf, dir, size, mod); break;
    168   case 13: VG_(transfer) (&tilegx->guest_r13, buf, dir, size, mod); break;
    169   case 14: VG_(transfer) (&tilegx->guest_r14, buf, dir, size, mod); break;
    170   case 15: VG_(transfer) (&tilegx->guest_r15, buf, dir, size, mod); break;
    171   case 16: VG_(transfer) (&tilegx->guest_r16, buf, dir, size, mod); break;
    172   case 17: VG_(transfer) (&tilegx->guest_r17, buf, dir, size, mod); break;
    173   case 18: VG_(transfer) (&tilegx->guest_r18, buf, dir, size, mod); break;
    174   case 19: VG_(transfer) (&tilegx->guest_r19, buf, dir, size, mod); break;
    175   case 20: VG_(transfer) (&tilegx->guest_r20, buf, dir, size, mod); break;
    176   case 21: VG_(transfer) (&tilegx->guest_r21, buf, dir, size, mod); break;
    177   case 22: VG_(transfer) (&tilegx->guest_r22, buf, dir, size, mod); break;
    178   case 23: VG_(transfer) (&tilegx->guest_r23, buf, dir, size, mod); break;
    179   case 24: VG_(transfer) (&tilegx->guest_r24, buf, dir, size, mod); break;
    180   case 25: VG_(transfer) (&tilegx->guest_r25, buf, dir, size, mod); break;
    181   case 26: VG_(transfer) (&tilegx->guest_r26, buf, dir, size, mod); break;
    182   case 27: VG_(transfer) (&tilegx->guest_r27, buf, dir, size, mod); break;
    183   case 28: VG_(transfer) (&tilegx->guest_r28, buf, dir, size, mod); break;
    184   case 29: VG_(transfer) (&tilegx->guest_r29, buf, dir, size, mod); break;
    185   case 30: VG_(transfer) (&tilegx->guest_r30, buf, dir, size, mod); break;
    186   case 31: VG_(transfer) (&tilegx->guest_r31, buf, dir, size, mod); break;
    187   case 32: VG_(transfer) (&tilegx->guest_r32, buf, dir, size, mod); break;
    188   case 33: VG_(transfer) (&tilegx->guest_r33, buf, dir, size, mod); break;
    189   case 34: VG_(transfer) (&tilegx->guest_r34, buf, dir, size, mod); break;
    190   case 35: VG_(transfer) (&tilegx->guest_r35, buf, dir, size, mod); break;
    191   case 36: VG_(transfer) (&tilegx->guest_r36, buf, dir, size, mod); break;
    192   case 37: VG_(transfer) (&tilegx->guest_r37, buf, dir, size, mod); break;
    193   case 38: VG_(transfer) (&tilegx->guest_r38, buf, dir, size, mod); break;
    194   case 39: VG_(transfer) (&tilegx->guest_r39, buf, dir, size, mod); break;
    195   case 40: VG_(transfer) (&tilegx->guest_r40, buf, dir, size, mod); break;
    196   case 41: VG_(transfer) (&tilegx->guest_r41, buf, dir, size, mod); break;
    197   case 42: VG_(transfer) (&tilegx->guest_r42, buf, dir, size, mod); break;
    198   case 43: VG_(transfer) (&tilegx->guest_r43, buf, dir, size, mod); break;
    199   case 44: VG_(transfer) (&tilegx->guest_r44, buf, dir, size, mod); break;
    200   case 45: VG_(transfer) (&tilegx->guest_r45, buf, dir, size, mod); break;
    201   case 46: VG_(transfer) (&tilegx->guest_r46, buf, dir, size, mod); break;
    202   case 47: VG_(transfer) (&tilegx->guest_r47, buf, dir, size, mod); break;
    203   case 48: VG_(transfer) (&tilegx->guest_r48, buf, dir, size, mod); break;
    204   case 49: VG_(transfer) (&tilegx->guest_r49, buf, dir, size, mod); break;
    205   case 50: VG_(transfer) (&tilegx->guest_r50, buf, dir, size, mod); break;
    206   case 51: VG_(transfer) (&tilegx->guest_r51, buf, dir, size, mod); break;
    207   case 52: VG_(transfer) (&tilegx->guest_r52, buf, dir, size, mod); break;
    208   case 53: VG_(transfer) (&tilegx->guest_r53, buf, dir, size, mod); break;
    209   case 54: VG_(transfer) (&tilegx->guest_r54, buf, dir, size, mod); break;
    210   case 55: VG_(transfer) (&tilegx->guest_r55, buf, dir, size, mod); break;
    211   case 56: VG_(transfer) (&tilegx->guest_r56, buf, dir, size, mod); break;
    212   case 57: VG_(transfer) (&tilegx->guest_r57, buf, dir, size, mod); break;
    213   case 58: VG_(transfer) (&tilegx->guest_r58, buf, dir, size, mod); break;
    214   case 59: VG_(transfer) (&tilegx->guest_r59, buf, dir, size, mod); break;
    215   case 60: VG_(transfer) (&tilegx->guest_r60, buf, dir, size, mod); break;
    216   case 61: VG_(transfer) (&tilegx->guest_r61, buf, dir, size, mod); break;
    217   case 62: VG_(transfer) (&tilegx->guest_r62, buf, dir, size, mod); break;
    218   case 63: VG_(transfer) (&tilegx->guest_r63, buf, dir, size, mod); break;
    219   case 64: VG_(transfer) (&tilegx->guest_pc,  buf, dir, size, mod); break;
    220 
    221   default: VG_(printf)("regno: %d\n", regno); vg_assert(0);
    222   }
    223 }
    224 
    225 static
    226 const char* target_xml ( Bool shadow_mode )
    227 {
    228   return NULL;
    229 #if 0
    230   if (shadow_mode)
    231     return "tilegx-linux-valgrind.xml";
    232   else
    233     return "tilegx-linux.xml";
    234 #endif
    235 }
    236 
    237 static CORE_ADDR** target_get_dtv (ThreadState *tst)
    238 {
    239   VexGuestTILEGXState* tilegx = (VexGuestTILEGXState*)&tst->arch.vex;
    240   // tilegx dtv location similar to mips
    241   return (CORE_ADDR**)((CORE_ADDR)tilegx->guest_r53
    242                         - 0x7000 - sizeof(CORE_ADDR));
    243 }
    244 
    245 static struct valgrind_target_ops low_target = {
    246   num_regs,
    247   regs,
    248   54, //sp = r54, which is register offset 54 in regs
    249   transfer_register,
    250   get_pc,
    251   set_pc,
    252   "tilegx",
    253   target_xml,
    254   target_get_dtv
    255 };
    256 
    257 void tilegx_init_architecture ( struct valgrind_target_ops *target )
    258 {
    259   *target = low_target;
    260   set_register_cache (regs, num_regs);
    261   gdbserver_expedite_regs = expedite_regs;
    262 }
    263