Bind to localhost.
[fw/stlink] / src / gdb-server.c
1 /* -*- tab-width:8 -*- */
2
3 /*
4  Copyright (C)  2011 Peter Zotov <whitequark@whitequark.org>
5  Use of this source code is governed by a BSD-style
6  license that can be found in the LICENSE file.
7 */
8
9 #include <stdio.h>
10 #include <string.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <sys/types.h>
14 #include <sys/socket.h>
15 #include <netinet/in.h>
16 #include <arpa/inet.h>
17 #include "gdb-remote.h"
18 #include "stlink-hw.h"
19
20 static const char hex[] = "0123456789abcdef";
21
22 int serve(struct stlink* sl, int port);
23
24 int main(int argc, char** argv) {
25         if(argc != 3) {
26                 fprintf(stderr, "Usage: %s <port> /dev/sgX\n", argv[0]);
27                 return 1;
28         }
29
30         struct stlink *sl = stlink_quirk_open(argv[2], 0);
31         if (sl == NULL)
32                 return 1;
33
34         if(stlink_current_mode(sl) != STLINK_DEV_DEBUG_MODE)
35                 stlink_enter_swd_mode(sl);
36
37         stlink_core_id(sl);
38         printf("Debugging ARM core %08x.\n", sl->core_id);
39
40         int port = atoi(argv[1]);
41
42         while(serve(sl, port) == 0);
43
44         stlink_close(sl);
45
46         return 0;
47 }
48
49 int serve(struct stlink* sl, int port) {
50         int sock = socket(AF_INET, SOCK_STREAM, 0);
51         if(sock < 0) {
52                 perror("socket");
53                 return 1;
54         }
55
56         unsigned int val = 1;
57         setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, &val, sizeof(val));
58
59         struct sockaddr_in serv_addr = {0};
60         serv_addr.sin_family = AF_INET;
61         serv_addr.sin_addr.s_addr = inet_addr("127.0.0.1");
62         serv_addr.sin_port = htons(port);
63
64         if(bind(sock, (struct sockaddr *) &serv_addr, sizeof(serv_addr)) < 0) {
65                 perror("bind");
66                 return 1;
67         }
68
69         if(listen(sock, 5) < 0) {
70                 perror("listen");
71                 return 1;
72         }
73
74         stlink_force_debug(sl);
75         stlink_reset(sl);
76
77         printf("Listening at *:%d...\n", port);
78
79         int client = accept(sock, NULL, NULL);
80         if(client < 0) {
81                 perror("accept");
82                 return 1;
83         }
84
85         close(sock);
86
87         printf("GDB connected.\n");
88
89         while(1) {
90                 char* packet;
91
92                 int status = gdb_recv_packet(client, &packet);
93                 if(status < 0) {
94                         fprintf(stderr, "cannot recv: %d\n", status);
95                         return 1;
96                 }
97
98                 //printf("recv: %s\n", packet);
99
100                 char* reply = NULL;
101
102                 switch(packet[0]) {
103                 case 'c':
104                         stlink_run(sl);
105
106                         printf("Core running, waiting for interrupt.\n");
107
108                         int status = gdb_wait_for_interrupt(client);
109                         if(status < 0) {
110                                 fprintf(stderr, "cannot wait for int: %d\n", status);
111                                 return 1;
112                         }
113
114                         stlink_force_debug(sl);
115
116                         reply = strdup("S05"); // TRAP
117                         break;
118
119                 case 's':
120                         stlink_step(sl);
121
122                         reply = strdup("S05"); // TRAP
123                         break;
124
125                 case '?':
126                         reply = strdup("S05"); // TRAP
127                         break;
128
129                 case 'g':
130                         stlink_read_all_regs(sl);
131
132                         reply = calloc(8 * 16 + 1, 1);
133                         for(int i = 0; i < 16; i++)
134                                 sprintf(&reply[i * 8], "%08x", htonl(sl->reg.r[i]));
135
136                         break;
137
138                 case 'p': {
139                         unsigned id = strtoul(&packet[1], NULL, 16), reg = 0xDEADDEAD;
140
141                         if(id < 16) {
142                                 stlink_read_reg(sl, id);
143                                 reg = htonl(sl->reg.r[id]);
144                         } else if(id == 0x19) {
145                                 stlink_read_reg(sl, 16);
146                                 reg = htonl(sl->reg.xpsr);
147                         } else {
148                                 reply = strdup("E00");
149                         }
150
151                         reply = calloc(8 + 1, 1);
152                         sprintf(reply, "%08x", reg);
153
154                         break;
155                 }
156
157                 case 'P': {
158                         char* s_reg = &packet[1];
159                         char* s_value = strstr(&packet[1], "=") + 1;
160
161                         unsigned reg   = strtoul(s_reg,   NULL, 16);
162                         unsigned value = strtoul(s_value, NULL, 16);
163
164                         if(reg < 16) {
165                                 stlink_write_reg(sl, ntohl(value), reg);
166                         } else if(reg == 0x19) {
167                                 stlink_write_reg(sl, ntohl(value), 16);
168                         } else {
169                                 reply = strdup("E00");
170                         }
171
172                         if(!reply) {
173                                 reply = strdup("OK");
174                         }
175
176                         break;
177                 }
178
179                 case 'G':
180                         for(int i = 0; i < 16; i++) {
181                                 char str[9] = {0};
182                                 strncpy(str, &packet[1 + i * 8], 8);
183                                 uint32_t reg = strtoul(str, NULL, 16);
184                                 stlink_write_reg(sl, ntohl(reg), i);
185                         }
186
187                         reply = strdup("OK");
188                         break;
189
190                 case 'm': {
191                         char* s_start = &packet[1];
192                         char* s_count = strstr(&packet[1], ",") + 1;
193
194                         stm32_addr_t start = strtoul(s_start, NULL, 16);
195                         unsigned     count = strtoul(s_count, NULL, 16);
196
197                         unsigned adj_start = start % 4;
198
199                         stlink_read_mem32(sl, start - adj_start, (count % 4 == 0) ?
200                                                 count : count + 4 - (count % 4));
201
202                         reply = calloc(count * 2 + 1, 1);
203                         for(int i = 0; i < count; i++) {
204                                 reply[i * 2 + 0] = hex[sl->q_buf[i + adj_start] >> 4];
205                                 reply[i * 2 + 1] = hex[sl->q_buf[i + adj_start] & 0xf];
206                         }
207
208                         break;
209                 }
210
211                 case 'M': {
212                         char* s_start = &packet[1];
213                         char* s_count = strstr(&packet[1], ",") + 1;
214                         char* hexdata = strstr(packet, ":") + 1;
215
216                         stm32_addr_t start = strtoul(s_start, NULL, 16);
217                         unsigned     count = strtoul(s_count, NULL, 16);
218
219                         for(int i = 0; i < count; i ++) {
220                                 char hex[3] = { hexdata[i*2], hexdata[i*2+1], 0 };
221                                 uint8_t byte = strtoul(hex, NULL, 16);
222                                 sl->q_buf[i] = byte;
223                         }
224
225                         if((count % 4) == 0 && (start % 4) == 0) {
226                                 stlink_write_mem32(sl, start, count);
227                         } else {
228                                 stlink_write_mem8(sl, start, count);
229                         }
230
231                         reply = strdup("OK");
232
233                         break;
234                 }
235
236                 case 'k': {
237                         // After this function will be entered afterwards, the
238                         // chip will be reset anyway. So this is a no-op.
239
240                         close(client);
241                         return 0;
242                 }
243
244                 default:
245                         reply = strdup("");
246                 }
247
248                 if(reply) {
249                         //printf("send: %s\n", reply);
250
251                         int result = gdb_send_packet(client, reply);
252                         if(result != 0) {
253                                 fprintf(stderr, "cannot send: %d\n", result);
254                                 return 1;
255                         }
256
257                         free(reply);
258                 }
259
260                 free(packet);
261         }
262
263         return 0;
264 }