Move PTRACE_GETREGSET and PTRACE_SETREGSET to nat/linux-ptrace.h
[binutils-gdb.git] / sim / cris / rvdummy.c
1 /* Test-driver for the remote-virtual-component simulator framework
2 for GDB, the GNU Debugger.
3
4 Copyright 2006-2015 Free Software Foundation, Inc.
5
6 This file is part of GDB.
7
8 This program 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 This program 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 this program. If not, see <http://www.gnu.org/licenses/>. */
20
21 /* Avoid any problems whatsoever building this program if we're not
22 also building hardware support. */
23
24 #if !WITH_HW
25 int
26 main (int argc, char *argv[])
27 {
28 return 2;
29 }
30 #else
31
32 #ifdef HAVE_CONFIG_H
33 #include "cconfig.h"
34 #endif
35
36 #include "getopt.h"
37 #include "libiberty.h"
38
39 #define _GNU_SOURCE
40 #include <stdio.h>
41
42 #ifdef HAVE_UNISTD_H
43 #include <unistd.h>
44 #endif
45 #ifdef HAVE_STDLIB_H
46 #include <stdlib.h>
47 #endif
48 #ifdef HAVE_STRING_H
49 #include <string.h>
50 #endif
51
52 #ifdef HAVE_SYS_TYPES_H
53 #include <sys/types.h>
54 #endif
55
56 #ifdef HAVE_SYS_TIME_H
57 #include <sys/time.h>
58 #endif
59
60 #ifdef HAVE_SYS_SELECT_H
61 #include <sys/select.h>
62 #endif
63
64 #ifdef HAVE_ERRNO_H
65 #include <errno.h>
66 #endif
67
68 /* Not guarded in dv-sockser.c, so why here. */
69 #include <netinet/in.h>
70 #include <arpa/inet.h>
71 #include <netdb.h>
72 #include <sys/socket.h>
73
74 enum rv_command {
75 RV_READ_CMD = 0,
76 RV_WRITE_CMD = 1,
77 RV_IRQ_CMD = 2,
78 RV_MEM_RD_CMD = 3,
79 RV_MEM_WR_CMD = 4,
80 RV_MBOX_HANDLE_CMD = 5,
81 RV_MBOX_PUT_CMD = 6,
82 RV_WATCHDOG_CMD = 7
83 };
84
85 enum opts { OPT_PORT = 1, OPT_TIMEOUT, OPT_VERBOSE };
86
87 struct option longopts[] =
88 {
89 {"port", required_argument, NULL, OPT_PORT},
90 {"timeout", required_argument, NULL, OPT_TIMEOUT},
91 {"verbose", no_argument, NULL, OPT_VERBOSE},
92 {NULL, 0, NULL, 0}
93 };
94
95 int port = 10000;
96 time_t timeout = 30000;
97 char *progname = "(unknown)";
98 int verbose = 0;
99
100 /* Required forward-declarations. */
101 static void handle_input_file (int, char *);
102
103 /* Set up a "server" listening to the port in PORT for a raw TCP
104 connection. Return a file descriptor for the connection or -1 on
105 error. */
106
107 int setupsocket (void)
108 {
109 int s;
110 socklen_t len;
111 int reuse = 1;
112 struct sockaddr_in sa_in;
113 struct sockaddr_in from;
114
115 len = sizeof (from);
116 memset (&from, 0, len);
117 memset (&sa_in, 0, sizeof (sa_in));
118
119 s = socket (AF_INET, SOCK_STREAM, 0);
120 if (s == -1)
121 return -1;
122
123 if (setsockopt (s, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof reuse) != 0)
124 return -1;
125
126 sa_in.sin_port = htons (port);
127 sa_in.sin_family = AF_INET;
128
129 if (bind (s, (struct sockaddr *) & sa_in, sizeof sa_in) < 0)
130 return -1;
131
132 if (listen (s, 1) < 0)
133 return -1;
134
135 return accept (s, (struct sockaddr *) &from, &len);
136 }
137
138 /* Basic host-to-little-endian 32-bit value. Could use the BFD
139 machinery, but let's avoid it for this only dependency. */
140
141 static void
142 h2le32 (unsigned char *dest, unsigned int val)
143 {
144 dest[0] = val & 255;
145 dest[1] = (val >> 8) & 255;
146 dest[2] = (val >> 16) & 255;
147 dest[3] = (val >> 24) & 255;
148 }
149
150 /* Send a blob of data. */
151
152 static void
153 send_output (int fd, unsigned char *buf, int nbytes)
154 {
155 while (nbytes > 0)
156 {
157 ssize_t written = write (fd, buf, nbytes);
158 if (written < 0)
159 {
160 fprintf (stderr, "%s: write to socket failed: %s\n",
161 progname, strerror (errno));
162 exit (2);
163 }
164 nbytes -= written;
165 }
166 }
167
168 /* Receive a blob of data, NBYTES large. Compare to the first NCOMP
169 bytes of BUF; if not a match, write error message to stderr and
170 exit (2). Else put it in buf. */
171
172 static void
173 expect_input (int fd, unsigned char *buf, int nbytes, int ncomp)
174 {
175 unsigned char byt;
176 int i;
177
178 for (i = 0; i < nbytes; i++)
179 {
180 int r;
181
182 do
183 {
184 errno = 0;
185 r = read (fd, &byt, 1);
186 }
187 while (r <= 0 && (r == 0 || errno == EAGAIN));
188
189 if (r != 1)
190 {
191 fprintf (stderr, "%s: read from socket failed: %s",
192 progname, strerror (errno));
193 exit (2);
194 }
195
196 if (i < ncomp && byt != buf[i])
197 {
198 int j;
199 fprintf (stderr, "%s: unexpected input,\n ", progname);
200 if (i == 0)
201 fprintf (stderr, "nothing,");
202 else
203 for (j = 0; j < i; j++)
204 fprintf (stderr, "%02x", buf[j]);
205 fprintf (stderr, "\nthen %02x instead of %02x\n", byt, buf[i]);
206 exit (2);
207 }
208 else
209 buf[i] = byt;
210 }
211 }
212
213 /* Handle everything about a nil-terminated line of input.
214 Call exit (2) on error with error text on stderr. */
215
216 static void
217 handle_input (int fd, char *buf, char *fname, int lineno)
218 {
219 int nbytes = 0;
220 int n = -1;
221 char *s = buf + 2;
222 unsigned int data;
223 static unsigned char bytes[1024];
224 int i;
225
226 memset (bytes, 0, sizeof bytes);
227 lineno++;
228
229 if (buf[1] != ',')
230 goto syntax_error;
231
232 switch (buf[0])
233 {
234 /* Comment characters and empty lines. */
235 case 0: case '!': case '#':
236 break;
237
238 /* Include another file. */
239 case '@':
240 handle_input_file (fd, s);
241 break;
242
243 /* Raw input (to be expected). */
244 case 'i':
245 do
246 {
247 n = -1;
248 sscanf (s, "%02x%n", &data, &n);
249 s += n;
250 if (n > 0)
251 bytes[nbytes++] = data;
252 }
253 while (n > 0);
254 expect_input (fd, bytes, nbytes, nbytes);
255 if (verbose)
256 {
257 printf ("i,");
258 for (i = 0; i < nbytes; i++)
259 printf ("%02x", bytes[i]);
260 printf ("\n");
261 }
262 break;
263
264 /* Raw output (to be written). */
265 case 'o':
266 do
267 {
268 n = -1;
269 sscanf (s, "%02x%n", &data, &n);
270 if (n > 0)
271 {
272 s += n;
273 bytes[nbytes++] = data;
274 }
275 }
276 while (n > 0);
277 if (*s != 0)
278 goto syntax_error;
279 send_output (fd, bytes, nbytes);
280 if (verbose)
281 {
282 printf ("o,");
283 for (i = 0; i < nbytes; i++)
284 printf ("%02x", bytes[i]);
285 printf ("\n");
286 }
287 break;
288
289 /* Read a register. */
290 case 'r':
291 {
292 unsigned int addr;
293 sscanf (s, "%x,%x%n", &addr, &data, &n);
294 if (n < 0 || s[n] != 0)
295 goto syntax_error;
296 bytes[0] = 11;
297 bytes[1] = 0;
298 bytes[2] = RV_READ_CMD;
299 h2le32 (bytes + 3, addr);
300 expect_input (fd, bytes, 11, 7);
301 h2le32 (bytes + 7, data);
302 send_output (fd, bytes, 11);
303 if (verbose)
304 printf ("r,%x,%x\n", addr, data);
305 }
306 break;
307
308 /* Write a register. */
309 case 'w':
310 {
311 unsigned int addr;
312 sscanf (s, "%x,%x%n", &addr, &data, &n);
313 if (n < 0 || s[n] != 0)
314 goto syntax_error;
315 bytes[0] = 11;
316 bytes[1] = 0;
317 bytes[2] = RV_WRITE_CMD;
318 h2le32 (bytes + 3, addr);
319 h2le32 (bytes + 7, data);
320 expect_input (fd, bytes, 11, 11);
321 send_output (fd, bytes, 11);
322 if (verbose)
323 printf ("w,%x,%x\n", addr, data);
324 }
325 break;
326
327 /* Wait for some milliseconds. */
328 case 't':
329 {
330 int del = 0;
331 struct timeval to;
332 sscanf (s, "%d%n", &del, &n);
333 if (n < 0 || s[n] != 0 || del == 0)
334 goto syntax_error;
335
336 to.tv_sec = del / 1000;
337 to.tv_usec = (del % 1000) * 1000;
338
339 if (select (0, NULL, NULL, NULL, &to) != 0)
340 {
341 fprintf (stderr, "%s: problem waiting for %d ms:\n %s\n",
342 progname, del, strerror (errno));
343 exit (2);
344 }
345 if (verbose)
346 printf ("t,%d\n", del);
347 }
348 break;
349
350 /* Expect a watchdog command. */
351 case 'W':
352 if (*s != 0)
353 goto syntax_error;
354 bytes[0] = 3;
355 bytes[1] = 0;
356 bytes[2] = RV_WATCHDOG_CMD;
357 expect_input (fd, bytes, 3, 3);
358 if (verbose)
359 printf ("W\n");
360 break;
361
362 /* Send an IRQ notification. */
363 case 'I':
364 sscanf (s, "%x%n", &data, &n);
365 if (n < 0 || s[n] != 0)
366 goto syntax_error;
367 bytes[0] = 7;
368 bytes[1] = 0;
369 bytes[2] = RV_IRQ_CMD;
370 h2le32 (bytes + 3, data);
371 send_output (fd, bytes, 7);
372 if (verbose)
373 printf ("I,%x\n", data);
374 break;
375
376 /* DMA store (to CPU). */
377 case 's':
378 {
379 unsigned int addr;
380 sscanf (s, "%x,%n", &addr, &n);
381
382 if (n < 0 || s[n] == 0)
383 goto syntax_error;
384 s += n;
385 do
386 {
387 n = -1;
388 sscanf (s, "%02x%n", &data, &n);
389 if (n > 0)
390 {
391 s += n;
392 bytes[11 + nbytes++] = data;
393 }
394 }
395 while (n > 0);
396
397 if (*s != 0)
398 goto syntax_error;
399 h2le32 (bytes, nbytes + 11);
400 bytes[2] = RV_MEM_WR_CMD;
401 h2le32 (bytes + 3, addr);
402 h2le32 (bytes + 7, nbytes);
403 send_output (fd, bytes, nbytes + 11);
404 if (verbose)
405 {
406 printf ("s,%x,", addr);
407 for (i = 0; i < nbytes; i++)
408 printf ("%02x", bytes[i]);
409 printf ("\n");
410 }
411 }
412 break;
413
414 /* DMA load (from CPU). */
415 case 'l':
416 {
417 unsigned int addr;
418 sscanf (s, "%x,%n", &addr, &n);
419
420 if (n < 0 || s[n] == 0)
421 goto syntax_error;
422 s += n;
423 do
424 {
425 n = -1;
426 sscanf (s, "%02x%n", &data, &n);
427 if (n > 0)
428 {
429 s += n;
430 bytes[11 + nbytes++] = data;
431 }
432 }
433 while (n > 0);
434
435 if (*s != 0)
436 goto syntax_error;
437 h2le32 (bytes, nbytes + 11);
438 bytes[0] = 11;
439 bytes[1] = 0;
440 bytes[2] = RV_MEM_RD_CMD;
441 h2le32 (bytes + 3, addr);
442 h2le32 (bytes + 7, nbytes);
443 send_output (fd, bytes, 11);
444 bytes[0] = (nbytes + 11) & 255;
445 bytes[1] = ((nbytes + 11) >> 8) & 255;
446 expect_input (fd, bytes, nbytes + 11, nbytes + 11);
447 if (verbose)
448 {
449 printf ("l,%x,", addr);
450 for (i = 0; i < nbytes; i++)
451 printf ("%02x", bytes[i]);
452 printf ("\n");
453 }
454 }
455 break;
456
457 syntax_error:
458 default:
459 fprintf (stderr, "%s: invalid command line in %s:%d:\n %s",
460 progname, fname, lineno, strerror (errno));
461 exit (2);
462 }
463 }
464
465 /* Loop over the contents of FNAME, using handle_input to parse each line.
466 Errors to stderr, exit (2). */
467
468 static void
469 handle_input_file (int fd, char *fname)
470 {
471 static char buf[2048] = {0};
472 int lineno = 0;
473 FILE *f = fopen (fname, "r");
474
475 if (f == NULL)
476 {
477 fprintf (stderr, "%s: problem opening %s: %s\n",
478 progname, fname, strerror (errno));
479 exit (2);
480 }
481
482 /* Let's cut the buffer short, so we always get a newline. */
483 while (fgets (buf, sizeof (buf) - 1, f) != NULL)
484 {
485 buf[strlen (buf) - 1] = 0;
486 lineno++;
487 handle_input (fd, buf, fname, lineno);
488 }
489
490 fclose (f);
491 }
492
493 int
494 main (int argc, char *argv[])
495 {
496 int optc;
497 int fd;
498 FILE *f;
499 int i;
500
501 progname = argv[0];
502 while ((optc = getopt_long (argc, argv, "", longopts, NULL)) != -1)
503 switch (optc)
504 {
505 case OPT_PORT:
506 port = atoi (optarg);
507 break;
508
509 case OPT_TIMEOUT:
510 timeout = (time_t) atoi (optarg);
511 break;
512
513 case OPT_VERBOSE:
514 verbose = 1;
515 break;
516 }
517
518 fd = setupsocket ();
519 if (fd == -1)
520 {
521 fprintf (stderr, "%s: problem setting up the connection: %s\n",
522 progname, strerror (errno));
523 exit (2);
524 }
525
526 for (i = optind; i < argc; i++)
527 handle_input_file (fd, argv[i]);
528
529 /* FIXME: option-controlled test for remaining input? */
530 close (fd);
531 return 1;
532 }
533 #endif