18b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/*
28b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * gdb server stub
38b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
48b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Copyright (c) 2003-2005 Fabrice Bellard
58b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
68b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This library is free software; you can redistribute it and/or
78b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * modify it under the terms of the GNU Lesser General Public
88b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * License as published by the Free Software Foundation; either
98b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * version 2 of the License, or (at your option) any later version.
108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * This library is distributed in the hope that it will be useful,
128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * but WITHOUT ANY WARRANTY; without even the implied warranty of
138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * Lesser General Public License for more details.
158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project *
168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * You should have received a copy of the GNU Lesser General Public
179251866320b5f8329a043bb56b3a794f78d12849David 'Digit' Turner * License along with this library; if not, see <http://www.gnu.org/licenses/>.
188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "config.h"
205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "qemu-common.h"
218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_USER_ONLY
228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdlib.h>
238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdio.h>
248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <stdarg.h>
258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <string.h>
268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <errno.h>
278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <unistd.h>
288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include <fcntl.h>
298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu.h"
318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "monitor.h"
338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu-char.h"
348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "sysemu.h"
358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "gdbstub.h"
368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define MAX_PACKET_LENGTH 4096
395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#include "qemu_socket.h"
415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#include "kvm.h"
425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerenum {
455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    GDB_SIGNAL_0 = 0,
465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    GDB_SIGNAL_INT = 2,
475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    GDB_SIGNAL_TRAP = 5,
485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    GDB_SIGNAL_UNKNOWN = 143
495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_USER_ONLY
525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Map target signal numbers to GDB protocol signal numbers and vice
545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * versa.  For user emulation's currently supported systems, we can
555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner * assume most signals are defined.
565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int gdb_signal_table[] = {
595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    0,
605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGHUP,
615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGINT,
625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGQUIT,
635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGILL,
645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGTRAP,
655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGABRT,
665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1, /* SIGEMT */
675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGFPE,
685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGKILL,
695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGBUS,
705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGSEGV,
715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGSYS,
725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGPIPE,
735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGALRM,
745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGTERM,
755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGURG,
765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGSTOP,
775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGTSTP,
785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGCONT,
795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGCHLD,
805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGTTIN,
815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGTTOU,
825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGIO,
835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGXCPU,
845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGXFSZ,
855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGVTALRM,
865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGPROF,
875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGWINCH,
885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1, /* SIGLOST */
895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGUSR1,
905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGUSR2,
915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef TARGET_SIGPWR
925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGPWR,
935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1, /* SIGPOLL */
975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
1005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
1015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
1025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
1035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
1045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
1055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
1065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
1075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
1085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef __SIGRTMIN
1095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 1,
1105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 2,
1115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 3,
1125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 4,
1135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 5,
1145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 6,
1155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 7,
1165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 8,
1175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 9,
1185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 10,
1195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 11,
1205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 12,
1215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 13,
1225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 14,
1235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 15,
1245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 16,
1255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 17,
1265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 18,
1275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 19,
1285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 20,
1295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 21,
1305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 22,
1315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 23,
1325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 24,
1335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 25,
1345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 26,
1355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 27,
1365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 28,
1375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 29,
1385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 30,
1395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 31,
1405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1, /* SIGCANCEL */
1415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN,
1425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 32,
1435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 33,
1445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 34,
1455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 35,
1465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 36,
1475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 37,
1485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 38,
1495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 39,
1505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 40,
1515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 41,
1525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 42,
1535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 43,
1545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 44,
1555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 45,
1565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 46,
1575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 47,
1585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 48,
1595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 49,
1605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 50,
1615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 51,
1625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 52,
1635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 53,
1645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 54,
1655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 55,
1665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 56,
1675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 57,
1685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 58,
1695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 59,
1705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 60,
1715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 61,
1725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 62,
1735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 63,
1745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 64,
1755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 65,
1765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 66,
1775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 67,
1785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 68,
1795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 69,
1805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 70,
1815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 71,
1825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 72,
1835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 73,
1845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 74,
1855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 75,
1865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 76,
1875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 77,
1885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 78,
1895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 79,
1905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 80,
1915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 81,
1925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 82,
1935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 83,
1945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 84,
1955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 85,
1965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 86,
1975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 87,
1985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 88,
1995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 89,
2005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 90,
2015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 91,
2025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 92,
2035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 93,
2045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 94,
2055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    __SIGRTMIN + 95,
2065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1, /* SIGINFO */
2075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1, /* UNKNOWN */
2085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1, /* DEFAULT */
2095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
2105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
2115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
2125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
2135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
2145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1
2158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
2178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
2185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* In system mode we only need SIGINT and SIGTRAP; other signals
2195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   are not yet supported.  */
2205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerenum {
2225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGINT = 2,
2235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGTRAP = 5
2245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
2255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int gdb_signal_table[] = {
2275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
2285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
2295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGINT,
2305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
2315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    -1,
2325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    TARGET_SIGTRAP
2335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
2345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
2355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_USER_ONLY
2375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int target_signal_to_gdb (int sig)
2385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i;
2405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; i < ARRAY_SIZE (gdb_signal_table); i++)
2415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (gdb_signal_table[i] == sig)
2425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return i;
2435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return GDB_SIGNAL_UNKNOWN;
2445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int gdb_signal_to_target (int sig)
2485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
2495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (sig < ARRAY_SIZE (gdb_signal_table))
2505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return gdb_signal_table[sig];
2515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
2525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -1;
2535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
2545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project//#define DEBUG_GDB
2568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnertypedef struct GDBRegisterState {
2585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int base_reg;
2595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int num_regs;
2605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    gdb_reg_cb get_reg;
2615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    gdb_reg_cb set_reg;
2625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *xml;
2635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct GDBRegisterState *next;
2645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner} GDBRegisterState;
2655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
2668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectenum RSState {
2675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    RS_INACTIVE,
2688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RS_IDLE,
2698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RS_GETLINE,
2708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RS_CHKSUM1,
2718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RS_CHKSUM2,
2728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    RS_SYSCALL,
2738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
2748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projecttypedef struct GDBState {
2755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *c_cpu; /* current CPU for step/continue ops */
2765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *g_cpu; /* current CPU for other ops */
2775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *query_cpu; /* for q{f|s}ThreadInfo */
2788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    enum RSState state; /* parsing state */
2795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char line_buf[MAX_PACKET_LENGTH];
2808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int line_buf_index;
2818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int line_csum;
2825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint8_t last_packet[MAX_PACKET_LENGTH + 4];
2838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int last_packet_len;
2848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int signal;
2858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_USER_ONLY
2868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int fd;
2878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int running_state;
2888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
2898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    CharDriverState *chr;
2905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CharDriverState *mon_chr;
2918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} GDBState;
2938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* By default use no IRQs and no timers while single stepping so as to
2958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project * make single stepping like an ICE HW step.
2968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project */
2978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int sstep_flags = SSTEP_ENABLE|SSTEP_NOIRQ|SSTEP_NOTIMER;
2988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
2995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic GDBState *gdbserver_state;
3005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* This is an ugly hack to cope with both new and old gdb.
3025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   If gdb sends qXfer:features:read then assume we're talking to a newish
3035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   gdb that understands target descriptions.  */
3045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int gdb_has_xml;
3055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
3068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_USER_ONLY
3078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* XXX: This is not thread safe.  Do we care?  */
3088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int gdbserver_fd = -1;
3098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int get_char(GDBState *s)
3118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t ch;
3138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
3148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(;;) {
3165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = recv(s->fd, &ch, 1, 0);
3178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ret < 0) {
3188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (errno == ECONNRESET)
3198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->fd = -1;
3208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (errno != EINTR && errno != EAGAIN)
3218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return -1;
3228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else if (ret == 0) {
3235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            close(s->fd);
3248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->fd = -1;
3258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
3268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
3278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
3288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return ch;
3318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic gdb_syscall_complete_cb gdb_current_syscall_cb;
3358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic enum {
3378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    GDB_SYS_UNKNOWN,
3388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    GDB_SYS_ENABLED,
3398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    GDB_SYS_DISABLED,
3408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project} gdb_syscall_mode;
3418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* If gdb is connected when the first semihosting syscall occurs then use
3438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   remote gdb syscalls.  Otherwise use native file IO.  */
3448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint use_gdb_syscalls(void)
3458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (gdb_syscall_mode == GDB_SYS_UNKNOWN) {
3475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        gdb_syscall_mode = (gdbserver_state ? GDB_SYS_ENABLED
3485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                            : GDB_SYS_DISABLED);
3498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return gdb_syscall_mode == GDB_SYS_ENABLED;
3518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Resume execution.  */
3548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline void gdb_continue(GDBState *s)
3558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_USER_ONLY
3578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->running_state = 1;
3588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
3598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    vm_start();
3608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void put_buffer(GDBState *s, const uint8_t *buf, int len)
3648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_USER_ONLY
3668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
3678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (len > 0) {
3695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = send(s->fd, buf, len, 0);
3708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ret < 0) {
3718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (errno != EINTR && errno != EAGAIN)
3728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                return;
3738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
3748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            buf += ret;
3758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            len -= ret;
3768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
3778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
3788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
3798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    qemu_chr_write(s->chr, buf, len);
3808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
3818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int fromhex(int v)
3848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (v >= '0' && v <= '9')
3868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return v - '0';
3878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if (v >= 'A' && v <= 'F')
3888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return v - 'A' + 10;
3898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else if (v >= 'a' && v <= 'f')
3908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return v - 'a' + 10;
3918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
3928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return 0;
3938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
3948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
3958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic inline int tohex(int v)
3968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
3978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (v < 10)
3988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return v + '0';
3998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    else
4008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return v - 10 + 'a';
4018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void memtohex(char *buf, const uint8_t *mem, int len)
4048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i, c;
4068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *q;
4078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    q = buf;
4088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < len; i++) {
4098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        c = mem[i];
4108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *q++ = tohex(c >> 4);
4118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *q++ = tohex(c & 0xf);
4128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *q = '\0';
4148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void hextomem(uint8_t *mem, const char *buf, int len)
4178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
4198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(i = 0; i < len; i++) {
4218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        mem[i] = (fromhex(buf[0]) << 4) | fromhex(buf[1]);
4228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf += 2;
4238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* return -1 if error, 0 if OK */
4275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int put_packet_binary(GDBState *s, const char *buf, int len)
4288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
4295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int csum, i;
4308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t *p;
4318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(;;) {
4338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p = s->last_packet;
4348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *(p++) = '$';
4358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        memcpy(p, buf, len);
4368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        p += len;
4378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        csum = 0;
4388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        for(i = 0; i < len; i++) {
4398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            csum += buf[i];
4408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
4418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *(p++) = '#';
4428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *(p++) = tohex((csum >> 4) & 0xf);
4438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        *(p++) = tohex((csum) & 0xf);
4448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        s->last_packet_len = p - s->last_packet;
4468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        put_buffer(s, (uint8_t *)s->last_packet, s->last_packet_len);
4478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_USER_ONLY
4498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        i = get_char(s);
4508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (i < 0)
4518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return -1;
4528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (i == '+')
4538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
4548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
4558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
4568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
4578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
4588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
4598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
4608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
4615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* return -1 if error, 0 if OK */
4625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int put_packet(GDBState *s, const char *buf)
4635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
4645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef DEBUG_GDB
4655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    printf("reply='%s'\n", buf);
4665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return put_packet_binary(s, buf, strlen(buf));
4695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
4705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* The GDB remote protocol transfers values in target byte order.  This means
4725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   we can use the raw memory access routines to access the value buffer.
4735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   Conveniently, these also handle the case where the buffer is mis-aligned.
4745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
4755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GET_REG8(val) do { \
4765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    stb_p(mem_buf, val); \
4775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 1; \
4785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } while(0)
4795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GET_REG16(val) do { \
4805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    stw_p(mem_buf, val); \
4815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 2; \
4825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } while(0)
4835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GET_REG32(val) do { \
4845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    stl_p(mem_buf, val); \
4855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 4; \
4865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } while(0)
4875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GET_REG64(val) do { \
4885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    stq_p(mem_buf, val); \
4895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 8; \
4905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } while(0)
4915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
4925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if TARGET_LONG_BITS == 64
4935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GET_REGL(val) GET_REG64(val)
4945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define ldtul_p(addr) ldq_p(addr)
4955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
4965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GET_REGL(val) GET_REG32(val)
4975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define ldtul_p(addr) ldl_p(addr)
4985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
4995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
5008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#if defined(TARGET_I386)
5018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TARGET_X86_64
5035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic const int gpr_map[16] = {
5048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    R_EAX, R_EBX, R_ECX, R_EDX, R_ESI, R_EDI, R_EBP, R_ESP,
5055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    8, 9, 10, 11, 12, 13, 14, 15
5068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project};
5075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
5085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic const int gpr_map[8] = {0, 1, 2, 3, 4, 5, 6, 7};
5098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define NUM_CORE_REGS (CPU_NB_REGS * 2 + 25)
5128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
5145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
5155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < CPU_NB_REGS) {
5165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        GET_REGL(env->regs[gpr_map[n]]);
5175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (n >= CPU_NB_REGS + 8 && n < CPU_NB_REGS + 16) {
5185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* FIXME: byteswap float values.  */
5198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef USE_X86LDOUBLE
5205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        memcpy(mem_buf, &env->fpregs[n - (CPU_NB_REGS + 8)], 10);
5218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
5225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        memset(mem_buf, 0, 10);
5238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 10;
5255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (n >= CPU_NB_REGS + 24) {
5265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        n -= CPU_NB_REGS + 24;
5275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (n < CPU_NB_REGS) {
5285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            stq_p(mem_buf, env->xmm_regs[n].XMM_Q(0));
5295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            stq_p(mem_buf + 8, env->xmm_regs[n].XMM_Q(1));
5305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 16;
5315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (n == CPU_NB_REGS) {
5325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            GET_REG32(env->mxcsr);
5335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
5345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
5355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        n -= CPU_NB_REGS;
5365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch (n) {
5375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 0: GET_REGL(env->eip);
5385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 1: GET_REG32(env->eflags);
5395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 2: GET_REG32(env->segs[R_CS].selector);
5405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 3: GET_REG32(env->segs[R_SS].selector);
5415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 4: GET_REG32(env->segs[R_DS].selector);
5425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 5: GET_REG32(env->segs[R_ES].selector);
5435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 6: GET_REG32(env->segs[R_FS].selector);
5445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 7: GET_REG32(env->segs[R_GS].selector);
5455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* 8...15 x87 regs.  */
5465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 16: GET_REG32(env->fpuc);
5475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 17: GET_REG32((env->fpus & ~0x3800) | (env->fpstt & 0x7) << 11);
5485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 18: GET_REG32(0); /* ftag */
5495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 19: GET_REG32(0); /* fiseg */
5505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 20: GET_REG32(0); /* fioff */
5515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 21: GET_REG32(0); /* foseg */
5525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 22: GET_REG32(0); /* fooff */
5535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 23: GET_REG32(0); /* fop */
5545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* 24+ xmm regs.  */
5555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
5568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
5575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
5588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
5598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int i)
5618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
5625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t tmp;
5638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
5645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (i < CPU_NB_REGS) {
5655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->regs[gpr_map[i]] = ldtul_p(mem_buf);
5665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return sizeof(target_ulong);
5675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (i >= CPU_NB_REGS + 8 && i < CPU_NB_REGS + 16) {
5685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        i -= CPU_NB_REGS + 8;
5695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef USE_X86LDOUBLE
5705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        memcpy(&env->fpregs[i], mem_buf, 10);
5718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 10;
5735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (i >= CPU_NB_REGS + 24) {
5745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        i -= CPU_NB_REGS + 24;
5755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (i < CPU_NB_REGS) {
5765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            env->xmm_regs[i].XMM_Q(0) = ldq_p(mem_buf);
5775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            env->xmm_regs[i].XMM_Q(1) = ldq_p(mem_buf + 8);
5785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 16;
5795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (i == CPU_NB_REGS) {
5805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            env->mxcsr = ldl_p(mem_buf);
5815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 4;
5828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
5835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
5845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        i -= CPU_NB_REGS;
5855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch (i) {
5865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 0: env->eip = ldtul_p(mem_buf); return sizeof(target_ulong);
5875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 1: env->eflags = ldl_p(mem_buf); return 4;
5885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_USER_ONLY)
5895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define LOAD_SEG(index, sreg)\
5905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            tmp = ldl_p(mem_buf);\
5915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (tmp != env->segs[sreg].selector)\
5925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                cpu_x86_load_seg(env, sreg, tmp);
5935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
5945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* FIXME: Honor segment registers.  Needs to avoid raising an exception
5955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   when the selector is invalid.  */
5965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define LOAD_SEG(index, sreg) do {} while(0)
5978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
5985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 2: LOAD_SEG(10, R_CS); return 4;
5995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 3: LOAD_SEG(11, R_SS); return 4;
6005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 4: LOAD_SEG(12, R_DS); return 4;
6015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 5: LOAD_SEG(13, R_ES); return 4;
6025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 6: LOAD_SEG(14, R_FS); return 4;
6035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 7: LOAD_SEG(15, R_GS); return 4;
6045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* 8...15 x87 regs.  */
6055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 16: env->fpuc = ldl_p(mem_buf); return 4;
6065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 17:
6075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 tmp = ldl_p(mem_buf);
6085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 env->fpstt = (tmp >> 11) & 7;
6095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 env->fpus = tmp & ~0x3800;
6105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 return 4;
6115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 18: /* ftag */ return 4;
6125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 19: /* fiseg */ return 4;
6135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 20: /* fioff */ return 4;
6145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 21: /* foseg */ return 4;
6155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 22: /* fooff */ return 4;
6165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 23: /* fop */ return 4;
6175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* 24+ xmm regs.  */
6188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
6198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
6205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Unrecognised register.  */
6215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
6228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined (TARGET_PPC)
6258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Old gdb always expects FP registers.  Newer (xml-aware) gdb only
6275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   expects whatever the target description contains.  Due to a
6285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   historical mishap the FP registers appear in between core integer
6295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   regs and PC, MSR, CR, and so forth.  We hack round this by giving the
6305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   FP regs zero size when talking to a newer gdb.  */
6315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define NUM_CORE_REGS 71
6325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined (TARGET_PPC64)
6335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GDB_CORE_XML "power64-core.xml"
6345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
6355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GDB_CORE_XML "power-core.xml"
6365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
6378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
6395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
6405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 32) {
6415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* gprs */
6425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        GET_REGL(env->gpr[n]);
6435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (n < 64) {
6445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* fprs */
6455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (gdb_has_xml)
6465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 0;
6475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        stfq_p(mem_buf, env->fpr[n-32]);
6485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 8;
6495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
6505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch (n) {
6515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 64: GET_REGL(env->nip);
6525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 65: GET_REGL(env->msr);
6535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 66:
6545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            {
6555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                uint32_t cr = 0;
6565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                int i;
6575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                for (i = 0; i < 8; i++)
6585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    cr |= env->crf[i] << (32 - ((i + 1) * 4));
6595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                GET_REG32(cr);
6605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
6615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 67: GET_REGL(env->lr);
6625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 68: GET_REGL(env->ctr);
6635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 69: GET_REGL(env->xer);
6645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 70:
6655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            {
6665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                if (gdb_has_xml)
6675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    return 0;
6685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                GET_REG32(0); /* fpscr */
6695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
6705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
6715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
6725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
6738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
6748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
6755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
6768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
6775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 32) {
6785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* gprs */
6795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->gpr[n] = ldtul_p(mem_buf);
6805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return sizeof(target_ulong);
6815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (n < 64) {
6825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* fprs */
6835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (gdb_has_xml)
6845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 0;
6855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->fpr[n-32] = ldfq_p(mem_buf);
6865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 8;
6875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
6885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch (n) {
6895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 64:
6905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            env->nip = ldtul_p(mem_buf);
6915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return sizeof(target_ulong);
6925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 65:
6935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            ppc_store_msr(env, ldtul_p(mem_buf));
6945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return sizeof(target_ulong);
6955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 66:
6965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            {
6975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                uint32_t cr = ldl_p(mem_buf);
6985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                int i;
6995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                for (i = 0; i < 8; i++)
7005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    env->crf[i] = (cr >> (32 - ((i + 1) * 4))) & 0xF;
7015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return 4;
7025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
7035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 67:
7045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            env->lr = ldtul_p(mem_buf);
7055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return sizeof(target_ulong);
7065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 68:
7075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            env->ctr = ldtul_p(mem_buf);
7085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return sizeof(target_ulong);
7095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 69:
7105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            env->xer = ldtul_p(mem_buf);
7115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return sizeof(target_ulong);
7125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 70:
7135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* fpscr */
7145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (gdb_has_xml)
7155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                return 0;
7165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 4;
7175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
7185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
7208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined (TARGET_SPARC)
7235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_SPARC64) && !defined(TARGET_ABI32)
7255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define NUM_CORE_REGS 86
7268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
7275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define NUM_CORE_REGS 72
7288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef TARGET_ABI32
7315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GET_REGA(val) GET_REG32(val)
7328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
7335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GET_REGA(val) GET_REGL(val)
7348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
7375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
7385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 8) {
7395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* g0..g7 */
7405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        GET_REGA(env->gregs[n]);
7418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 32) {
7435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* register window */
7445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        GET_REGA(env->regwptr[n - 8]);
7458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
7475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 64) {
7485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* fprs */
7495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        GET_REG32(*((uint32_t *)&env->fpr[n - 32]));
7508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
7525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (n) {
7535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 64: GET_REGA(env->y);
7545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 65: GET_REGA(GET_PSR(env));
7555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 66: GET_REGA(env->wim);
7565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 67: GET_REGA(env->tbr);
7575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 68: GET_REGA(env->pc);
7585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 69: GET_REGA(env->npc);
7595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 70: GET_REGA(env->fsr);
7605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 71: GET_REGA(0); /* csr */
7615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default: GET_REGA(0);
7625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
7645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 64) {
7655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* f0-f31 */
7665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        GET_REG32(*((uint32_t *)&env->fpr[n - 32]));
7675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 80) {
7695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* f32-f62 (double width, even numbers only) */
7705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        uint64_t val;
7718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        val = (uint64_t)*((uint32_t *)&env->fpr[(n - 64) * 2 + 32]) << 32;
7735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        val |= *((uint32_t *)&env->fpr[(n - 64) * 2 + 33]);
7745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        GET_REG64(val);
7758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
7765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (n) {
7775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 80: GET_REGL(env->pc);
7785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 81: GET_REGL(env->npc);
7795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 82: GET_REGL(((uint64_t)GET_CCR(env) << 32) |
7808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                           ((env->asi & 0xff) << 24) |
7818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                           ((env->pstate & 0xfff) << 8) |
7828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                           GET_CWP64(env));
7835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 83: GET_REGL(env->fsr);
7845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 84: GET_REGL(env->fprs);
7855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 85: GET_REGL(env->y);
7865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
7878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
7885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
7898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
7908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
7915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
7928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
7935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_ABI32)
7945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    abi_ulong tmp;
7955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
7965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tmp = ldl_p(mem_buf);
7978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
7985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    target_ulong tmp;
7995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
8005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tmp = ldtul_p(mem_buf);
8018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 8) {
8045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* g0..g7 */
8055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->gregs[n] = tmp;
8065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (n < 32) {
8075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* register window */
8085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->regwptr[n - 8] = tmp;
8098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_ABI32) || !defined(TARGET_SPARC64)
8115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (n < 64) {
8125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* fprs */
8135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        *((uint32_t *)&env->fpr[n - 32]) = tmp;
8145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
8155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Y, PSR, WIM, TBR, PC, NPC, FPSR, CPSR */
8165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch (n) {
8175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 64: env->y = tmp; break;
8185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 65: PUT_PSR(env, tmp); break;
8195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 66: env->wim = tmp; break;
8205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 67: env->tbr = tmp; break;
8215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 68: env->pc = tmp; break;
8225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 69: env->npc = tmp; break;
8235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 70: env->fsr = tmp; break;
8245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default: return 0;
8255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
8268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 4;
8288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
8295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (n < 64) {
8305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* f0-f31 */
8315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->fpr[n] = ldfl_p(mem_buf);
8325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 4;
8335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (n < 80) {
8345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* f32-f62 (double width, even numbers only) */
8355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        *((uint32_t *)&env->fpr[(n - 64) * 2 + 32]) = tmp >> 32;
8365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        *((uint32_t *)&env->fpr[(n - 64) * 2 + 33]) = tmp;
8375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
8385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch (n) {
8395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 80: env->pc = tmp; break;
8405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 81: env->npc = tmp; break;
8415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 82:
8425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    PUT_CCR(env, tmp >> 32);
8435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    env->asi = (tmp >> 24) & 0xff;
8445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    env->pstate = (tmp >> 8) & 0xfff;
8455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    PUT_CWP64(env, tmp & 0xff);
8465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    break;
8475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 83: env->fsr = tmp; break;
8485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 84: env->fprs = tmp; break;
8495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 85: env->y = tmp; break;
8505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default: return 0;
8515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
8528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 8;
8548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
8558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined (TARGET_ARM)
8578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Old gdb always expect FPA registers.  Newer (xml-aware) gdb only expect
8595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   whatever the target description contains.  Due to a historical mishap
8605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   the FPA registers appear in between core integer regs and the CPSR.
8615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   We hack round this by giving the FPA regs zero size when talking to a
8625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   newer gdb.  */
8635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define NUM_CORE_REGS 26
8645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GDB_CORE_XML "arm-core.xml"
8658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
8678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 16) {
8695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Core integer register.  */
8705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        GET_REG32(env->regs[n]);
8718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 24) {
8735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* FPA registers.  */
8745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (gdb_has_xml)
8755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 0;
8765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        memset(mem_buf, 0, 12);
8775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 12;
8788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (n) {
8805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 24:
8815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* FPA status register.  */
8825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (gdb_has_xml)
8835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 0;
8845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        GET_REG32(0);
8855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 25:
8865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* CPSR */
8875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        GET_REG32(cpsr_read(env));
8888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
8895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Unknown register.  */
8905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
8918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
8928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
8948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
8955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t tmp;
8968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tmp = ldl_p(mem_buf);
8988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
8995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Mask out low bit of PC to workaround gdb bugs.  This will probably
9005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       cause problems if we ever implement the Jazelle DBX extensions.  */
9015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n == 15)
9025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        tmp &= ~1;
9038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 16) {
9055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Core integer register.  */
9065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->regs[n] = tmp;
9075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 4;
9085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
9095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 24) { /* 16-23 */
9105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* FPA registers (ignored).  */
9115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (gdb_has_xml)
9125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 0;
9135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 12;
9145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
9155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (n) {
9165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 24:
9175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* FPA status register (ignored).  */
9185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (gdb_has_xml)
9195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return 0;
9205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 4;
9215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 25:
9225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* CPSR */
9235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpsr_write (env, tmp, 0xffffffff);
9245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 4;
9255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
9265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Unknown register.  */
9275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
9285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined (TARGET_M68K)
9318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define NUM_CORE_REGS 18
9338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define GDB_CORE_XML "cf-core.xml"
9358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
9375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 8) {
9395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* D0-D7 */
9405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        GET_REG32(env->dregs[n]);
9415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (n < 16) {
9425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* A0-A7 */
9435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        GET_REG32(env->aregs[n - 8]);
9445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
9455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	switch (n) {
9465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 16: GET_REG32(env->sr);
9475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 17: GET_REG32(env->pc);
9485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
9495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
9505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* FP registers not included here because they vary between
9515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       ColdFire and m68k.  Use XML bits for these.  */
9525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
9535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
9565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t tmp;
9588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tmp = ldl_p(mem_buf);
9608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 8) {
9625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* D0-D7 */
9635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->dregs[n] = tmp;
9645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (n < 8) {
9655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* A0-A7 */
9665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->aregs[n - 8] = tmp;
9675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
9685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch (n) {
9695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 16: env->sr = tmp; break;
9705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 17: env->pc = tmp; break;
9715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default: return 0;
9725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
9735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
9745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 4;
9755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
9765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined (TARGET_MIPS)
9778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define NUM_CORE_REGS 73
9798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
9805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
9815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
9825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 32) {
9835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        GET_REGL(env->active_tc.gpr[n]);
9845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
9855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
9865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (n >= 38 && n < 70) {
9875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (env->CP0_Status & (1 << CP0St_FR))
9885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		GET_REGL(env->active_fpu.fpr[n - 38].d);
9895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            else
9905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner		GET_REGL(env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX]);
9915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
9925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch (n) {
9935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 70: GET_REGL((int32_t)env->active_fpu.fcr31);
9945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 71: GET_REGL((int32_t)env->active_fpu.fcr0);
9955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
9965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
9975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (n) {
9985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 32: GET_REGL((int32_t)env->CP0_Status);
9995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 33: GET_REGL(env->active_tc.LO[0]);
10005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 34: GET_REGL(env->active_tc.HI[0]);
10015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 35: GET_REGL(env->CP0_BadVAddr);
10025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 36: GET_REGL((int32_t)env->CP0_Cause);
10035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 37: GET_REGL(env->active_tc.PC);
10045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 72: GET_REGL(0); /* fp */
10055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 89: GET_REGL((int32_t)env->CP0_PRid);
10065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
10075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n >= 73 && n <= 88) {
10085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* 16 embedded regs.  */
10095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	GET_REGL(0);
10105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
10118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
10138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
10148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* convert MIPS rounding mode in FCR31 to IEEE library */
10168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic unsigned int ieee_rm[] =
10178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  {
10188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float_round_nearest_even,
10198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float_round_to_zero,
10208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float_round_up,
10218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    float_round_down
10228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  };
10238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#define RESTORE_ROUNDING_MODE \
10245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    set_float_rounding_mode(ieee_rm[env->active_fpu.fcr31 & 3], &env->active_fpu.fp_status)
10258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
10278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
10285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    target_ulong tmp;
10298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tmp = ldtul_p(mem_buf);
10318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 32) {
10335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->active_tc.gpr[n] = tmp;
10345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return sizeof(target_ulong);
10355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
10365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (env->CP0_Config1 & (1 << CP0C1_FP)
10375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            && n >= 38 && n < 73) {
10385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (n < 70) {
10395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (env->CP0_Status & (1 << CP0St_FR))
10405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner              env->active_fpu.fpr[n - 38].d = tmp;
10415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            else
10425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner              env->active_fpu.fpr[n - 38].w[FP_ENDIAN_IDX] = tmp;
10435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
10445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch (n) {
10455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 70:
10465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            env->active_fpu.fcr31 = tmp & 0xFF83FFFF;
10475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* set rounding mode */
10485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            RESTORE_ROUNDING_MODE;
10495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_SOFTFLOAT
10505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* no floating point exception for native float */
10515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            SET_FP_ENABLE(env->active_fpu.fcr31, 0);
10525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
10535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
10545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 71: env->active_fpu.fcr0 = tmp; break;
10555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
10565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return sizeof(target_ulong);
10575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
10585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (n) {
10595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 32: env->CP0_Status = tmp; break;
10605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 33: env->active_tc.LO[0] = tmp; break;
10615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 34: env->active_tc.HI[0] = tmp; break;
10625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 35: env->CP0_BadVAddr = tmp; break;
10635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 36: env->CP0_Cause = tmp; break;
10645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 37: env->active_tc.PC = tmp; break;
10655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 72: /* fp, ignored */ break;
10665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default:
10675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	if (n > 89)
10685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	    return 0;
10695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	/* Other registers are readonly.  Ignore writes.  */
10705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	break;
10715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
10728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return sizeof(target_ulong);
10745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
10755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined (TARGET_SH4)
10768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Hint: Use "set architecture sh4" in GDB to see fpu registers */
10785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* FIXME: We should use XML for this.  */
10798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define NUM_CORE_REGS 59
10818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
10825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
10835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
10845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 8) {
10855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
10865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            GET_REGL(env->gregs[n + 16]);
10875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
10885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            GET_REGL(env->gregs[n]);
10895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
10905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (n < 16) {
10915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        GET_REGL(env->gregs[n - 8]);
10925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (n >= 25 && n < 41) {
10935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	GET_REGL(env->fregs[(n - 25) + ((env->fpscr & FPSCR_FR) ? 16 : 0)]);
10945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (n >= 43 && n < 51) {
10955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	GET_REGL(env->gregs[n - 43]);
10965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (n >= 51 && n < 59) {
10975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	GET_REGL(env->gregs[n - (51 - 16)]);
10985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
10995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (n) {
11005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 16: GET_REGL(env->pc);
11015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 17: GET_REGL(env->pr);
11025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 18: GET_REGL(env->gbr);
11035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 19: GET_REGL(env->vbr);
11045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 20: GET_REGL(env->mach);
11055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 21: GET_REGL(env->macl);
11065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 22: GET_REGL(env->sr);
11075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 23: GET_REGL(env->fpul);
11085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 24: GET_REGL(env->fpscr);
11095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 41: GET_REGL(env->ssr);
11105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 42: GET_REGL(env->spc);
11115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
11145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
11175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t tmp;
11198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tmp = ldl_p(mem_buf);
11218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 8) {
11235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if ((env->sr & (SR_MD | SR_RB)) == (SR_MD | SR_RB)) {
11245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            env->gregs[n + 16] = tmp;
11255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
11265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            env->gregs[n] = tmp;
11275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
11285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	return 4;
11295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (n < 16) {
11305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->gregs[n - 8] = tmp;
11315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	return 4;
11325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (n >= 25 && n < 41) {
11335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	env->fregs[(n - 25) + ((env->fpscr & FPSCR_FR) ? 16 : 0)] = tmp;
11345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (n >= 43 && n < 51) {
11355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	env->gregs[n - 43] = tmp;
11365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	return 4;
11375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else if (n >= 51 && n < 59) {
11385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	env->gregs[n - (51 - 16)] = tmp;
11395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	return 4;
11405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (n) {
11425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 16: env->pc = tmp;
11435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 17: env->pr = tmp;
11445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 18: env->gbr = tmp;
11455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 19: env->vbr = tmp;
11465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 20: env->mach = tmp;
11475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 21: env->macl = tmp;
11485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 22: env->sr = tmp;
11495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 23: env->fpul = tmp;
11505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 24: env->fpscr = tmp;
11515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 41: env->ssr = tmp;
11525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 42: env->spc = tmp;
11535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default: return 0;
11545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 4;
11578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined (TARGET_MICROBLAZE)
11598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define NUM_CORE_REGS (32 + 5)
11618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
11638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 32) {
11655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	GET_REG32(env->regs[n]);
11665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
11675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	GET_REG32(env->sregs[n - 32]);
11685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
11705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
11718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
11735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
11745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t tmp;
11755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n > NUM_CORE_REGS)
11775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	return 0;
11785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tmp = ldl_p(mem_buf);
11805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 32) {
11825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	env->regs[n] = tmp;
11835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
11845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	env->sregs[n - 32] = tmp;
11855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
11865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 4;
11878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
11888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#elif defined (TARGET_CRIS)
11898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
11905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define NUM_CORE_REGS 49
11915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
11938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
11945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint8_t srs;
11955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
11965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    srs = env->pregs[PR_SRS];
11975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 16) {
11985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	GET_REG32(env->regs[n]);
11995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n >= 21 && n < 32) {
12025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	GET_REG32(env->pregs[n - 16]);
12035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n >= 33 && n < 49) {
12055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	GET_REG32(env->sregs[srs][n - 33]);
12065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (n) {
12085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 16: GET_REG8(env->pregs[0]);
12095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 17: GET_REG8(env->pregs[1]);
12105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 18: GET_REG32(env->pregs[2]);
12115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 19: GET_REG8(srs);
12125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 20: GET_REG16(env->pregs[4]);
12135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 32: GET_REG32(env->pc);
12145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
12178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
12208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t tmp;
12225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n > 49)
12245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	return 0;
12255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tmp = ldl_p(mem_buf);
12275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 16) {
12295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	env->regs[n] = tmp;
12305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n >= 21 && n < 32) {
12335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	env->pregs[n - 16] = tmp;
12345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* FIXME: Should support function regs be writable?  */
12375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (n) {
12385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 16: return 1;
12395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 17: return 1;
12405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 18: env->pregs[PR_PID] = tmp; break;
12415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 19: return 1;
12425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 20: return 2;
12435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 32: env->pc = tmp; break;
12445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 4;
12478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined (TARGET_ALPHA)
12495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define NUM_CORE_REGS 65
12515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
12538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 31) {
12555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       GET_REGL(env->ir[n]);
12565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (n == 31) {
12585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       GET_REGL(0);
12595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (n<63) {
12615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       uint64_t val;
12625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       val=*((uint64_t *)&env->fir[n-32]);
12645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       GET_REGL(val);
12655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (n==63) {
12675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       GET_REGL(env->fpcr);
12685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else if (n==64) {
12705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       GET_REGL(env->pc);
12715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else {
12735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       GET_REGL(0);
12745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
12778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
12788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
12795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
12808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
12815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    target_ulong tmp;
12825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    tmp = ldtul_p(mem_buf);
12835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n < 31) {
12855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->ir[n] = tmp;
12865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n > 31 && n < 63) {
12895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env->fir[n - 32] = ldfl_p(mem_buf);
12905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (n == 64 ) {
12935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner       env->pc=tmp;
12945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
12955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
12965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 8;
12975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
12985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
12998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#define NUM_CORE_REGS 0
13018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_read_register(CPUState *env, uint8_t *mem_buf, int n)
13035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
13045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
13055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
13068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int cpu_gdb_write_register(CPUState *env, uint8_t *mem_buf, int n)
13085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
13095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
13105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
13118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
13138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int num_g_regs = NUM_CORE_REGS;
13158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef GDB_CORE_XML
13175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Encode data using the encoding for 'x' packets.  */
13185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int memtox(char *buf, const char *mem, int len)
13195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
13205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char *p = buf;
13215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char c;
13225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (len--) {
13245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        c = *(mem++);
13255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        switch (c) {
13265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case '#': case '$': case '*': case '}':
13275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *(p++) = '}';
13285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *(p++) = c ^ 0x20;
13295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
13305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        default:
13315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            *(p++) = c;
13325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
13335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
13345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return p - buf;
13365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
13378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic const char *get_feature_xml(const char *p, const char **newp)
13395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
13405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    extern const char *const xml_builtin[][2];
13415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    size_t len;
13425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int i;
13435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *name;
13445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    static char target_xml[1024];
13455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    len = 0;
13475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (p[len] && p[len] != ':')
13485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        len++;
13495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *newp = p + len;
13505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    name = NULL;
13525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strncmp(p, "target.xml", len) == 0) {
13535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Generate the XML description for this CPU.  */
13545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!target_xml[0]) {
13555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            GDBRegisterState *r;
13565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            snprintf(target_xml, sizeof(target_xml),
13585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                     "<?xml version=\"1.0\"?>"
13595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                     "<!DOCTYPE target SYSTEM \"gdb-target.dtd\">"
13605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                     "<target>"
13615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                     "<xi:include href=\"%s\"/>",
13625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                     GDB_CORE_XML);
13635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            for (r = first_cpu->gdb_regs; r; r = r->next) {
13655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                pstrcat(target_xml, sizeof(target_xml), "<xi:include href=\"");
13665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                pstrcat(target_xml, sizeof(target_xml), r->xml);
13675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                pstrcat(target_xml, sizeof(target_xml), "\"/>");
13685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
13695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            pstrcat(target_xml, sizeof(target_xml), "</target>");
13705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
13715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return target_xml;
13725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (i = 0; ; i++) {
13745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        name = xml_builtin[i][0];
13755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!name || (strncmp(name, p, len) == 0 && strlen(name) == len))
13765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
13775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return name ? xml_builtin[i][1] : NULL;
13798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
13818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int gdb_read_register(CPUState *env, uint8_t *mem_buf, int reg)
13838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    GDBRegisterState *r;
13858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
13865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (reg < NUM_CORE_REGS)
13875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return cpu_gdb_read_register(env, mem_buf, reg);
13885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (r = env->gdb_regs; r; r = r->next) {
13905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
13915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return r->get_reg(env, mem_buf, reg - r->base_reg);
13925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
13935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
13945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return 0;
13958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
13965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
13975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int gdb_write_register(CPUState *env, uint8_t *mem_buf, int reg)
13988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
13995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    GDBRegisterState *r;
14005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (reg < NUM_CORE_REGS)
14025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return cpu_gdb_write_register(env, mem_buf, reg);
14035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (r = env->gdb_regs; r; r = r->next) {
14055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (r->base_reg <= reg && reg < r->base_reg + r->num_regs) {
14065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return r->set_reg(env, mem_buf, reg - r->base_reg);
14075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
14085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
14098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
14108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Register a supplemental set of CPU registers.  If g_pos is nonzero it
14135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   specifies the first register number and these registers are included in
14145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   a standard "g" packet.  Direction is relative to gdb, i.e. get_reg is
14155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   gdb reading a CPU register, and set_reg is gdb modifying a CPU register.
14165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner */
14175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid gdb_register_coprocessor(CPUState * env,
14195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             gdb_reg_cb get_reg, gdb_reg_cb set_reg,
14205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                             int num_regs, const char *xml, int g_pos)
14218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    GDBRegisterState *s;
14235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    GDBRegisterState **p;
14245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    static int last_reg = NUM_CORE_REGS;
14255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s = (GDBRegisterState *)qemu_mallocz(sizeof(GDBRegisterState));
14275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->base_reg = last_reg;
14285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->num_regs = num_regs;
14295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->get_reg = get_reg;
14305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->set_reg = set_reg;
14315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->xml = xml;
14325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    p = &env->gdb_regs;
14335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    while (*p) {
14345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Check for duplicates.  */
14355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (strcmp((*p)->xml, xml) == 0)
14365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return;
14375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        p = &(*p)->next;
14385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
14395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    /* Add to end of list.  */
14405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    last_reg += num_regs;
14415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    *p = s;
14425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (g_pos) {
14435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (g_pos != s->base_reg) {
14445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            fprintf(stderr, "Error: Bad gdb register numbering for '%s'\n"
14455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                    "Expected %d got %d\n", xml, g_pos, s->base_reg);
14465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
14475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            num_g_regs = last_reg;
14485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
14495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
14508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
14518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_USER_ONLY
14535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic const int xlat_gdb_type[] = {
14545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    [GDB_WATCHPOINT_WRITE]  = BP_GDB | BP_MEM_WRITE,
14555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    [GDB_WATCHPOINT_READ]   = BP_GDB | BP_MEM_READ,
14565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    [GDB_WATCHPOINT_ACCESS] = BP_GDB | BP_MEM_ACCESS,
14575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner};
14585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
14595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int gdb_breakpoint_insert(target_ulong addr, target_ulong len, int type)
14615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
14625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env;
14635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int err = 0;
14645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled())
14665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return kvm_insert_breakpoint(gdbserver_state->c_cpu, addr, len, type);
14675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (type) {
14695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case GDB_BREAKPOINT_SW:
14705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case GDB_BREAKPOINT_HW:
14715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (env = first_cpu; env != NULL; env = env->next_cpu) {
14725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            err = cpu_breakpoint_insert(env, addr, BP_GDB, NULL);
14735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (err)
14745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
14755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
14765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return err;
14775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_USER_ONLY
14785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case GDB_WATCHPOINT_WRITE:
14795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case GDB_WATCHPOINT_READ:
14805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case GDB_WATCHPOINT_ACCESS:
14815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (env = first_cpu; env != NULL; env = env->next_cpu) {
14825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            err = cpu_watchpoint_insert(env, addr, len, xlat_gdb_type[type],
14835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                                        NULL);
14845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (err)
14855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
14865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
14875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return err;
14888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
14895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default:
14905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -ENOSYS;
14915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
14925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
14938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
14945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int gdb_breakpoint_remove(target_ulong addr, target_ulong len, int type)
14958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
14965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env;
14975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int err = 0;
14985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
14995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled())
15005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return kvm_remove_breakpoint(gdbserver_state->c_cpu, addr, len, type);
15015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    switch (type) {
15035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case GDB_BREAKPOINT_SW:
15045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case GDB_BREAKPOINT_HW:
15055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (env = first_cpu; env != NULL; env = env->next_cpu) {
15065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            err = cpu_breakpoint_remove(env, addr, BP_GDB);
15075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (err)
15085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
15095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
15105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return err;
15115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_USER_ONLY
15125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case GDB_WATCHPOINT_WRITE:
15135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case GDB_WATCHPOINT_READ:
15145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case GDB_WATCHPOINT_ACCESS:
15155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (env = first_cpu; env != NULL; env = env->next_cpu) {
15165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            err = cpu_watchpoint_remove(env, addr, len, xlat_gdb_type[type]);
15175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (err)
15185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
15195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
15205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return err;
15215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
15225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    default:
15235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return -ENOSYS;
15245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
15255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
15265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void gdb_breakpoint_remove_all(void)
15285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
15295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env;
15305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (kvm_enabled()) {
15325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        kvm_remove_all_breakpoints(gdbserver_state->c_cpu);
15335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return;
15345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
15355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (env = first_cpu; env != NULL; env = env->next_cpu) {
15375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_breakpoint_remove_all(env, BP_GDB);
15385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef CONFIG_USER_ONLY
15395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_watchpoint_remove_all(env, BP_GDB);
15405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
15415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
15425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
15435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void gdb_set_cpu_pc(GDBState *s, target_ulong pc)
15455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
15465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(TARGET_I386)
15475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->c_cpu->eip = pc;
15485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cpu_synchronize_state(s->c_cpu, 1);
15495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined (TARGET_PPC)
15505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->c_cpu->nip = pc;
15515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined (TARGET_SPARC)
15525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->c_cpu->pc = pc;
15535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->c_cpu->npc = pc + 4;
15545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined (TARGET_ARM)
15555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->c_cpu->regs[15] = pc;
15565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined (TARGET_SH4)
15575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->c_cpu->pc = pc;
15585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined (TARGET_MIPS)
15595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->c_cpu->active_tc.PC = pc;
15605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined (TARGET_MICROBLAZE)
15615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->c_cpu->sregs[SR_PC] = pc;
15625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined (TARGET_CRIS)
15635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->c_cpu->pc = pc;
15645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#elif defined (TARGET_ALPHA)
15655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->c_cpu->pc = pc;
15665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
15675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
15685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic inline int gdb_id(CPUState *env)
15705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
15715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#if defined(CONFIG_USER_ONLY) && defined(USE_NPTL)
15725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return env->host_tid;
15735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else
15745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return env->cpu_index + 1;
15755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
15765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
15775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic CPUState *find_cpu(uint32_t thread_id)
15795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
15805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env;
15815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (env = first_cpu; env != NULL; env = env->next_cpu) {
15835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (gdb_id(env) == thread_id) {
15845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return env;
15855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
15865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
15875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return NULL;
15895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
15905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
15915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int gdb_handle_packet(GDBState *s, const char *line_buf)
15925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
15935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env;
15948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    const char *p;
15955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint32_t thread;
15965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int ch, reg_size, type, res;
15975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char buf[MAX_PACKET_LENGTH];
15985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint8_t mem_buf[MAX_PACKET_LENGTH];
15995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    uint8_t *registers;
16008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    target_ulong addr, len;
16018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_GDB
16038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    printf("command='%s'\n", line_buf);
16048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
16058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p = line_buf;
16068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    ch = *p++;
16078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch(ch) {
16088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case '?':
16098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* TODO: Make this return the correct value for user-mode.  */
16105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,
16115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                 gdb_id(s->c_cpu));
16128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        put_packet(s, buf);
16138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Remove all the breakpoints when this query is issued,
16148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         * because gdb is doing and initial connect and the state
16158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         * should be cleaned up.
16168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project         */
16175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        gdb_breakpoint_remove_all();
16188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
16198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 'c':
16208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (*p != '\0') {
16218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            addr = strtoull(p, (char **)&p, 16);
16225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            gdb_set_cpu_pc(s, addr);
16238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
16245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        s->signal = 0;
16258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        gdb_continue(s);
16268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	return RS_IDLE;
16278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 'C':
16285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        s->signal = gdb_signal_to_target (strtoul(p, (char **)&p, 16));
16295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (s->signal == -1)
16305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            s->signal = 0;
16318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        gdb_continue(s);
16328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return RS_IDLE;
16338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 'k':
16348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Kill the target */
16358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        fprintf(stderr, "\nQEMU: Terminated via GDBstub\n");
16368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        exit(0);
16378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 'D':
16388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Detach packet */
16395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        gdb_breakpoint_remove_all();
16408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        gdb_continue(s);
16418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        put_packet(s, "OK");
16428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
16438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 's':
16448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (*p != '\0') {
16458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            addr = strtoull(p, (char **)&p, 16);
16465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            gdb_set_cpu_pc(s, addr);
16478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
16485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_single_step(s->c_cpu, sstep_flags);
16498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        gdb_continue(s);
16508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project	return RS_IDLE;
16518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 'F':
16528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
16538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            target_ulong ret;
16548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            target_ulong err;
16558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
16568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            ret = strtoull(p, (char **)&p, 16);
16578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (*p == ',') {
16588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                p++;
16598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                err = strtoull(p, (char **)&p, 16);
16608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
16618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                err = 0;
16628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
16638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (*p == ',')
16648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                p++;
16658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            type = *p;
16668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (gdb_current_syscall_cb)
16675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                gdb_current_syscall_cb(s->c_cpu, ret, err);
16688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (type == 'C') {
16698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                put_packet(s, "T02");
16708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
16718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                gdb_continue(s);
16728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
16738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
16748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
16758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 'g':
16765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_synchronize_state(s->g_cpu, 0);
16775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        len = 0;
16785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (addr = 0; addr < num_g_regs; addr++) {
16795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            reg_size = gdb_read_register(s->g_cpu, mem_buf + len, addr);
16805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            len += reg_size;
16815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
16825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        memtohex(buf, mem_buf, len);
16838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        put_packet(s, buf);
16848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
16858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 'G':
16865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        registers = mem_buf;
16878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len = strlen(p) / 2;
16888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        hextomem((uint8_t *)registers, p, len);
16895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        for (addr = 0; addr < num_g_regs && len > 0; addr++) {
16905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            reg_size = gdb_write_register(s->g_cpu, registers, addr);
16915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            len -= reg_size;
16925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            registers += reg_size;
16935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
16945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        cpu_synchronize_state(s->g_cpu, 1);
16958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        put_packet(s, "OK");
16968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
16978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 'm':
16988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        addr = strtoull(p, (char **)&p, 16);
16998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (*p == ',')
17008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p++;
17018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len = strtoull(p, NULL, 16);
17025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cpu_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 0) != 0) {
17038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            put_packet (s, "E14");
17048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
17058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            memtohex(buf, mem_buf, len);
17068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            put_packet(s, buf);
17078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
17098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 'M':
17108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        addr = strtoull(p, (char **)&p, 16);
17118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (*p == ',')
17128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p++;
17138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len = strtoull(p, (char **)&p, 16);
17148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (*p == ':')
17158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p++;
17168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        hextomem(mem_buf, p, len);
17175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (cpu_memory_rw_debug(s->g_cpu, addr, mem_buf, len, 1) != 0)
17188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            put_packet(s, "E14");
17198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
17208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            put_packet(s, "OK");
17218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
17225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 'p':
17235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Older gdb are really dumb, and don't use 'g' if 'p' is avaialable.
17245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           This works, but can be very slow.  Anything new enough to
17255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner           understand XML also knows how to use this properly.  */
17265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!gdb_has_xml)
17275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            goto unknown_command;
17285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        addr = strtoull(p, (char **)&p, 16);
17295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        reg_size = gdb_read_register(s->g_cpu, mem_buf, addr);
17305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (reg_size) {
17315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            memtohex(buf, mem_buf, reg_size);
17325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            put_packet(s, buf);
17335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else {
17345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            put_packet(s, "E14");
17355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
17365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
17375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 'P':
17385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!gdb_has_xml)
17395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            goto unknown_command;
17405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        addr = strtoull(p, (char **)&p, 16);
17415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (*p == '=')
17425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            p++;
17435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        reg_size = strlen(p) / 2;
17445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        hextomem(mem_buf, p, reg_size);
17455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        gdb_write_register(s->g_cpu, mem_buf, addr);
17465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        put_packet(s, "OK");
17475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
17488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 'Z':
17495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 'z':
17508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        type = strtoul(p, (char **)&p, 16);
17518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (*p == ',')
17528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p++;
17538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        addr = strtoull(p, (char **)&p, 16);
17548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (*p == ',')
17558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p++;
17568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        len = strtoull(p, (char **)&p, 16);
17575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (ch == 'Z')
17585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            res = gdb_breakpoint_insert(addr, len, type);
17595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else
17605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            res = gdb_breakpoint_remove(addr, len, type);
17615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (res >= 0)
17625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             put_packet(s, "OK");
17635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (res == -ENOSYS)
17645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            put_packet(s, "");
17655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else
17665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            put_packet(s, "E22");
17675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        break;
17685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 'H':
17695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        type = *p++;
17705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        thread = strtoull(p, (char **)&p, 16);
17715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (thread == -1 || thread == 0) {
17725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            put_packet(s, "OK");
17735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
17745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
17755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env = find_cpu(thread);
17765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (env == NULL) {
17775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            put_packet(s, "E22");
17785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
17795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
17808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch (type) {
17815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 'c':
17825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            s->c_cpu = env;
17838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            put_packet(s, "OK");
17848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
17855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        case 'g':
17865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            s->g_cpu = env;
17878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            put_packet(s, "OK");
17888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
17898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
17905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             put_packet(s, "E22");
17915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             break;
17928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
17938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
17945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    case 'T':
17955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        thread = strtoull(p, (char **)&p, 16);
17965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        env = find_cpu(thread);
17978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
17985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (env != NULL) {
17998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            put_packet(s, "OK");
18008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
18015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            put_packet(s, "E22");
18028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
18048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 'q':
18058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    case 'Q':
18068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* parse any 'q' packets here */
18078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (!strcmp(p,"qemu.sstepbits")) {
18088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* Query Breakpoint bit definitions */
18098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            snprintf(buf, sizeof(buf), "ENABLE=%x,NOIRQ=%x,NOTIMER=%x",
18108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     SSTEP_ENABLE,
18118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     SSTEP_NOIRQ,
18128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     SSTEP_NOTIMER);
18138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            put_packet(s, buf);
18148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
18158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else if (strncmp(p,"qemu.sstep",10) == 0) {
18168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            /* Display or change the sstep_flags */
18178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p += 10;
18188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (*p != '=') {
18198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                /* Display current setting */
18208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                snprintf(buf, sizeof(buf), "0x%x", sstep_flags);
18218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                put_packet(s, buf);
18228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
18238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
18248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            p++;
18258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            type = strtoul(p, (char **)&p, 16);
18268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            sstep_flags = type;
18278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            put_packet(s, "OK");
18288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
18295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (strcmp(p,"C") == 0) {
18305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* "Current thread" remains vague in the spec, so always return
18315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner             *  the first CPU (gdb returns the first thread). */
18325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            put_packet(s, "QC1");
18335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
18345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (strcmp(p,"fThreadInfo") == 0) {
18355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            s->query_cpu = first_cpu;
18365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            goto report_cpuinfo;
18375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (strcmp(p,"sThreadInfo") == 0) {
18385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        report_cpuinfo:
18395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (s->query_cpu) {
18405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                snprintf(buf, sizeof(buf), "m%x", gdb_id(s->query_cpu));
18415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                put_packet(s, buf);
18425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                s->query_cpu = s->query_cpu->next_cpu;
18435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else
18445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                put_packet(s, "l");
18455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
18465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        } else if (strncmp(p,"ThreadExtraInfo,", 16) == 0) {
18475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            thread = strtoull(p+16, (char **)&p, 16);
18485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            env = find_cpu(thread);
18495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (env != NULL) {
18505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                cpu_synchronize_state(env, 0);
18515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                len = snprintf((char *)mem_buf, sizeof(mem_buf),
18525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               "CPU#%d [%s]", env->cpu_index,
18535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                               env->halted ? "halted " : "running");
18545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                memtohex(buf, mem_buf, len);
18555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                put_packet(s, buf);
18565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
18575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
18588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef CONFIG_USER_ONLY
18608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else if (strncmp(p, "Offsets", 7) == 0) {
18615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            TaskState *ts = s->c_cpu->opaque;
18628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
18638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            snprintf(buf, sizeof(buf),
18648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     "Text=" TARGET_ABI_FMT_lx ";Data=" TARGET_ABI_FMT_lx
18658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     ";Bss=" TARGET_ABI_FMT_lx,
18668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     ts->info->code_offset,
18678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     ts->info->data_offset,
18688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                     ts->info->data_offset);
18698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            put_packet(s, buf);
18708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
18718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
18725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#else /* !CONFIG_USER_ONLY */
18735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (strncmp(p, "Rcmd,", 5) == 0) {
18745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            int len = strlen(p + 5);
18755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
18765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if ((len % 2) != 0) {
18775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                put_packet(s, "E01");
18785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
18795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
18805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            hextomem(mem_buf, p + 5, len);
18815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            len = len / 2;
18825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            mem_buf[len++] = 0;
18835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_chr_read(s->mon_chr, mem_buf, len);
18845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            put_packet(s, "OK");
18855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
18865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
18875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif /* !CONFIG_USER_ONLY */
18885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (strncmp(p, "Supported", 9) == 0) {
18895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            snprintf(buf, sizeof(buf), "PacketSize=%x", MAX_PACKET_LENGTH);
18905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef GDB_CORE_XML
18915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            pstrcat(buf, sizeof(buf), ";qXfer:features:read+");
18925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
18935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            put_packet(s, buf);
18945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
18955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
18965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifdef GDB_CORE_XML
18975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (strncmp(p, "Xfer:features:read:", 19) == 0) {
18985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            const char *xml;
18995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            target_ulong total_len;
19005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            gdb_has_xml = 1;
19025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            p += 19;
19035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            xml = get_feature_xml(p, &p);
19045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (!xml) {
19055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                snprintf(buf, sizeof(buf), "E00");
19065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                put_packet(s, buf);
19075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
19085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
19095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (*p == ':')
19115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                p++;
19125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            addr = strtoul(p, (char **)&p, 16);
19135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (*p == ',')
19145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                p++;
19155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            len = strtoul(p, (char **)&p, 16);
19165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            total_len = strlen(xml);
19185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (addr > total_len) {
19195d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                snprintf(buf, sizeof(buf), "E00");
19205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                put_packet(s, buf);
19215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
19225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
19235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (len > (MAX_PACKET_LENGTH - 5) / 2)
19245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                len = (MAX_PACKET_LENGTH - 5) / 2;
19255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            if (len < total_len - addr) {
19265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                buf[0] = 'm';
19275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                len = memtox(buf + 1, xml + addr, len);
19285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            } else {
19295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                buf[0] = 'l';
19305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                len = memtox(buf + 1, xml + addr, total_len - addr);
19315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
19325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            put_packet_binary(s, buf, len + 1);
19335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
19345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
19358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
19365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Unrecognised 'q' command.  */
19375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        goto unknown_command;
19385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
19398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
19405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    unknown_command:
19418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* put empty packet */
19428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        buf[0] = '\0';
19438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        put_packet(s, buf);
19448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
19458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return RS_IDLE;
19478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
19488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid gdb_set_stop_cpu(CPUState *env)
19505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
19515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    gdbserver_state->c_cpu = env;
19525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    gdbserver_state->g_cpu = env;
19535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
19548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef CONFIG_USER_ONLY
19565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void gdb_vm_state_change(void *opaque, int running, int reason)
19578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
19585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    GDBState *s = gdbserver_state;
19595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CPUState *env = s->c_cpu;
19608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char buf[256];
19615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *type;
19628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int ret;
19638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (running || (reason != EXCP_DEBUG && reason != EXCP_INTERRUPT) ||
19655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        s->state == RS_INACTIVE || s->state == RS_SYSCALL)
19668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
19678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* disable single step if it was enable */
19695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cpu_single_step(env, 0);
19708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
19718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (reason == EXCP_DEBUG) {
19725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (env->watchpoint_hit) {
19735d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            switch (env->watchpoint_hit->flags & BP_MEM_ACCESS) {
19745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case BP_MEM_READ:
19755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                type = "r";
19765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
19775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            case BP_MEM_ACCESS:
19785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                type = "a";
19795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
19805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            default:
19815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                type = "";
19825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                break;
19835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            }
19845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            snprintf(buf, sizeof(buf),
19855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                     "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
19865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                     GDB_SIGNAL_TRAP, gdb_id(env), type,
19875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                     env->watchpoint_hit->vaddr);
19888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            put_packet(s, buf);
19895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            env->watchpoint_hit = NULL;
19908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return;
19918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
19925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner	tb_flush(env);
19935d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = GDB_SIGNAL_TRAP;
19948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else {
19955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        ret = GDB_SIGNAL_INT;
19968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
19975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    snprintf(buf, sizeof(buf), "T%02xthread:%02x;", ret, gdb_id(env));
19988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    put_packet(s, buf);
19998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
20008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Send a gdb syscall request.
20038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project   This accepts limited printf-style format specifiers, specifically:
20048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    %x  - target_ulong argument printed in hex.
20058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    %lx - 64-bit argument printed in hex.
20068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    %s  - string pointer (target_ulong) and length (int) pair.  */
20078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid gdb_do_syscall(gdb_syscall_complete_cb cb, const char *fmt, ...)
20088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
20098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_list va;
20108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char buf[256];
20118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    char *p;
20128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    target_ulong addr;
20138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint64_t i64;
20148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    GDBState *s;
20158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s = gdbserver_state;
20178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!s)
20188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return;
20198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    gdb_current_syscall_cb = cb;
20208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->state = RS_SYSCALL;
20218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef CONFIG_USER_ONLY
20228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    vm_stop(EXCP_DEBUG);
20238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->state = RS_IDLE;
20258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_start(va, fmt);
20268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    p = buf;
20278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *(p++) = 'F';
20288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    while (*fmt) {
20298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (*fmt == '%') {
20308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            fmt++;
20318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            switch (*fmt++) {
20328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 'x':
20338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                addr = va_arg(va, target_ulong);
20348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                p += snprintf(p, &buf[sizeof(buf)] - p, TARGET_FMT_lx, addr);
20358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
20368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 'l':
20378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                if (*(fmt++) != 'x')
20388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                    goto bad_format;
20398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                i64 = va_arg(va, uint64_t);
20408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                p += snprintf(p, &buf[sizeof(buf)] - p, "%" PRIx64, i64);
20418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
20428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            case 's':
20438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                addr = va_arg(va, target_ulong);
20448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                p += snprintf(p, &buf[sizeof(buf)] - p, TARGET_FMT_lx "/%x",
20458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                              addr, va_arg(va, int));
20468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
20478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            default:
20488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            bad_format:
20498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                fprintf(stderr, "gdbstub: Bad syscall format string '%s'\n",
20508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                        fmt - 1);
20518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                break;
20528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
20538b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else {
20548b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            *(p++) = *(fmt++);
20558b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
20568b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20578b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    *p = 0;
20588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    va_end(va);
20598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    put_packet(s, buf);
20608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_USER_ONLY
20615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    gdb_handlesig(s->c_cpu, 0);
20628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
20635d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cpu_exit(s->c_cpu);
20648b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
20668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void gdb_read_byte(GDBState *s, int ch)
20688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
20698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i, csum;
20708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    uint8_t reply;
20718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
20728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifndef CONFIG_USER_ONLY
20738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (s->last_packet_len) {
20748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* Waiting for a response to the last packet.  If we see the start
20758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           of a new command then abandon the previous response.  */
20768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ch == '-') {
20778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_GDB
20788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("Got NACK, retransmitting\n");
20798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            put_buffer(s, (uint8_t *)s->last_packet, s->last_packet_len);
20818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
20828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef DEBUG_GDB
20838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else if (ch == '+')
20848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("Got ACK\n");
20858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        else
20868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            printf("Got '%c' when expecting ACK/NACK\n", ch);
20878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ch == '+' || ch == '$')
20898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->last_packet_len = 0;
20908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        if (ch != '$')
20918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return;
20928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
20938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (vm_running) {
20948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        /* when the CPU is running, we cannot do anything except stop
20958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project           it when receiving a char */
20968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        vm_stop(EXCP_INTERRUPT);
20978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    } else
20988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
20998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
21008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        switch(s->state) {
21018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case RS_IDLE:
21028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ch == '$') {
21038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->line_buf_index = 0;
21048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->state = RS_GETLINE;
21058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
21068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
21078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case RS_GETLINE:
21088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (ch == '#') {
21098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->state = RS_CHKSUM1;
21108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else if (s->line_buf_index >= sizeof(s->line_buf) - 1) {
21118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->state = RS_IDLE;
21128b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
21138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->line_buf[s->line_buf_index++] = ch;
21148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
21158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
21168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case RS_CHKSUM1:
21178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->line_buf[s->line_buf_index] = '\0';
21188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->line_csum = fromhex(ch) << 4;
21198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->state = RS_CHKSUM2;
21208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
21218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        case RS_CHKSUM2:
21228b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            s->line_csum |= fromhex(ch);
21238b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            csum = 0;
21248b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            for(i = 0; i < s->line_buf_index; i++) {
21258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                csum += s->line_buf[i];
21268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
21278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            if (s->line_csum != (csum & 0xff)) {
21288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                reply = '-';
21298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                put_buffer(s, &reply, 1);
21308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                s->state = RS_IDLE;
21318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            } else {
21328b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                reply = '+';
21338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project                put_buffer(s, &reply, 1);
21345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                s->state = gdb_handle_packet(s, s->line_buf);
21358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            }
21368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
21378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        default:
21388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            abort();
21398b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
21408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
21418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
21428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#ifdef CONFIG_USER_ONLY
21448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint
21455d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnergdb_queuesig (void)
21465d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
21475d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    GDBState *s;
21485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21495d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s = gdbserver_state;
21505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (gdbserver_fd < 0 || s->fd < 0)
21525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 0;
21535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    else
21545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        return 1;
21555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
21565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
21575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint
21588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectgdb_handlesig (CPUState *env, int sig)
21598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
21608b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  GDBState *s;
21618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  char buf[256];
21628b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  int n;
21638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  s = gdbserver_state;
21658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  if (gdbserver_fd < 0 || s->fd < 0)
21668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return sig;
21678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  /* disable single step if it was enabled */
21698b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  cpu_single_step(env, 0);
21708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  tb_flush(env);
21718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21728b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  if (sig != 0)
21738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    {
21745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner      snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb (sig));
21758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      put_packet(s, buf);
21768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
21778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  /* put_packet() might have detected that the peer terminated the
21788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project     connection.  */
21798b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  if (s->fd < 0)
21808b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      return sig;
21818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21828b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  sig = 0;
21838b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  s->state = RS_IDLE;
21848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  s->running_state = 0;
21858b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  while (s->running_state == 0) {
21868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      n = read (s->fd, buf, 256);
21878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      if (n > 0)
21888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
21898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          int i;
21908b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
21918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          for (i = 0; i < n; i++)
21928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            gdb_read_byte (s, buf[i]);
21938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
21948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project      else if (n == 0 || errno != EAGAIN)
21958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        {
21968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          /* XXX: Connection closed.  Should probably wait for annother
21978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project             connection before continuing.  */
21988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project          return sig;
21998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
22008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  }
22018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  sig = s->signal;
22028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  s->signal = 0;
22038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  return sig;
22048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project/* Tell the remote gdb that the process has exited.  */
22078b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectvoid gdb_exit(CPUState *env, int code)
22088b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22098b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  GDBState *s;
22108b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  char buf[4];
22118b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  s = gdbserver_state;
22138b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  if (gdbserver_fd < 0 || s->fd < 0)
22148b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return;
22158b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22168b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  snprintf(buf, sizeof(buf), "W%02x", code);
22178b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project  put_packet(s, buf);
22188b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Tell the remote gdb that the process has exited due to SIG.  */
22215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid gdb_signalled(CPUState *env, int sig)
22225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
22235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  GDBState *s;
22245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  char buf[4];
22255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  s = gdbserver_state;
22275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  if (gdbserver_fd < 0 || s->fd < 0)
22285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return;
22295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb (sig));
22315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  put_packet(s, buf);
22325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
22338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22345d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void gdb_accept(void)
22358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    GDBState *s;
22375d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct sockaddr_in sockaddr;
22385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    socklen_t len;
22395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int val, fd;
22408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for(;;) {
22425d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        len = sizeof(sockaddr);
22435d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        fd = accept(gdbserver_fd, (struct sockaddr *)&sockaddr, &len);
22445d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (fd < 0 && errno != EINTR) {
22458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            perror("accept");
22468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            return;
22478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        } else if (fd >= 0) {
22488b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project            break;
22498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        }
22508b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
22518b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22528b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* set short latency */
22535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    val = 1;
22545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, (char *)&val, sizeof(val));
22555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
22565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s = qemu_mallocz(sizeof(GDBState));
22575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->c_cpu = first_cpu;
22585d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->g_cpu = first_cpu;
22598b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->fd = fd;
22605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    gdb_has_xml = 0;
22618b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    gdbserver_state = s;
22638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fcntl(fd, F_SETFL, O_NONBLOCK);
22658b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22668b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22678b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int gdbserver_open(int port)
22688b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
22695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    struct sockaddr_in sockaddr;
22708b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int fd, val, ret;
22718b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    fd = socket(PF_INET, SOCK_STREAM, 0);
22738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (fd < 0) {
22748b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        perror("socket");
22758b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
22768b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
22778b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22788b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* allow fast reuse */
22795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    val = 1;
22805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, (char *)&val, sizeof(val));
22818b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sockaddr.sin_family = AF_INET;
22835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sockaddr.sin_port = htons(port);
22845d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    sockaddr.sin_addr.s_addr = 0;
22855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = bind(fd, (struct sockaddr *)&sockaddr, sizeof(sockaddr));
22868b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0) {
22878b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        perror("bind");
22888b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
22898b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
22905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    ret = listen(fd, 0);
22918b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (ret < 0) {
22928b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        perror("listen");
22938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
22948b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
22958b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return fd;
22968b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
22978b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
22988b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectint gdbserver_start(int port)
22998b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
23008b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    gdbserver_fd = gdbserver_open(port);
23018b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (gdbserver_fd < 0)
23028b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
23038b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    /* accept connections */
23045d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    gdb_accept();
23058b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
23068b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
23075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner/* Disable gdb stub for child processes.  */
23095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnervoid gdbserver_fork(CPUState *env)
23105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
23115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    GDBState *s = gdbserver_state;
23125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (gdbserver_fd < 0 || s->fd < 0)
23135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner      return;
23145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    close(s->fd);
23155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->fd = -1;
23165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cpu_breakpoint_remove_all(env, BP_GDB);
23175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    cpu_watchpoint_remove_all(env, BP_GDB);
23185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
23198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#else
23208b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic int gdb_chr_can_receive(void *opaque)
23218b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
23225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  /* We can handle an arbitrarily large amount of data.
23235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner   Pick the maximum packet size, which is as good as anything.  */
23245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner  return MAX_PACKET_LENGTH;
23258b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
23268b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23278b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void gdb_chr_receive(void *opaque, const uint8_t *buf, int size)
23288b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
23298b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    int i;
23308b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23318b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    for (i = 0; i < size; i++) {
23325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        gdb_read_byte(gdbserver_state, buf[i]);
23338b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
23348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
23358b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23368b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Projectstatic void gdb_chr_event(void *opaque, int event)
23378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
23388b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    switch (event) {
2339a5d412078b8e7478d81df03710eacc7a21096ba2David 'Digit' Turner    case CHR_EVENT_OPENED:
23408b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        vm_stop(EXCP_INTERRUPT);
23415d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        gdb_has_xml = 0;
23428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
23438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    default:
23448b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        break;
23458b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
23468b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
23478b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23485d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void gdb_monitor_output(GDBState *s, const char *msg, int len)
23498b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project{
23505d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char buf[MAX_PACKET_LENGTH];
23515d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23525d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    buf[0] = 'O';
23535d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (len > (MAX_PACKET_LENGTH/2) - 1)
23545d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        len = (MAX_PACKET_LENGTH/2) - 1;
23555d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    memtohex(buf + 1, (uint8_t *)msg, len);
23565d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    put_packet(s, buf);
23575d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
23588b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23595d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic int gdb_monitor_write(CharDriverState *chr, const uint8_t *buf, int len)
23605d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
23615d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    const char *p = (const char *)buf;
23625d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    int max_sz;
23638b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23645d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    max_sz = (sizeof(gdbserver_state->last_packet) - 2) / 2;
23655d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    for (;;) {
23665d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (len <= max_sz) {
23675d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            gdb_monitor_output(gdbserver_state, p, len);
23685d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            break;
23695d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
23705d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        gdb_monitor_output(gdbserver_state, p, max_sz);
23715d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        p += max_sz;
23725d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        len -= max_sz;
23738b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
23745d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    return len;
23755d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
23765d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23775d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
23785d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerstatic void gdb_sigterm_handler(int signal)
23795d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
23805d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (vm_running)
23815d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        vm_stop(EXCP_INTERRUPT);
23825d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner}
23835d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
23848b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
23855d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turnerint gdbserver_start(const char *device)
23865d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner{
23875d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    GDBState *s;
23885d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    char gdbstub_device_name[128];
23895d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CharDriverState *chr = NULL;
23905d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    CharDriverState *mon_chr;
23915d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
23925d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (!device)
23938b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project        return -1;
23945d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    if (strcmp(device, "none") != 0) {
23955d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (strstart(device, "tcp:", NULL)) {
23965d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            /* enforce required TCP attributes */
23975d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            snprintf(gdbstub_device_name, sizeof(gdbstub_device_name),
23985d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                     "%s,nowait,nodelay,server", device);
23995d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            device = gdbstub_device_name;
24005d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
24015d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#ifndef _WIN32
24025d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        else if (strcmp(device, "stdio") == 0) {
24035d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            struct sigaction act;
24048b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project
24055d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            memset(&act, 0, sizeof(act));
24065d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            act.sa_handler = gdb_sigterm_handler;
24075d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            sigaction(SIGINT, &act, NULL);
24085d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        }
24095d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner#endif
24105d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        chr = qemu_chr_open("gdb", device, NULL);
24115d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (!chr)
24125d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            return -1;
24135d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24145d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_chr_add_handlers(chr, gdb_chr_can_receive, gdb_chr_receive,
24155d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner                              gdb_chr_event, NULL);
24165d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    }
24175d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24185d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s = gdbserver_state;
24198b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    if (!s) {
24205d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        s = qemu_mallocz(sizeof(GDBState));
24215d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        gdbserver_state = s;
24225d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24235d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        qemu_add_vm_change_state_handler(gdb_vm_state_change, NULL);
24245d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24255d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        /* Initialize a monitor terminal for gdb */
24265d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        mon_chr = qemu_mallocz(sizeof(*mon_chr));
24275d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        mon_chr->chr_write = gdb_monitor_write;
24285d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        monitor_init(mon_chr, 0);
24295d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    } else {
24305d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        if (s->chr)
24315d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner            qemu_chr_close(s->chr);
24325d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        mon_chr = s->mon_chr;
24335d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner        memset(s, 0, sizeof(GDBState));
24348b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    }
24355d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->c_cpu = first_cpu;
24365d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->g_cpu = first_cpu;
24378b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    s->chr = chr;
24385d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->state = chr ? RS_IDLE : RS_INACTIVE;
24395d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner    s->mon_chr = mon_chr;
24405d8f37ad78fc66901af50c762029a501561f3b23David 'Digit' Turner
24418b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project    return 0;
24428b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project}
24438b23a6c7e1aee255004dd19098d4c2462b61b849The Android Open Source Project#endif
2444