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