1f0c1250e324f6684757c6a15545366447ef1d64fsewardj/* Low level interface to valgrind, for the remote server for GDB integrated
2f0c1250e324f6684757c6a15545366447ef1d64fsewardj   in valgrind.
30eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   Copyright (C) 2014
4f0c1250e324f6684757c6a15545366447ef1d64fsewardj   Free Software Foundation, Inc.
5f0c1250e324f6684757c6a15545366447ef1d64fsewardj
6f0c1250e324f6684757c6a15545366447ef1d64fsewardj   This file is part of VALGRIND.
7f0c1250e324f6684757c6a15545366447ef1d64fsewardj   It has been inspired from a file from gdbserver in gdb 6.6.
8f0c1250e324f6684757c6a15545366447ef1d64fsewardj
9f0c1250e324f6684757c6a15545366447ef1d64fsewardj   This program is free software; you can redistribute it and/or modify
10f0c1250e324f6684757c6a15545366447ef1d64fsewardj   it under the terms of the GNU General Public License as published by
11f0c1250e324f6684757c6a15545366447ef1d64fsewardj   the Free Software Foundation; either version 2 of the License, or
12f0c1250e324f6684757c6a15545366447ef1d64fsewardj   (at your option) any later version.
13f0c1250e324f6684757c6a15545366447ef1d64fsewardj
14f0c1250e324f6684757c6a15545366447ef1d64fsewardj   This program is distributed in the hope that it will be useful,
15f0c1250e324f6684757c6a15545366447ef1d64fsewardj   but WITHOUT ANY WARRANTY; without even the implied warranty of
16f0c1250e324f6684757c6a15545366447ef1d64fsewardj   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17f0c1250e324f6684757c6a15545366447ef1d64fsewardj   GNU General Public License for more details.
18f0c1250e324f6684757c6a15545366447ef1d64fsewardj
19f0c1250e324f6684757c6a15545366447ef1d64fsewardj   You should have received a copy of the GNU General Public License
20f0c1250e324f6684757c6a15545366447ef1d64fsewardj   along with this program; if not, write to the Free Software
21f0c1250e324f6684757c6a15545366447ef1d64fsewardj   Foundation, Inc., 51 Franklin Street, Fifth Floor,
22f0c1250e324f6684757c6a15545366447ef1d64fsewardj   Boston, MA 02110-1301, USA.  */
23f0c1250e324f6684757c6a15545366447ef1d64fsewardj
24f0c1250e324f6684757c6a15545366447ef1d64fsewardj#include "server.h"
25f0c1250e324f6684757c6a15545366447ef1d64fsewardj#include "target.h"
26f0c1250e324f6684757c6a15545366447ef1d64fsewardj#include "regdef.h"
27f0c1250e324f6684757c6a15545366447ef1d64fsewardj#include "regcache.h"
28f0c1250e324f6684757c6a15545366447ef1d64fsewardj
29987862ca3b53c1f8d4addeb55936da898ccb7d9csewardj#include "pub_core_machine.h"
30f0c1250e324f6684757c6a15545366447ef1d64fsewardj#include "pub_core_threadstate.h"
31f0c1250e324f6684757c6a15545366447ef1d64fsewardj#include "pub_core_transtab.h"
32f0c1250e324f6684757c6a15545366447ef1d64fsewardj#include "pub_core_gdbserver.h"
33f0c1250e324f6684757c6a15545366447ef1d64fsewardj#include "pub_core_debuginfo.h"
34f0c1250e324f6684757c6a15545366447ef1d64fsewardj
35f0c1250e324f6684757c6a15545366447ef1d64fsewardj#include "valgrind_low.h"
36f0c1250e324f6684757c6a15545366447ef1d64fsewardj
37f0c1250e324f6684757c6a15545366447ef1d64fsewardj#include "libvex_guest_arm64.h"
38f0c1250e324f6684757c6a15545366447ef1d64fsewardj
390eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippestatic struct reg regs[] = {
400eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x0", 0, 64 },
410eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x1", 64, 64 },
420eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x2", 128, 64 },
430eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x3", 192, 64 },
440eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x4", 256, 64 },
450eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x5", 320, 64 },
460eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x6", 384, 64 },
470eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x7", 448, 64 },
480eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x8", 512, 64 },
490eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x9", 576, 64 },
500eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x10", 640, 64 },
510eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x11", 704, 64 },
520eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x12", 768, 64 },
530eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x13", 832, 64 },
540eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x14", 896, 64 },
550eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x15", 960, 64 },
560eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x16", 1024, 64 },
570eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x17", 1088, 64 },
580eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x18", 1152, 64 },
590eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x19", 1216, 64 },
600eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x20", 1280, 64 },
610eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x21", 1344, 64 },
620eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x22", 1408, 64 },
630eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x23", 1472, 64 },
640eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x24", 1536, 64 },
650eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x25", 1600, 64 },
660eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x26", 1664, 64 },
670eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x27", 1728, 64 },
680eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x28", 1792, 64 },
690eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x29", 1856, 64 },
700eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "x30", 1920, 64 },
710eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "sp", 1984, 64 },
720eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "pc", 2048, 64 },
730eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "cpsr", 2112, 32 },
740eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v0", 2144, 128 },
750eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v1", 2272, 128 },
760eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v2", 2400, 128 },
770eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v3", 2528, 128 },
780eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v4", 2656, 128 },
790eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v5", 2784, 128 },
800eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v6", 2912, 128 },
810eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v7", 3040, 128 },
820eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v8", 3168, 128 },
830eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v9", 3296, 128 },
840eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v10", 3424, 128 },
850eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v11", 3552, 128 },
860eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v12", 3680, 128 },
870eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v13", 3808, 128 },
880eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v14", 3936, 128 },
890eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v15", 4064, 128 },
900eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v16", 4192, 128 },
910eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v17", 4320, 128 },
920eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v18", 4448, 128 },
930eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v19", 4576, 128 },
940eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v20", 4704, 128 },
950eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v21", 4832, 128 },
960eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v22", 4960, 128 },
970eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v23", 5088, 128 },
980eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v24", 5216, 128 },
990eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v25", 5344, 128 },
1000eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v26", 5472, 128 },
1010eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v27", 5600, 128 },
1020eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v28", 5728, 128 },
1030eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v29", 5856, 128 },
1040eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v30", 5984, 128 },
1050eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "v31", 6112, 128 },
1060eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "fpsr", 6240, 32 },
1070eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe  { "fpcr", 6272, 32 },
1080eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe};
1090eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe
1100eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippestatic const char *expedite_regs[] = { "x29", "sp", "pc", 0 };
1110eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe
1120eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe#define num_regs (sizeof (regs) / sizeof (regs[0]))
1130eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe
1140eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippestatic
1150eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippeCORE_ADDR get_pc (void)
1160eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe{
1170eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   unsigned long pc;
1180eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe
1190eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   collect_register_by_name ("pc", &pc);
1200eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe
1210eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   dlog(1, "stop pc is %p\n", (void *) pc);
1220eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   return pc;
1230eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe}
1240eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe
1250eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippestatic
1260eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippevoid set_pc (CORE_ADDR newpc)
1270eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe{
1280eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   Bool mod;
1290eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   supply_register_by_name ("pc", &newpc, &mod);
1300eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   if (mod)
1310eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe      dlog(1, "set pc to %p\n", C2v (newpc));
1320eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   else
1330eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe      dlog(1, "set pc not changed %p\n", C2v (newpc));
1340eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe}
1350eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe
1360eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe/* store registers in the guest state (gdbserver_to_valgrind)
1370eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   or fetch register from the guest state (valgrind_to_gdbserver). */
1380eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippestatic
1390eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippevoid transfer_register (ThreadId tid, int abs_regno, void * buf,
1400eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe                        transfer_direction dir, int size, Bool *mod)
1410eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe{
1420eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   ThreadState* tst = VG_(get_ThreadState)(tid);
1430eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   int set = abs_regno / num_regs;
1440eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   int regno = abs_regno % num_regs;
1450eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   *mod = False;
1460eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe
1470eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   VexGuestARM64State* arm = (VexGuestARM64State*) get_arch (set, tst);
1480eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe
1490eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   switch (regno) {
1500eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   // numbers here have to match the order of regs above
1510eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   // Attention: gdb order does not match valgrind order.
1520eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 0:  VG_(transfer) (&arm->guest_X0,   buf, dir, size, mod); break;
1530eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 1:  VG_(transfer) (&arm->guest_X1,   buf, dir, size, mod); break;
1540eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 2:  VG_(transfer) (&arm->guest_X2,   buf, dir, size, mod); break;
1550eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 3:  VG_(transfer) (&arm->guest_X3,   buf, dir, size, mod); break;
1560eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 4:  VG_(transfer) (&arm->guest_X4,   buf, dir, size, mod); break;
1570eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 5:  VG_(transfer) (&arm->guest_X5,   buf, dir, size, mod); break;
1580eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 6:  VG_(transfer) (&arm->guest_X6,   buf, dir, size, mod); break;
1590eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 7:  VG_(transfer) (&arm->guest_X7,   buf, dir, size, mod); break;
1600eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 8:  VG_(transfer) (&arm->guest_X8,   buf, dir, size, mod); break;
1610eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 9:  VG_(transfer) (&arm->guest_X9,   buf, dir, size, mod); break;
1620eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 10: VG_(transfer) (&arm->guest_X10,  buf, dir, size, mod); break;
1630eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 11: VG_(transfer) (&arm->guest_X11,  buf, dir, size, mod); break;
1640eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 12: VG_(transfer) (&arm->guest_X12,  buf, dir, size, mod); break;
1650eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 13: VG_(transfer) (&arm->guest_X13,  buf, dir, size, mod); break;
1660eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 14: VG_(transfer) (&arm->guest_X14,  buf, dir, size, mod); break;
1670eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 15: VG_(transfer) (&arm->guest_X15,  buf, dir, size, mod); break;
1680eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 16: VG_(transfer) (&arm->guest_X16,  buf, dir, size, mod); break;
1690eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 17: VG_(transfer) (&arm->guest_X17,  buf, dir, size, mod); break;
1700eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 18: VG_(transfer) (&arm->guest_X18,  buf, dir, size, mod); break;
1710eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 19: VG_(transfer) (&arm->guest_X19,  buf, dir, size, mod); break;
1720eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 20: VG_(transfer) (&arm->guest_X20,  buf, dir, size, mod); break;
1730eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 21: VG_(transfer) (&arm->guest_X21,  buf, dir, size, mod); break;
1740eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 22: VG_(transfer) (&arm->guest_X22,  buf, dir, size, mod); break;
1750eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 23: VG_(transfer) (&arm->guest_X23,  buf, dir, size, mod); break;
1760eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 24: VG_(transfer) (&arm->guest_X24,  buf, dir, size, mod); break;
1770eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 25: VG_(transfer) (&arm->guest_X25,  buf, dir, size, mod); break;
1780eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 26: VG_(transfer) (&arm->guest_X26,  buf, dir, size, mod); break;
1790eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 27: VG_(transfer) (&arm->guest_X27,  buf, dir, size, mod); break;
1800eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 28: VG_(transfer) (&arm->guest_X28,  buf, dir, size, mod); break;
1810eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 29: VG_(transfer) (&arm->guest_X29,  buf, dir, size, mod); break;
1820eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 30: VG_(transfer) (&arm->guest_X30,  buf, dir, size, mod); break;
1830eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 31: VG_(transfer) (&arm->guest_XSP,  buf, dir, size, mod); break;
1840eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 32: VG_(transfer) (&arm->guest_PC,   buf, dir, size, mod); break;
1853ebc6dc9f6a252ad597bb3ae76cb2f2aa3dbd24dphilippe   case 33: *mod = False; break; // GDBTD cpsr what to do for arm64 ???
1860eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe
1870eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 34: VG_(transfer) (&arm->guest_Q0,  buf, dir, size, mod); break;
1880eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 35: VG_(transfer) (&arm->guest_Q1,  buf, dir, size, mod); break;
1890eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 36: VG_(transfer) (&arm->guest_Q2,  buf, dir, size, mod); break;
1900eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 37: VG_(transfer) (&arm->guest_Q3,  buf, dir, size, mod); break;
1910eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 38: VG_(transfer) (&arm->guest_Q4,  buf, dir, size, mod); break;
1920eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 39: VG_(transfer) (&arm->guest_Q5,  buf, dir, size, mod); break;
1930eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 40: VG_(transfer) (&arm->guest_Q6,  buf, dir, size, mod); break;
1940eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 41: VG_(transfer) (&arm->guest_Q7,  buf, dir, size, mod); break;
1950eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 42: VG_(transfer) (&arm->guest_Q8,  buf, dir, size, mod); break;
1960eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 43: VG_(transfer) (&arm->guest_Q9,  buf, dir, size, mod); break;
1970eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 44: VG_(transfer) (&arm->guest_Q10, buf, dir, size, mod); break;
1980eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 45: VG_(transfer) (&arm->guest_Q11, buf, dir, size, mod); break;
1990eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 46: VG_(transfer) (&arm->guest_Q12, buf, dir, size, mod); break;
2000eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 47: VG_(transfer) (&arm->guest_Q13, buf, dir, size, mod); break;
2010eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 48: VG_(transfer) (&arm->guest_Q14, buf, dir, size, mod); break;
2020eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 49: VG_(transfer) (&arm->guest_Q15, buf, dir, size, mod); break;
2030eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 50: VG_(transfer) (&arm->guest_Q16, buf, dir, size, mod); break;
2040eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 51: VG_(transfer) (&arm->guest_Q17, buf, dir, size, mod); break;
2050eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 52: VG_(transfer) (&arm->guest_Q18, buf, dir, size, mod); break;
2060eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 53: VG_(transfer) (&arm->guest_Q19, buf, dir, size, mod); break;
2070eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 54: VG_(transfer) (&arm->guest_Q20, buf, dir, size, mod); break;
2080eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 55: VG_(transfer) (&arm->guest_Q21, buf, dir, size, mod); break;
2090eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 56: VG_(transfer) (&arm->guest_Q22, buf, dir, size, mod); break;
2100eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 57: VG_(transfer) (&arm->guest_Q23, buf, dir, size, mod); break;
2110eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 58: VG_(transfer) (&arm->guest_Q24, buf, dir, size, mod); break;
2120eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 59: VG_(transfer) (&arm->guest_Q25, buf, dir, size, mod); break;
2130eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 60: VG_(transfer) (&arm->guest_Q26, buf, dir, size, mod); break;
2140eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 61: VG_(transfer) (&arm->guest_Q27, buf, dir, size, mod); break;
2150eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 62: VG_(transfer) (&arm->guest_Q28, buf, dir, size, mod); break;
2160eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 63: VG_(transfer) (&arm->guest_Q29, buf, dir, size, mod); break;
2170eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 64: VG_(transfer) (&arm->guest_Q30, buf, dir, size, mod); break;
2180eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 65: VG_(transfer) (&arm->guest_Q31, buf, dir, size, mod); break;
219c69477a9567ff23bb77d4b6a24a8e391e29d8e0dsewardj   case 66: {
220e5d36ff3cd64b5b6ed26752099f345060246ffa3philippe      /* The VEX ARM64 FPSR representation is not the same as the
221c69477a9567ff23bb77d4b6a24a8e391e29d8e0dsewardj          architecturally defined representation.  Hence use conversion
222e5d36ff3cd64b5b6ed26752099f345060246ffa3philippe          functions to convert to/from it.
223e5d36ff3cd64b5b6ed26752099f345060246ffa3philippe          VEX FPSR only models QC (bit 27), and uses a 64 bits to store
224a0a0c6bc3ed5df4cf05db6ce90c881199152127dphilippe          this FPSR QC bit. So, we need to transfer from/to the lowest
225a0a0c6bc3ed5df4cf05db6ce90c881199152127dphilippe          significant part of the ULong that VEX provides/needs,
226a0a0c6bc3ed5df4cf05db6ce90c881199152127dphilippe          as GDB expects or gives only 4 bytes. */
227c69477a9567ff23bb77d4b6a24a8e391e29d8e0dsewardj      if (dir == valgrind_to_gdbserver) {
228ea90a0d84c254e20d1f500f9f244178c83dd66a5philippe         ULong fpsr64 = LibVEX_GuestARM64_get_fpsr(arm);
229ea90a0d84c254e20d1f500f9f244178c83dd66a5philippe         UInt fpsr = (UInt)fpsr64;
230ea90a0d84c254e20d1f500f9f244178c83dd66a5philippe         VG_(transfer) (&fpsr, buf, dir, size, mod);
231c69477a9567ff23bb77d4b6a24a8e391e29d8e0dsewardj      } else {
232ea90a0d84c254e20d1f500f9f244178c83dd66a5philippe         UInt fpsr;
233ea90a0d84c254e20d1f500f9f244178c83dd66a5philippe         ULong fpsr64;
234a0a0c6bc3ed5df4cf05db6ce90c881199152127dphilippe         VG_(transfer) ((UInt*)&fpsr, buf, dir, size, mod);
235ea90a0d84c254e20d1f500f9f244178c83dd66a5philippe         fpsr64 = fpsr;
236ea90a0d84c254e20d1f500f9f244178c83dd66a5philippe         LibVEX_GuestARM64_set_fpsr(arm, fpsr64);
237064263952263d2ef2114c8d3199ca33d4e0222c3philippe         /* resync the cache with the part of fpsr that VEX represents. */
238ea90a0d84c254e20d1f500f9f244178c83dd66a5philippe         fpsr64 = LibVEX_GuestARM64_get_fpsr(arm);
239ea90a0d84c254e20d1f500f9f244178c83dd66a5philippe         fpsr = (UInt)fpsr64;
240ea90a0d84c254e20d1f500f9f244178c83dd66a5philippe         VG_(transfer) (&fpsr, buf, valgrind_to_gdbserver, size, mod);
241c69477a9567ff23bb77d4b6a24a8e391e29d8e0dsewardj      }
242c69477a9567ff23bb77d4b6a24a8e391e29d8e0dsewardj      break;
243c69477a9567ff23bb77d4b6a24a8e391e29d8e0dsewardj   }
2440eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   case 67: VG_(transfer) (&arm->guest_FPCR, buf, dir, size, mod); break;
2450eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   default: vg_assert(0);
2460eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   }
2470eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe}
2480eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe
2490eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippestatic
2500eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippeconst char* target_xml (Bool shadow_mode)
2510eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe{
2520eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   return NULL;
2530eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe#if 0
2540eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   GDBTD
2550eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   if (shadow_mode) {
2560eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe      return "arm-with-vfpv3-valgrind.xml";
2570eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   } else {
2580eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe      return "arm-with-vfpv3.xml";
2590eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   }
2600eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe#endif
2610eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe}
2620eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe
2631670b05a4a415dbfd75b1a120713b4a206bb719ephilippestatic CORE_ADDR** target_get_dtv (ThreadState *tst)
2641670b05a4a415dbfd75b1a120713b4a206bb719ephilippe{
26587fc2a9cdecaf88c3e847a168057b2122c9cab04philippe   VexGuestARM64State* arm64 = (VexGuestARM64State*)&tst->arch.vex;
2661670b05a4a415dbfd75b1a120713b4a206bb719ephilippe   // arm64 dtv is pointed to by TPIDR_EL0.
26787fc2a9cdecaf88c3e847a168057b2122c9cab04philippe   return (CORE_ADDR**)((CORE_ADDR)arm64->guest_TPIDR_EL0);
2681670b05a4a415dbfd75b1a120713b4a206bb719ephilippe}
2691670b05a4a415dbfd75b1a120713b4a206bb719ephilippe
2700eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippestatic struct valgrind_target_ops low_target = {
2710eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   num_regs,
2720eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   regs,
2730eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   31, //SP
2740eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   transfer_register,
2750eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   get_pc,
2760eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   set_pc,
2770eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   "arm64",
2781670b05a4a415dbfd75b1a120713b4a206bb719ephilippe   target_xml,
2791670b05a4a415dbfd75b1a120713b4a206bb719ephilippe   target_get_dtv
2800eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe};
281f0c1250e324f6684757c6a15545366447ef1d64fsewardj
282f0c1250e324f6684757c6a15545366447ef1d64fsewardjvoid arm64_init_architecture (struct valgrind_target_ops *target)
283f0c1250e324f6684757c6a15545366447ef1d64fsewardj{
2840eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   *target = low_target;
2850eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   set_register_cache (regs, num_regs);
2860eb0d5a73655b8ed1b6c93d7032311a5d102a8f0philippe   gdbserver_expedite_regs = expedite_regs;
287f0c1250e324f6684757c6a15545366447ef1d64fsewardj}
288