~vcs-imports/qemu/git

« back to all changes in this revision

Viewing changes to gdbstub.c

  • Committer: aurel32
  • Date: 2008-12-18 22:44:13 UTC
  • Revision ID: git-v1:ca587a8ebdb4bfb30d3080ea5721882209911670
User-mode GDB stub improvements - handle signals

Handle signals in the user-mode GDB stub.  Report them to GDB, and
allow it to change or cancel them.  Also correct the protocol numbering;
it happens to match Linux numbering for SIGINT and SIGTRAP, but that's
just good fortune.

Signed-off-by: Daniel Jacobowitz <dan@codesourcery.com>
Acked-by: Edgar E. Iglesias <edgar.iglesias@gmail.com>
Signed-off-by: Aurelien Jarno <aurelien@aurel32.net>

git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@6096 c046a42c-6fe2-441c-8c8c-71466251a162

Show diffs side-by-side

added added

removed removed

Lines of Context:
38
38
#define MAX_PACKET_LENGTH 4096
39
39
 
40
40
#include "qemu_socket.h"
41
 
#ifdef _WIN32
42
 
/* XXX: these constants may be independent of the host ones even for Unix */
43
 
#ifndef SIGTRAP
44
 
#define SIGTRAP 5
45
 
#endif
46
 
#ifndef SIGINT
47
 
#define SIGINT 2
48
 
#endif
 
41
 
 
42
 
 
43
enum {
 
44
    GDB_SIGNAL_0 = 0,
 
45
    GDB_SIGNAL_INT = 2,
 
46
    GDB_SIGNAL_TRAP = 5,
 
47
    GDB_SIGNAL_UNKNOWN = 143
 
48
};
 
49
 
 
50
#ifdef CONFIG_USER_ONLY
 
51
 
 
52
/* Map target signal numbers to GDB protocol signal numbers and vice
 
53
 * versa.  For user emulation's currently supported systems, we can
 
54
 * assume most signals are defined.
 
55
 */
 
