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