]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/common/syscall.c
sim: reorder header includes
[thirdparty/binutils-gdb.git] / sim / common / syscall.c
1 /* Remote target system call support.
2 Copyright 1997-2021 Free Software Foundation, Inc.
3 Contributed by Cygnus Solutions.
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
19
20 /* This interface isn't intended to be specific to any particular kind
21 of remote (hardware, simulator, whatever). As such, support for it
22 (e.g. sim/common/callback.c) should *not* live in the simulator source
23 tree, nor should it live in the gdb source tree. K&R C must be
24 supported. */
25
26 /* This must come before any other includes. */
27 #include "defs.h"
28
29 #include <errno.h>
30 #include <fcntl.h>
31 #include <stdarg.h>
32 #include <stdio.h>
33 #include <stdlib.h>
34 #include <string.h>
35 #include <time.h>
36 #ifdef HAVE_UNISTD_H
37 #include <unistd.h>
38 #endif
39 #include <sys/stat.h>
40 #include <sys/types.h>
41
42 #include "ansidecl.h"
43 #include "libiberty.h"
44
45 #include "sim/callback.h"
46
47 #ifndef ENOSYS
48 #define ENOSYS EINVAL
49 #endif
50 #ifndef ENAMETOOLONG
51 #define ENAMETOOLONG EINVAL
52 #endif
53
54 /* Maximum length of a path name. */
55 #ifndef MAX_PATH_LEN
56 #define MAX_PATH_LEN 1024
57 #endif
58
59 /* When doing file read/writes, do this many bytes at a time. */
60 #define FILE_XFR_SIZE 4096
61
62 /* FIXME: for now, need to consider target word size. */
63 #define TWORD long
64 #define TADDR unsigned long
65
66 /* Path to be prepended to syscalls with absolute paths, and to be
67 chdir:ed at startup, if not empty. */
68 char *simulator_sysroot = "";
69
70 /* Utility of cb_syscall to fetch a path name or other string from the target.
71 The result is 0 for success or a host errno value. */
72
73 int
74 cb_get_string (host_callback *cb, CB_SYSCALL *sc, char *buf, int buflen,
75 TADDR addr)
76 {
77 char *p, *pend;
78
79 for (p = buf, pend = buf + buflen; p < pend; ++p, ++addr)
80 {
81 /* No, it isn't expected that this would cause one transaction with
82 the remote target for each byte. The target could send the
83 path name along with the syscall request, and cache the file
84 name somewhere (or otherwise tweak this as desired). */
85 unsigned int count = (*sc->read_mem) (cb, sc, addr, p, 1);
86
87 if (count != 1)
88 return EINVAL;
89 if (*p == 0)
90 break;
91 }
92 if (p == pend)
93 return ENAMETOOLONG;
94 return 0;
95 }
96
97 /* Utility of cb_syscall to fetch a path name.
98 The buffer is malloc'd and the address is stored in BUFP.
99 The result is that of get_string, but prepended with
100 simulator_sysroot if the string starts with '/'.
101 If an error occurs, no buffer is left malloc'd. */
102
103 static int
104 get_path (host_callback *cb, CB_SYSCALL *sc, TADDR addr, char **bufp)
105 {
106 char *buf = xmalloc (MAX_PATH_LEN);
107 int result;
108 int sysroot_len = strlen (simulator_sysroot);
109
110 result = cb_get_string (cb, sc, buf, MAX_PATH_LEN - sysroot_len, addr);
111 if (result == 0)
112 {
113 /* Prepend absolute paths with simulator_sysroot. Relative paths
114 are supposed to be relative to a chdir within that path, but at
115 this point unknown where. */
116 if (simulator_sysroot[0] != '\0' && *buf == '/')
117 {
118 /* Considering expected rareness of syscalls with absolute
119 file paths (compared to relative file paths and insn
120 execution), it does not seem worthwhile to rearrange things
121 to get rid of the string moves here; we'd need at least an
122 extra call to check the initial '/' in the path. */
123 memmove (buf + sysroot_len, buf, sysroot_len);
124 memcpy (buf, simulator_sysroot, sysroot_len);
125 }
126
127 *bufp = buf;
128 }
129 else
130 free (buf);
131 return result;
132 }
133
134 /* Perform a system call on behalf of the target. */
135
136 CB_RC
137 cb_syscall (host_callback *cb, CB_SYSCALL *sc)
138 {
139 TWORD result = 0, errcode = 0;
140
141 if (sc->magic != CB_SYSCALL_MAGIC)
142 abort ();
143
144 switch (cb_target_to_host_syscall (cb, sc->func))
145 {
146 case CB_SYS_argc:
147 result = countargv (cb->argv);
148 break;
149
150 case CB_SYS_argnlen:
151 {
152 if (sc->arg1 >= 0 && sc->arg1 < countargv (cb->argv))
153 result = strlen (cb->argv[sc->arg1]);
154 else
155 {
156 result = -1;
157 errcode = EINVAL;
158 }
159 }
160 break;
161
162 case CB_SYS_argn:
163 {
164 if (sc->arg1 >= 0 && sc->arg1 < countargv (cb->argv))
165 {
166 const char *argn = cb->argv[sc->arg1];
167 int len = strlen (argn);
168 int written = sc->write_mem (cb, sc, sc->arg2, argn, len + 1);
169
170 if (written == len + 1)
171 result = sc->arg2;
172 else
173 {
174 result = -1;
175 errcode = EINVAL;
176 }
177 }
178 else
179 {
180 result = -1;
181 errcode = EINVAL;
182 }
183 }
184 break;
185
186 case CB_SYS_argvlen :
187 {
188 /* Compute how much space is required to store the argv,envp
189 strings so that the program can allocate the space and then
190 call SYS_argv to fetch the values. */
191 int argc, envc, arglen, envlen;
192 char **argv = cb->argv;
193 char **envp = cb->envp;
194
195 argc = arglen = 0;
196 if (argv)
197 {
198 for ( ; argv[argc]; ++argc)
199 arglen += strlen (argv[argc]) + 1;
200 }
201 envc = envlen = 0;
202 if (envp)
203 {
204 for ( ; envp[envc]; ++envc)
205 envlen += strlen (envp[envc]) + 1;
206 }
207 result = arglen + 1 + envlen + 1;
208 break;
209 }
210
211 case CB_SYS_argv :
212 {
213 /* Pointer to target's buffer. */
214 TADDR tbuf = sc->arg1;
215 /* Buffer size. */
216 int bufsize = sc->arg2;
217 int written = 0;
218 /* Q is the target address of where all the strings go. */
219 TADDR q;
220 int i, argc, envc, len, ret;
221 char **argv = cb->argv;
222 char **envp = cb->envp;
223
224 result = -1;
225
226 argc = 0;
227 if (argv)
228 {
229 for ( ; argv[argc]; ++argc)
230 {
231 len = strlen (argv[argc]) + 1;
232 if (written + len > bufsize)
233 goto efault;
234
235 ret = (*sc->write_mem) (cb, sc, tbuf + written, argv[argc],
236 len);
237 if (ret != len)
238 goto einval;
239
240 written += ret;
241 }
242 }
243 /* Double NUL bytes indicates end of strings. */
244 if (written >= bufsize)
245 goto efault;
246 if ((*sc->write_mem) (cb, sc, tbuf + written, "", 1) != 1)
247 goto einval;
248 ++written;
249
250 envc = 0;
251 if (envp)
252 {
253 for ( ; envp[envc]; ++envc)
254 {
255 len = strlen (envp[envc]) + 1;
256 if (written + len > bufsize)
257 goto efault;
258
259 ret = (*sc->write_mem) (cb, sc, tbuf + written, envp[envc],
260 len);
261 if (ret != len)
262 goto einval;
263 written += ret;
264 }
265 }
266 /* Double NUL bytes indicates end of strings. */
267 if (written >= bufsize)
268 goto efault;
269 if ((*sc->write_mem) (cb, sc, tbuf + written, "", 1) != 1)
270 goto einval;
271
272 result = argc;
273 sc->result2 = envc;
274 break;
275
276 efault:
277 errcode = EFAULT;
278 goto FinishSyscall;
279
280 einval:
281 errcode = EINVAL;
282 goto FinishSyscall;
283 }
284
285 case CB_SYS_exit :
286 /* Caller must catch and handle; see sim_syscall as an example. */
287 break;
288
289 case CB_SYS_open :
290 {
291 char *path;
292
293 errcode = get_path (cb, sc, sc->arg1, &path);
294 if (errcode != 0)
295 {
296 result = -1;
297 goto FinishSyscall;
298 }
299 result = (*cb->open) (cb, path, sc->arg2 /*, sc->arg3*/);
300 free (path);
301 if (result < 0)
302 goto ErrorFinish;
303 }
304 break;
305
306 case CB_SYS_close :
307 result = (*cb->close) (cb, sc->arg1);
308 if (result < 0)
309 goto ErrorFinish;
310 break;
311
312 case CB_SYS_read :
313 {
314 /* ??? Perfect handling of error conditions may require only one
315 call to cb->read. One can't assume all the data is
316 contiguously stored in host memory so that would require
317 malloc'ing/free'ing the space. Maybe later. */
318 char buf[FILE_XFR_SIZE];
319 int fd = sc->arg1;
320 TADDR addr = sc->arg2;
321 size_t count = sc->arg3;
322 size_t bytes_read = 0;
323 int bytes_written;
324
325 while (count > 0)
326 {
327 if (cb_is_stdin (cb, fd))
328 result = (int) (*cb->read_stdin) (cb, buf,
329 (count < FILE_XFR_SIZE
330 ? count : FILE_XFR_SIZE));
331 else
332 result = (int) (*cb->read) (cb, fd, buf,
333 (count < FILE_XFR_SIZE
334 ? count : FILE_XFR_SIZE));
335 if (result == -1)
336 goto ErrorFinish;
337 if (result == 0) /* EOF */
338 break;
339 bytes_written = (*sc->write_mem) (cb, sc, addr, buf, result);
340 if (bytes_written != result)
341 {
342 result = -1;
343 errcode = EINVAL;
344 goto FinishSyscall;
345 }
346 bytes_read += result;
347 count -= result;
348 addr += result;
349 /* If this is a short read, don't go back for more */
350 if (result != FILE_XFR_SIZE)
351 break;
352 }
353 result = bytes_read;
354 }
355 break;
356
357 case CB_SYS_write :
358 {
359 /* ??? Perfect handling of error conditions may require only one
360 call to cb->write. One can't assume all the data is
361 contiguously stored in host memory so that would require
362 malloc'ing/free'ing the space. Maybe later. */
363 char buf[FILE_XFR_SIZE];
364 int fd = sc->arg1;
365 TADDR addr = sc->arg2;
366 size_t count = sc->arg3;
367 int bytes_read;
368 size_t bytes_written = 0;
369
370 while (count > 0)
371 {
372 int bytes_to_read = count < FILE_XFR_SIZE ? count : FILE_XFR_SIZE;
373 bytes_read = (*sc->read_mem) (cb, sc, addr, buf, bytes_to_read);
374 if (bytes_read != bytes_to_read)
375 {
376 result = -1;
377 errcode = EINVAL;
378 goto FinishSyscall;
379 }
380 if (cb_is_stdout (cb, fd))
381 {
382 result = (int) (*cb->write_stdout) (cb, buf, bytes_read);
383 (*cb->flush_stdout) (cb);
384 }
385 else if (cb_is_stderr (cb, fd))
386 {
387 result = (int) (*cb->write_stderr) (cb, buf, bytes_read);
388 (*cb->flush_stderr) (cb);
389 }
390 else
391 result = (int) (*cb->write) (cb, fd, buf, bytes_read);
392 if (result == -1)
393 goto ErrorFinish;
394 bytes_written += result;
395 count -= result;
396 addr += result;
397 }
398 result = bytes_written;
399 }
400 break;
401
402 case CB_SYS_lseek :
403 {
404 int fd = sc->arg1;
405 unsigned long offset = sc->arg2;
406 int whence = sc->arg3;
407
408 result = (*cb->lseek) (cb, fd, offset, whence);
409 if (result < 0)
410 goto ErrorFinish;
411 }
412 break;
413
414 case CB_SYS_unlink :
415 {
416 char *path;
417
418 errcode = get_path (cb, sc, sc->arg1, &path);
419 if (errcode != 0)
420 {
421 result = -1;
422 goto FinishSyscall;
423 }
424 result = (*cb->unlink) (cb, path);
425 free (path);
426 if (result < 0)
427 goto ErrorFinish;
428 }
429 break;
430
431 case CB_SYS_truncate :
432 {
433 char *path;
434 long len = sc->arg2;
435
436 errcode = get_path (cb, sc, sc->arg1, &path);
437 if (errcode != 0)
438 {
439 result = -1;
440 errcode = EFAULT;
441 goto FinishSyscall;
442 }
443 result = (*cb->truncate) (cb, path, len);
444 free (path);
445 if (result < 0)
446 goto ErrorFinish;
447 }
448 break;
449
450 case CB_SYS_ftruncate :
451 {
452 int fd = sc->arg1;
453 long len = sc->arg2;
454
455 result = (*cb->ftruncate) (cb, fd, len);
456 if (result < 0)
457 goto ErrorFinish;
458 }
459 break;
460
461 case CB_SYS_rename :
462 {
463 char *path1, *path2;
464
465 errcode = get_path (cb, sc, sc->arg1, &path1);
466 if (errcode != 0)
467 {
468 result = -1;
469 errcode = EFAULT;
470 goto FinishSyscall;
471 }
472 errcode = get_path (cb, sc, sc->arg2, &path2);
473 if (errcode != 0)
474 {
475 result = -1;
476 errcode = EFAULT;
477 free (path1);
478 goto FinishSyscall;
479 }
480 result = (*cb->rename) (cb, path1, path2);
481 free (path1);
482 free (path2);
483 if (result < 0)
484 goto ErrorFinish;
485 }
486 break;
487
488 case CB_SYS_stat :
489 {
490 char *path,*buf;
491 int buflen;
492 struct stat statbuf;
493 TADDR addr = sc->arg2;
494
495 errcode = get_path (cb, sc, sc->arg1, &path);
496 if (errcode != 0)
497 {
498 result = -1;
499 goto FinishSyscall;
500 }
501 result = (*cb->to_stat) (cb, path, &statbuf);
502 free (path);
503 if (result < 0)
504 goto ErrorFinish;
505 buflen = cb_host_to_target_stat (cb, NULL, NULL);
506 buf = xmalloc (buflen);
507 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
508 {
509 /* The translation failed. This is due to an internal
510 host program error, not the target's fault. */
511 free (buf);
512 errcode = ENOSYS;
513 result = -1;
514 goto FinishSyscall;
515 }
516 if ((*sc->write_mem) (cb, sc, addr, buf, buflen) != buflen)
517 {
518 free (buf);
519 errcode = EINVAL;
520 result = -1;
521 goto FinishSyscall;
522 }
523 free (buf);
524 }
525 break;
526
527 case CB_SYS_fstat :
528 {
529 char *buf;
530 int buflen;
531 struct stat statbuf;
532 TADDR addr = sc->arg2;
533
534 result = (*cb->to_fstat) (cb, sc->arg1, &statbuf);
535 if (result < 0)
536 goto ErrorFinish;
537 buflen = cb_host_to_target_stat (cb, NULL, NULL);
538 buf = xmalloc (buflen);
539 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
540 {
541 /* The translation failed. This is due to an internal
542 host program error, not the target's fault. */
543 free (buf);
544 errcode = ENOSYS;
545 result = -1;
546 goto FinishSyscall;
547 }
548 if ((*sc->write_mem) (cb, sc, addr, buf, buflen) != buflen)
549 {
550 free (buf);
551 errcode = EINVAL;
552 result = -1;
553 goto FinishSyscall;
554 }
555 free (buf);
556 }
557 break;
558
559 case CB_SYS_lstat :
560 {
561 char *path, *buf;
562 int buflen;
563 struct stat statbuf;
564 TADDR addr = sc->arg2;
565
566 errcode = get_path (cb, sc, sc->arg1, &path);
567 if (errcode != 0)
568 {
569 result = -1;
570 goto FinishSyscall;
571 }
572 result = (*cb->to_lstat) (cb, path, &statbuf);
573 free (path);
574 if (result < 0)
575 goto ErrorFinish;
576
577 buflen = cb_host_to_target_stat (cb, NULL, NULL);
578 buf = xmalloc (buflen);
579 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
580 {
581 /* The translation failed. This is due to an internal
582 host program error, not the target's fault.
583 Unfortunately, it's hard to test this case, so there's no
584 test-case for this execution path. */
585 free (buf);
586 errcode = ENOSYS;
587 result = -1;
588 goto FinishSyscall;
589 }
590
591 if ((*sc->write_mem) (cb, sc, addr, buf, buflen) != buflen)
592 {
593 free (buf);
594 errcode = EINVAL;
595 result = -1;
596 goto FinishSyscall;
597 }
598
599 free (buf);
600 }
601 break;
602
603 case CB_SYS_pipe :
604 {
605 int p[2];
606 char *target_p = xcalloc (1, cb->target_sizeof_int * 2);
607
608 result = (*cb->pipe) (cb, p);
609 if (result != 0)
610 goto ErrorFinish;
611
612 cb_store_target_endian (cb, target_p, cb->target_sizeof_int, p[0]);
613 cb_store_target_endian (cb, target_p + cb->target_sizeof_int,
614 cb->target_sizeof_int, p[1]);
615 if ((*sc->write_mem) (cb, sc, sc->arg1, target_p,
616 cb->target_sizeof_int * 2)
617 != cb->target_sizeof_int * 2)
618 {
619 /* Close the pipe fd:s. */
620 (*cb->close) (cb, p[0]);
621 (*cb->close) (cb, p[1]);
622 errcode = EFAULT;
623 result = -1;
624 }
625
626 free (target_p);
627 }
628 break;
629
630 case CB_SYS_getpid:
631 /* POSIX says getpid always succeeds. */
632 result = (*cb->getpid) (cb);
633 break;
634
635 case CB_SYS_kill:
636 /* If killing self, leave it to the caller to process so it can send the
637 signal to the engine. */
638 if (sc->arg1 == (*cb->getpid) (cb))
639 {
640 result = -1;
641 errcode = ENOSYS;
642 }
643 else
644 {
645 int signum = cb_target_to_host_signal (cb, sc->arg2);
646
647 result = (*cb->kill) (cb, sc->arg1, signum);
648 cb->last_errno = errno;
649 goto ErrorFinish;
650 }
651 break;
652
653 case CB_SYS_time :
654 {
655 /* FIXME: May wish to change CB_SYS_time to something else.
656 We might also want gettimeofday or times, but if system calls
657 can be built on others, we can keep the number we have to support
658 here down. */
659 time_t t = (*cb->time) (cb);
660 result = t;
661 /* It is up to target code to process the argument to time(). */
662 }
663 break;
664
665 case CB_SYS_chdir :
666 case CB_SYS_chmod :
667 case CB_SYS_utime :
668 /* fall through for now */
669
670 default :
671 result = -1;
672 errcode = ENOSYS;
673 break;
674 }
675
676 FinishSyscall:
677 sc->result = result;
678 if (errcode == 0)
679 sc->errcode = 0;
680 else
681 sc->errcode = cb_host_to_target_errno (cb, errcode);
682 return CB_RC_OK;
683
684 ErrorFinish:
685 sc->result = result;
686 sc->errcode = (*cb->get_errno) (cb);
687 return CB_RC_OK;
688 }