56
 
 
57
static int gdb_signal_table[] = {
 
58
    0,
 
59
    TARGET_SIGHUP,
 
60
    TARGET_SIGINT,
 
61
    TARGET_SIGQUIT,
 
62
    TARGET_SIGILL,
 
63
    TARGET_SIGTRAP,
 
64
    TARGET_SIGABRT,
 
65
    -1, /* SIGEMT */
 
66
    TARGET_SIGFPE,
 
67
    TARGET_SIGKILL,
 
68
    TARGET_SIGBUS,
 
69
    TARGET_SIGSEGV,
 
70
    TARGET_SIGSYS,
 
71
    TARGET_SIGPIPE,
 
72
    TARGET_SIGALRM,
 
73
    TARGET_SIGTERM,
 
74
    TARGET_SIGURG,
 
75
    TARGET_SIGSTOP,
 
76
    TARGET_SIGTSTP,
 
77
    TARGET_SIGCONT,
 
78
    TARGET_SIGCHLD,
 
79
    TARGET_SIGTTIN,
 
80
    TARGET_SIGTTOU,
 
81
    TARGET_SIGIO,
 
82
    TARGET_SIGXCPU,
 
83
    TARGET_SIGXFSZ,
 
84
    TARGET_SIGVTALRM,
 
85
    TARGET_SIGPROF,
 
86
    TARGET_SIGWINCH,
 
87
    -1, /* SIGLOST */
 
88
    TARGET_SIGUSR1,
 
89
    TARGET_SIGUSR2,
 
90
    TARGET_SIGPWR,
 
91
    -1, /* SIGPOLL */
 
92
    -1,
 
93
    -1,
 
94
    -1,
 
95
    -1,
 
96
    -1,
 
97
    -1,
 
98
    -1,
 
99
    -1,
 
100
    -1,
 
101
    -1,
 
102
    -1,
 
103
    __SIGRTMIN + 1,
 
104
    __SIGRTMIN + 2,
 
105
    __SIGRTMIN + 3,
 
106
    __SIGRTMIN + 4,
 
107
    __SIGRTMIN + 5,
 
108
    __SIGRTMIN + 6,
 
109
    __SIGRTMIN + 7,
 
110
    __SIGRTMIN + 8,
 
111
    __SIGRTMIN + 9,
 
112
    __SIGRTMIN + 10,
 
113
    __SIGRTMIN + 11,
 
114
    __SIGRTMIN + 12,
 
115
    __SIGRTMIN + 13,
 
116
    __SIGRTMIN + 14,
 
117
    __SIGRTMIN + 15,
 
118
    __SIGRTMIN + 16,
 
119
    __SIGRTMIN + 17,
 
120
    __SIGRTMIN + 18,
 
121
    __SIGRTMIN + 19,
 
122
    __SIGRTMIN + 20,
 
123
    __SIGRTMIN + 21,
 
124
    __SIGRTMIN + 22,
 
125
    __SIGRTMIN + 23,
 
126
    __SIGRTMIN + 24,
 
127
    __SIGRTMIN + 25,
 
128
    __SIGRTMIN + 26,
 
129
    __SIGRTMIN + 27,
 
130
    __SIGRTMIN + 28,
 
131
    __SIGRTMIN + 29,
 
132
    __SIGRTMIN + 30,
 
133
    __SIGRTMIN + 31,
 
134
    -1, /* SIGCANCEL */
 
135
    __SIGRTMIN,
 
136
    __SIGRTMIN + 32,
 
137
    __SIGRTMIN + 33,
 
138
    __SIGRTMIN + 34,
 
139
    __SIGRTMIN + 35,
 
140
    __SIGRTMIN + 36,
 
141
    __SIGRTMIN + 37,
 
142
    __SIGRTMIN + 38,
 
143
    __SIGRTMIN + 39,
 
144
    __SIGRTMIN + 40,
 
145
    __SIGRTMIN + 41,
 
146
    __SIGRTMIN + 42,
 
147
    __SIGRTMIN + 43,
 
148
    __SIGRTMIN + 44,
 
149
    __SIGRTMIN + 45,
 
150
    __SIGRTMIN + 46,
 
151
    __SIGRTMIN + 47,
 
152
    __SIGRTMIN + 48,
 
153
    __SIGRTMIN + 49,
 
154
    __SIGRTMIN + 50,
 
155
    __SIGRTMIN + 51,
 
156
    __SIGRTMIN + 52,
 
157
    __SIGRTMIN + 53,
 
158
    __SIGRTMIN + 54,
 
159
    __SIGRTMIN + 55,
 
160
    __SIGRTMIN + 56,
 
161
    __SIGRTMIN + 57,
 
162
    __SIGRTMIN + 58,
 
163
    __SIGRTMIN + 59,
 
164
    __SIGRTMIN + 60,
 
165
    __SIGRTMIN + 61,
 
166
    __SIGRTMIN + 62,
 
167
    __SIGRTMIN + 63,
 
168
    __SIGRTMIN + 64,
 
169
    __SIGRTMIN + 65,
 
170
    __SIGRTMIN + 66,
 
171
    __SIGRTMIN + 67,
 
172
    __SIGRTMIN + 68,
 
173
    __SIGRTMIN + 69,
 
174
    __SIGRTMIN + 70,
 
175
    __SIGRTMIN + 71,
 
176
    __SIGRTMIN + 72,
 
177
    __SIGRTMIN + 73,
 
178
    __SIGRTMIN + 74,
 
179
    __SIGRTMIN + 75,
 
180
    __SIGRTMIN + 76,
 
181
    __SIGRTMIN + 77,
 
182
    __SIGRTMIN + 78,
 
183
    __SIGRTMIN + 79,
 
184
    __SIGRTMIN + 80,
 
185
    __SIGRTMIN + 81,
 
186
    __SIGRTMIN + 82,
 
187
    __SIGRTMIN + 83,
 
188
    __SIGRTMIN + 84,
 
189
    __SIGRTMIN + 85,
 
190
    __SIGRTMIN + 86,
 
191
    __SIGRTMIN + 87,
 
192
    __SIGRTMIN + 88,
 
193
    __SIGRTMIN + 89,
 
194
    __SIGRTMIN + 90,
 
195
    __SIGRTMIN + 91,
 
196
    __SIGRTMIN + 92,
 
197
    __SIGRTMIN + 93,
 
198
    __SIGRTMIN + 94,
 
199
    __SIGRTMIN + 95,
 
200
    -1, /* SIGINFO */
 
201
    -1, /* UNKNOWN */
 
202
    -1, /* DEFAULT */
 
203
    -1,
 
204
    -1,
 
205
    -1,
 
206
    -1,
 
207
    -1,
 
208
    -1
 
209
};
49
210
#else
50
 
#include <signal.h>
51
 
#endif
 
211
/* In system mode we only need SIGINT and SIGTRAP; other signals
 
212
   are not yet supported.  */
 
213
 
 
214
enum {
 
215
    TARGET_SIGINT = 2,
 
216
    TARGET_SIGTRAP = 5
 
217
};
 
218
 
 
219
static int gdb_signal_table[] = {
 
220
    -1,
 
221
    -1,
 
222
    TARGET_SIGINT,
 
223
    -1,
 
224
    -1,
 
225
    TARGET_SIGTRAP
 
226
};
 
227
#endif
 
