Merge pull request #2 from schuay/watchpoints
[simavr] / simavr / sim / sim_gdb.c
1 /*
2         sim_gdb.c
3
4         Copyright 2008, 2009 Michel Pollet <buserror@gmail.com>
5
6         This file is part of simavr.
7
8         simavr is free software: you can redistribute it and/or modify
9         it under the terms of the GNU General Public License as published by
10         the Free Software Foundation, either version 3 of the License, or
11         (at your option) any later version.
12
13         simavr is distributed in the hope that it will be useful,
14         but WITHOUT ANY WARRANTY; without even the implied warranty of
15         MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16         GNU General Public License for more details.
17
18         You should have received a copy of the GNU General Public License
19         along with simavr.  If not, see <http://www.gnu.org/licenses/>.
20  */
21
22 #include <netinet/in.h>
23 #include <netinet/tcp.h>
24 #include <arpa/inet.h>
25 #include <sys/socket.h>
26 #include <sys/time.h>
27 #include <stdlib.h>
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <string.h>
31 #include <errno.h>
32 #include <poll.h>
33 #include <pthread.h>
34 #include "sim_avr.h"
35 #include "sim_hex.h"
36 #include "avr_eeprom.h"
37 #include "sim_gdb.h"
38
39 #define DBG(w)
40
41 #define WATCH_LIMIT (32)
42
43 typedef struct {
44         uint32_t len; /**< How many points are taken (points[0] .. points[len - 1]). */
45         struct {
46                 uint32_t addr; /**< Which address is watched. */
47                 uint32_t size; /**< How large is the watched segment. */
48                 uint32_t kind; /**< Bitmask of enum avr_gdb_watch_type values. */
49         } points[WATCH_LIMIT];
50 } avr_gdb_watchpoints_t;
51
52 typedef struct avr_gdb_t {
53         avr_t * avr;
54         int             listen; // listen socket
55         int             s;              // current gdb connection
56
57         avr_gdb_watchpoints_t breakpoints;
58         avr_gdb_watchpoints_t watchpoints;
59 } avr_gdb_t;
60
61
62 /**
63  * Returns the index of the watchpoint if found, -1 otherwise.
64  */
65 static int gdb_watch_find(const avr_gdb_watchpoints_t * w, uint32_t addr)
66 {
67         for (int i = 0; i < w->len; i++) {
68                 if (w->points[i].addr > addr) {
69                         return -1;
70                 } else if (w->points[i].addr == addr) {
71                         return i;
72                 }
73         }
74
75         return -1;
76 }
77
78 /**
79  * Contrary to gdb_watch_find, this actually checks the address against
80  * a watched memory _range_.
81  */
82 static int gdb_watch_find_range(const avr_gdb_watchpoints_t * w, uint32_t addr)
83 {
84         for (int i = 0; i < w->len; i++) {
85                 if (w->points[i].addr > addr) {
86                         return -1;
87                 } else if (w->points[i].addr <= addr && addr < w->points[i].addr + w->points[i].size) {
88                         return i;
89                 }
90         }
91
92         return -1;
93 }
94
95 /**
96  * Returns -1 on error, 0 otherwise.
97  */
98 static int gdb_watch_add_or_update(avr_gdb_watchpoints_t * w, enum avr_gdb_watch_type kind, uint32_t addr,
99                 uint32_t size)
100 {
101         /* If the watchpoint exists, update it. */
102         int i = gdb_watch_find(w, addr);
103         if (i != -1) {
104                 w->points[i].size = size;
105                 w->points[i].kind |= kind;
106                 return 0;
107         }
108
109         /* Otherwise add it. */
110         if (w->len == WATCH_LIMIT) {
111                 return -1;
112         }
113
114         /* Find the insertion point. */
115         for (i = 0; i < w->len; i++) {
116                 if (w->points[i].addr > addr) {
117                         break;
118                 }
119         }
120
121         w->len++;
122
123         /* Make space for new element. */
124         for (int j = i + 1; j < w->len; j++) {
125                 w->points[j] = w->points[j - 1];
126         }
127
128         /* Insert it. */
129         w->points[i].kind = kind;
130         w->points[i].addr = addr;
131         w->points[i].size = size;
132
133         return 0;
134 }
135
136 /**
137  * Returns -1 on error or if the specified point does not exist, 0 otherwise.
138  */
139 static int gdb_watch_rm(avr_gdb_watchpoints_t * w, enum avr_gdb_watch_type kind, uint32_t addr)
140 {
141         int i = gdb_watch_find(w, addr);
142         if (i == -1) {
143                 return -1;
144         }
145
146         w->points[i].kind &= ~kind;
147         if (w->points[i].kind) {
148                 return 0;
149         }
150
151         for (i = i + 1; i < w->len; i++) {
152                 w->points[i - 1] = w->points[i];
153         }
154
155         w->len--;
156
157         return 0;
158 }
159
160 static void gdb_watch_clear(avr_gdb_watchpoints_t * w)
161 {
162         w->len = 0;
163 }
164
165 static void gdb_send_reply(avr_gdb_t * g, char * cmd)
166 {
167         uint8_t reply[1024];
168         uint8_t * dst = reply;
169         uint8_t check = 0;
170         *dst++ = '$';
171         while (*cmd) {
172                 check += *cmd;
173                 *dst++ = *cmd++;
174         }
175         sprintf((char*)dst, "#%02x", check);
176         DBG(printf("%s '%s'\n", __FUNCTION__, reply);)
177         send(g->s, reply, dst - reply + 3, 0);
178 }
179
180 static void gdb_send_quick_status(avr_gdb_t * g, uint8_t signal)
181 {
182         char cmd[64];
183
184         sprintf(cmd, "T%02x20:%02x;21:%02x%02x;22:%02x%02x%02x00;",
185                 signal ? signal : 5, g->avr->data[R_SREG], 
186                 g->avr->data[R_SPL], g->avr->data[R_SPH],
187                 g->avr->pc & 0xff, (g->avr->pc>>8)&0xff, (g->avr->pc>>16)&0xff);
188         gdb_send_reply(g, cmd);
189 }
190
191 static int gdb_change_breakpoint(avr_gdb_watchpoints_t * w, int set, enum avr_gdb_watch_type kind,
192                 uint32_t addr, uint32_t size)
193 {
194         DBG(printf("set %d kind %d addr %08x len %d\n", set, kind, addr, len);)
195
196         if (set) {
197                 return gdb_watch_add_or_update(w, kind, addr, size);
198         } else {
199                 return gdb_watch_rm(w, kind, addr);
200         }
201
202         return -1;
203 }
204
205 static int gdb_write_register(avr_gdb_t * g, int regi, uint8_t * src)
206 {
207         switch (regi) {
208                 case 0 ... 31:
209                         g->avr->data[regi] = *src;
210                         return 1;
211                 case 32:
212                         g->avr->data[R_SREG] = *src;
213                         return 1;
214                 case 33:
215                         g->avr->data[R_SPL] = src[0];
216                         g->avr->data[R_SPH] = src[1];
217                         return 2;
218                 case 34:
219                         g->avr->pc = src[0] | (src[1] << 8) | (src[2] << 16) | (src[3] << 24);
220                         return 4;
221         }
222         return 1;
223 }
224
225 static int gdb_read_register(avr_gdb_t * g, int regi, char * rep)
226 {
227         switch (regi) {
228                 case 0 ... 31:
229                         sprintf(rep, "%02x", g->avr->data[regi]);
230                         break;
231                 case 32:
232                         sprintf(rep, "%02x", g->avr->data[R_SREG]);
233                         break;
234                 case 33:
235                         sprintf(rep, "%02x%02x", g->avr->data[R_SPL], g->avr->data[R_SPH]);
236                         break;
237                 case 34:
238                         sprintf(rep, "%02x%02x%02x00", 
239                                 g->avr->pc & 0xff, (g->avr->pc>>8)&0xff, (g->avr->pc>>16)&0xff);
240                         break;
241         }
242         return strlen(rep);
243 }
244
245 static void gdb_handle_command(avr_gdb_t * g, char * cmd)
246 {
247         avr_t * avr = g->avr;
248         char rep[1024];
249         uint8_t command = *cmd++;
250         switch (command) {
251                 case '?':
252                         gdb_send_quick_status(g, 0);
253                         break;
254                 case 'G': {     // set all general purpose registers
255                         // get their binary form
256                         read_hex_string(cmd, (uint8_t*)rep, strlen(cmd));
257                         uint8_t *src = (uint8_t*)rep;
258                         for (int i = 0; i < 35; i++)
259                                 src += gdb_write_register(g, i, src);
260                         gdb_send_reply(g, "OK");                                                                                
261                 }       break;
262                 case 'g': {     // read all general purpose registers
263                         char * dst = rep;
264                         for (int i = 0; i < 35; i++)
265                                 dst += gdb_read_register(g, i, dst);
266                         gdb_send_reply(g, rep);                                         
267                 }       break;
268                 case 'p': {     // read register
269                         unsigned int regi = 0;
270                         sscanf(cmd, "%x", &regi);
271                         gdb_read_register(g, regi, rep);
272                         gdb_send_reply(g, rep);                 
273                 }       break;
274                 case 'P': {     // write register
275                         unsigned int regi = 0;
276                         char * val = strchr(cmd, '=');
277                         if (!val)
278                                 break;
279                         *val++ = 0;
280                         sscanf(cmd, "%x", &regi);
281                         read_hex_string(val, (uint8_t*)rep, strlen(val));
282                         gdb_write_register(g, regi, (uint8_t*)rep);
283                         gdb_send_reply(g, "OK");                                                                                
284                 }       break;
285                 case 'm': {     // read memory
286                         avr_flashaddr_t addr;
287                         uint32_t len;
288                         sscanf(cmd, "%x,%x", &addr, &len);
289                         uint8_t * src = NULL;
290                         if (addr < avr->flashend) {
291                                 src = avr->flash + addr;
292                         } else if (addr >= 0x800000 && (addr - 0x800000) <= avr->ramend) {
293                                 src = avr->data + addr - 0x800000;
294                         } else if (addr >= 0x810000 && (addr - 0x810000) <= avr->e2end) {
295                                 avr_eeprom_desc_t ee = {.offset = (addr - 0x810000)};
296                                 avr_ioctl(avr, AVR_IOCTL_EEPROM_GET, &ee);
297                                 if (ee.ee)
298                                         src = ee.ee;
299                                 else {
300                                         gdb_send_reply(g, "E01");
301                                         break;
302                                 }
303                         } else if (addr >= 0x800000 && (addr - 0x800000) == avr->ramend+1 && len == 2) {
304                                 // Allow GDB to read a value just after end of stack.
305                                 // This is necessary to make instruction stepping work when stack is empty
306                                 printf("GDB read just past end of stack %08x, %08x; returning zero\n", addr, len);
307                                 gdb_send_reply(g, "0000");
308                                 break;
309                         } else {
310                                 printf("read memory error %08x, %08x (ramend %04x)\n", addr, len, avr->ramend+1);
311                                 gdb_send_reply(g, "E01");
312                                 break;
313                         }
314                         char * dst = rep;
315                         while (len--) {
316                                 sprintf(dst, "%02x", *src++);
317                                 dst += 2;
318                         }
319                         *dst = 0;
320                         gdb_send_reply(g, rep);
321                 }       break;
322                 case 'M': {     // write memory
323                         uint32_t addr, len;
324                         sscanf(cmd, "%x,%x", &addr, &len);
325                         char * start = strchr(cmd, ':');
326                         if (!start) {
327                                 gdb_send_reply(g, "E01");
328                                 break;
329                         }
330                         if (addr < 0xffff) {
331                                 read_hex_string(start + 1, avr->flash + addr, strlen(start+1));
332                                 gdb_send_reply(g, "OK");                        
333                         } else if (addr >= 0x800000 && (addr - 0x800000) <= avr->ramend) {
334                                 read_hex_string(start + 1, avr->data + addr - 0x800000, strlen(start+1));
335                                 gdb_send_reply(g, "OK");                                                        
336                         } else if (addr >= 0x810000 && (addr - 0x810000) <= avr->e2end) {
337                                 read_hex_string(start + 1, (uint8_t*)rep, strlen(start+1));
338                                 avr_eeprom_desc_t ee = {.offset = (addr - 0x810000), .size = len, .ee = (uint8_t*)rep };
339                                 avr_ioctl(avr, AVR_IOCTL_EEPROM_SET, &ee);
340                                 gdb_send_reply(g, "OK");                                                        
341                         } else {
342                                 printf("write memory error %08x, %08x\n", addr, len);
343                                 gdb_send_reply(g, "E01");
344                         }               
345                 }       break;
346                 case 'c': {     // continue
347                         avr->state = cpu_Running;
348                 }       break;
349                 case 's': {     // step
350                         avr->state = cpu_Step;
351                 }       break;
352                 case 'r': {     // deprecated, suggested for AVRStudio compatibility
353                         avr->state = cpu_StepDone;
354                         avr_reset(avr);
355                 }       break;
356                 case 'Z':       // set clear break/watchpoint
357                 case 'z': {
358                         uint32_t kind, addr, len;
359                         int set = (command == 'Z');
360                         sscanf(cmd, "%d,%x,%x", &kind, &addr, &len);
361 //                      printf("breakpoint %d, %08x, %08x\n", kind, addr, len);
362                         switch (kind) {
363                                 case 0: // software breakpoint
364                                 case 1: // hardware breakpoint
365                                         if (addr > avr->flashend ||
366                                                         gdb_change_breakpoint(&g->breakpoints, set, 1 << kind, addr, len) == -1) {
367                                                 gdb_send_reply(g, "E01");
368                                                 break;
369                                         }
370
371                                         gdb_send_reply(g, "OK");
372                                         break;
373                                 case 2: // write watchpoint
374                                 case 3: // read watchpoint
375                                 case 4: // access watchpoint
376                                         /* Mask out the offset applied to SRAM addresses. */
377                                         addr &= ~0x800000;
378                                         if (addr > avr->ramend ||
379                                                         gdb_change_breakpoint(&g->watchpoints, set, 1 << kind, addr, len) == -1) {
380                                                 gdb_send_reply(g, "E01");
381                                                 break;
382                                         }
383
384                                         gdb_send_reply(g, "OK");
385                                         break;
386                                 default:
387                                         gdb_send_reply(g, "");
388                                         break;
389                         }
390                 }       break;
391                 default:
392                         gdb_send_reply(g, "");
393                         break;
394         }
395 }
396
397 static int gdb_network_handler(avr_gdb_t * g, uint32_t dosleep)
398 {
399         fd_set read_set;
400         int max;
401         FD_ZERO(&read_set);
402
403         if (g->s != -1) {
404                 FD_SET(g->s, &read_set);
405                 max = g->s + 1;
406         } else {
407                 FD_SET(g->listen, &read_set);
408                 max = g->listen + 1;
409         }
410         struct timeval timo = { 0, dosleep };   // short, but not too short interval
411         int ret = select(max, &read_set, NULL, NULL, &timo);
412
413         if (ret == 0)
414                 return 0;
415         
416         if (FD_ISSET(g->listen, &read_set)) {
417                 g->s = accept(g->listen, NULL, NULL);
418
419                 if (g->s == -1) {
420                         perror("gdb_network_handler accept");
421                         sleep(5);
422                         return 1;
423                 }
424         int i = 1;
425         setsockopt (g->s, IPPROTO_TCP, TCP_NODELAY, &i, sizeof (i));
426                 g->avr->state = cpu_Stopped;
427                 printf("%s connection opened\n", __FUNCTION__);         
428         }
429                 
430         if (g->s != -1 && FD_ISSET(g->s, &read_set)) {
431                 uint8_t buffer[1024];
432                 
433                 ssize_t r = recv(g->s, buffer, sizeof(buffer)-1, 0);
434
435                 if (r == 0) {
436                         printf("%s connection closed\n", __FUNCTION__);
437                         close(g->s);
438                         gdb_watch_clear(&g->breakpoints);
439                         gdb_watch_clear(&g->watchpoints);
440                         g->avr->state = cpu_Running;    // resume
441                         g->s = -1;
442                         return 1;
443                 }
444                 if (r == -1) {
445                         perror("gdb_network_handler recv");
446                         sleep(1);
447                         return 1;
448                 }
449                 buffer[r] = 0;
450         //      printf("%s: received %d bytes\n'%s'\n", __FUNCTION__, r, buffer);
451         //      hdump("gdb", buffer, r);
452
453                 uint8_t * src = buffer;
454                 while (*src == '+' || *src == '-')
455                         src++;
456                 // control C -- lets send the guy a nice status packet
457                 if (*src == 3) {
458                         src++;
459                         g->avr->state = cpu_StepDone;
460                         printf("GDB hit control-c\n");
461                 }
462                 if (*src  == '$') {
463                         // strip checksum
464                         uint8_t * end = buffer + r - 1;
465                         while (end > src && *end != '#')
466                                 *end-- = 0;
467                         *end = 0;
468                         src++;
469                         DBG(printf("GDB command = '%s'\n", src);)
470
471                         send(g->s, "+", 1, 0);
472
473                         gdb_handle_command(g, (char*)src);
474                 }
475         }
476         return 1;
477 }
478
479 /**
480  * If an applicable watchpoint exists for addr, stop the cpu and send a status report.
481  * type is one of AVR_GDB_WATCH_READ, AVR_GDB_WATCH_WRITE depending on the type of access.
482  */
483 void avr_gdb_handle_watchpoints(avr_t * avr, uint16_t addr, enum avr_gdb_watch_type type)
484 {
485         avr_gdb_t *g = avr->gdb;
486
487         int i = gdb_watch_find_range(&g->watchpoints, addr);
488         if (i == -1) {
489                 return;
490         }
491
492         int kind = g->watchpoints.points[i].kind;
493         if (kind & type) {
494                 /* Send gdb reply (see GDB user manual appendix E.3). */
495                 char cmd[78];
496                 sprintf(cmd, "T%02x20:%02x;21:%02x%02x;22:%02x%02x%02x00;%s:%06x;",
497                                 5, g->avr->data[R_SREG],
498                                 g->avr->data[R_SPL], g->avr->data[R_SPH],
499                                 g->avr->pc & 0xff, (g->avr->pc>>8)&0xff, (g->avr->pc>>16)&0xff,
500                                 kind & AVR_GDB_WATCH_ACCESS ? "awatch" : kind & AVR_GDB_WATCH_WRITE ? "watch" : "rwatch",
501                                 addr | 0x800000);
502                 gdb_send_reply(g, cmd);
503
504                 avr->state = cpu_Stopped;
505         }
506 }
507
508 int avr_gdb_processor(avr_t * avr, int sleep)
509 {
510         if (!avr || !avr->gdb)
511                 return 0;       
512         avr_gdb_t * g = avr->gdb;
513
514         if (avr->state == cpu_Running && gdb_watch_find(&g->breakpoints, avr->pc) != -1) {
515                 DBG(printf("avr_gdb_processor hit breakpoint at %08x\n", avr->pc);)
516                 gdb_send_quick_status(g, 0);
517                 avr->state = cpu_Stopped;
518         } else if (avr->state == cpu_StepDone) {
519                 gdb_send_quick_status(g, 0);
520                 avr->state = cpu_Stopped;
521         }
522         // this also sleeps for a bit
523         return gdb_network_handler(g, sleep);
524 }
525
526
527 int avr_gdb_init(avr_t * avr)
528 {
529         avr_gdb_t * g = malloc(sizeof(avr_gdb_t));
530         memset(g, 0, sizeof(avr_gdb_t));
531
532         avr->gdb = NULL;
533
534         if ((g->listen = socket(PF_INET, SOCK_STREAM, 0)) < 0) {
535                 fprintf(stderr, "Can't create socket: %s", strerror(errno));
536                 return -1;
537         }
538
539         int i = 1;
540         setsockopt(g->listen, SOL_SOCKET, SO_REUSEADDR, &i, sizeof(i));
541
542         struct sockaddr_in address = { 0 };
543         address.sin_family = AF_INET;
544         address.sin_port = htons (avr->gdb_port);
545
546         if (bind(g->listen, (struct sockaddr *) &address, sizeof(address))) {
547                 fprintf(stderr, "Can not bind socket: %s", strerror(errno));
548                 return -1;
549         }
550         if (listen(g->listen, 1)) {
551                 perror("listen");
552                 return -1;
553         }
554         printf("avr_gdb_init listening on port %d\n", avr->gdb_port);
555         g->avr = avr;
556         g->s = -1;
557         avr->gdb = g;
558         // change default run behaviour to use the slightly slower versions
559         avr->run = avr_callback_run_gdb;
560         avr->sleep = avr_callback_sleep_gdb;
561         
562         return 0;
563 }