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