228
 
 
229
#ifdef CONFIG_USER_ONLY
 
230
static int target_signal_to_gdb (int sig)
 
231
{
 
232
    int i;
 
233
    for (i = 0; i < ARRAY_SIZE (gdb_signal_table); i++)
 
234
        if (gdb_signal_table[i] == sig)
 
235
            return i;
 
236
    return GDB_SIGNAL_UNKNOWN;
 
237
}
 
238
#endif
 
239
 
 
240
static int gdb_signal_to_target (int sig)
 
241
{
 
242
    if (sig < ARRAY_SIZE (gdb_signal_table))
 
243
        return gdb_signal_table[sig];
 
244
    else
 
245
        return -1;
 
246
}
52
247
 
53
248
//#define DEBUG_GDB
54
249
 
1300
1495
    switch(ch) {
1301
1496
    case '?':
1302
1497
        /* TODO: Make this return the correct value for user-mode.  */
1303
 
        snprintf(buf, sizeof(buf), "T%02xthread:%02x;", SIGTRAP,
 
1498
        snprintf(buf, sizeof(buf), "T%02xthread:%02x;", GDB_SIGNAL_TRAP,
1304
1499
                 s->c_cpu->cpu_index+1);
1305
1500
        put_packet(s, buf);
1306
1501
        /* Remove all the breakpoints when this query is issued,
1331
1526
            s->c_cpu->pc = addr;
1332
1527
#endif
1333
1528
        }
 
1529
        s->signal = 0;
1334
1530
        gdb_continue(s);
1335
1531
        return RS_IDLE;
1336
1532
    case 'C':
1337
 
        s->signal = strtoul(p, (char **)&p, 16);
 
1533
        s->signal = gdb_signal_to_target (strtoul(p, (char **)&p, 16));
 
1534
        if (s->signal == -1)
 
1535
            s->signal = 0;
1338
1536
        gdb_continue(s);
1339
1537
        return RS_IDLE;
1340
1538
    case 'k':
1692
1890
            }
1693
1891
            snprintf(buf, sizeof(buf),
1694
1892
                     "T%02xthread:%02x;%swatch:" TARGET_FMT_lx ";",
1695
 
                     SIGTRAP, env->cpu_index+1, type,
 
1893
                     GDB_SIGNAL_TRAP, env->cpu_index+1, type,
1696
1894
                     env->watchpoint_hit->vaddr);
1697
1895
            put_packet(s, buf);
1698
1896
            env->watchpoint_hit = NULL;
1699
1897
            return;
1700
1898
        }
1701
1899
        tb_flush(env);
1702
 
        ret = SIGTRAP;
 
1900
        ret = GDB_SIGNAL_TRAP;
1703
1901
    } else if (reason == EXCP_INTERRUPT) {
1704
 
        ret = SIGINT;
 
1902
        ret = GDB_SIGNAL_INT;
1705
1903
    } else {
1706
1904
        ret = 0;
1707
1905
    }
1853
2051
 
1854
2052
#ifdef CONFIG_USER_ONLY
1855
2053
int
 
2054
gdb_queuesig (void)
 
2055
{
 
2056
    GDBState *s;
 
2057
 
 
2058
    s = gdbserver_state;
 
2059
 
 
2060
    if (gdbserver_fd < 0 || s->fd < 0)
 
2061
        return 0;
 
2062
    else
 
2063
        return 1;
 
2064
}
 
2065
 
 
2066
int
1856
2067
gdb_handlesig (CPUState *env, int sig)
1857
2068
{
1858
2069
  GDBState *s;
1869
2080
 
1870
2081
  if (sig != 0)
1871
2082
    {
1872
 
      snprintf(buf, sizeof(buf), "S%02x", sig);
 
2083
      snprintf(buf, sizeof(buf), "S%02x", target_signal_to_gdb (sig));
1873
2084
      put_packet(s, buf);
1874
2085
    }
1875
2086
  /* put_packet() might have detected that the peer terminated the 
1915
2126
  put_packet(s, buf);
1916
2127
}
1917
2128
 
 
2129
/* Tell the remote gdb that the process has exited due to SIG.  */
 
2130
void gdb_signalled(CPUState *env, int sig)
 
2131
{
 
2132
  GDBState *s;
 
2133
  char buf[4];
 
2134
 
 
2135
  s = gdbserver_state;
 
2136
  if (gdbserver_fd < 0 || s->fd < 0)
 
2137
    return;
 
2138
 
 
2139
  snprintf(buf, sizeof(buf), "X%02x", target_signal_to_gdb (sig));
 
2140
  put_packet(s, buf);
 
2141
}
1918
2142
 
1919
2143
static void gdb_accept(void)
1920
2144
{