1 /* Remote target system call support.
2 Copyright 1997-2023 Free Software Foundation, Inc.
3 Contributed by Cygnus Solutions.
5 This file is part of GDB.
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.
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.
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/>. */
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
26 /* This must come before any other includes. */
40 #include <sys/types.h>
43 #include "libiberty.h"
45 #include "sim/callback.h"
51 #define ENAMETOOLONG EINVAL
54 /* Maximum length of a path name. */
56 #define MAX_PATH_LEN 1024
59 /* When doing file read/writes, do this many bytes at a time. */
60 #define FILE_XFR_SIZE 4096
62 /* FIXME: for now, need to consider target word size. */
64 #define TADDR unsigned long
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
= "";
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. */
74 cb_get_string (host_callback
*cb
, CB_SYSCALL
*sc
, char *buf
, int buflen
,
79 for (p
= buf
, pend
= buf
+ buflen
; p
< pend
; ++p
, ++addr
)
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);
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. */
104 get_path (host_callback
*cb
, CB_SYSCALL
*sc
, TADDR addr
, char **bufp
)
106 char *buf
= xmalloc (MAX_PATH_LEN
);
108 int sysroot_len
= strlen (simulator_sysroot
);
110 result
= cb_get_string (cb
, sc
, buf
, MAX_PATH_LEN
- sysroot_len
, addr
);
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
== '/')
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
);
134 /* Perform a system call on behalf of the target. */
137 cb_syscall (host_callback
*cb
, CB_SYSCALL
*sc
)
139 TWORD result
= 0, errcode
= 0;
141 if (sc
->magic
!= CB_SYSCALL_MAGIC
)
144 switch (cb_target_to_host_syscall (cb
, sc
->func
))
147 result
= countargv (cb
->argv
);
152 if (sc
->arg1
>= 0 && sc
->arg1
< countargv (cb
->argv
))
153 result
= strlen (cb
->argv
[sc
->arg1
]);
164 if (sc
->arg1
>= 0 && sc
->arg1
< countargv (cb
->argv
))
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);
170 if (written
== len
+ 1)
186 case CB_SYS_argvlen
:
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
;
198 for ( ; argv
[argc
]; ++argc
)
199 arglen
+= strlen (argv
[argc
]) + 1;
204 for ( ; envp
[envc
]; ++envc
)
205 envlen
+= strlen (envp
[envc
]) + 1;
207 result
= arglen
+ 1 + envlen
+ 1;
213 /* Pointer to target's buffer. */
214 TADDR tbuf
= sc
->arg1
;
216 int bufsize
= sc
->arg2
;
218 /* Q is the target address of where all the strings go. */
220 int i
, argc
, envc
, len
, ret
;
221 char **argv
= cb
->argv
;
222 char **envp
= cb
->envp
;
229 for ( ; argv
[argc
]; ++argc
)
231 len
= strlen (argv
[argc
]) + 1;
232 if (written
+ len
> bufsize
)
235 ret
= (*sc
->write_mem
) (cb
, sc
, tbuf
+ written
, argv
[argc
],
243 /* Double NUL bytes indicates end of strings. */
244 if (written
>= bufsize
)
246 if ((*sc
->write_mem
) (cb
, sc
, tbuf
+ written
, "", 1) != 1)
253 for ( ; envp
[envc
]; ++envc
)
255 len
= strlen (envp
[envc
]) + 1;
256 if (written
+ len
> bufsize
)
259 ret
= (*sc
->write_mem
) (cb
, sc
, tbuf
+ written
, envp
[envc
],
266 /* Double NUL bytes indicates end of strings. */
267 if (written
>= bufsize
)
269 if ((*sc
->write_mem
) (cb
, sc
, tbuf
+ written
, "", 1) != 1)
286 /* Caller must catch and handle; see sim_syscall as an example. */
293 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
299 result
= (*cb
->open
) (cb
, path
, sc
->arg2
/*, sc->arg3*/);
307 result
= (*cb
->close
) (cb
, sc
->arg1
);
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
];
320 TADDR addr
= sc
->arg2
;
321 size_t count
= sc
->arg3
;
322 size_t bytes_read
= 0;
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
));
332 result
= (int) (*cb
->read
) (cb
, fd
, buf
,
333 (count
< FILE_XFR_SIZE
334 ? count
: FILE_XFR_SIZE
));
337 if (result
== 0) /* EOF */
339 bytes_written
= (*sc
->write_mem
) (cb
, sc
, addr
, buf
, result
);
340 if (bytes_written
!= result
)
346 bytes_read
+= result
;
349 /* If this is a short read, don't go back for more */
350 if (result
!= FILE_XFR_SIZE
)
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
];
365 TADDR addr
= sc
->arg2
;
366 size_t count
= sc
->arg3
;
368 size_t bytes_written
= 0;
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
)
380 if (cb_is_stdout (cb
, fd
))
382 result
= (int) (*cb
->write_stdout
) (cb
, buf
, bytes_read
);
383 (*cb
->flush_stdout
) (cb
);
385 else if (cb_is_stderr (cb
, fd
))
387 result
= (int) (*cb
->write_stderr
) (cb
, buf
, bytes_read
);
388 (*cb
->flush_stderr
) (cb
);
391 result
= (int) (*cb
->write
) (cb
, fd
, buf
, bytes_read
);
394 bytes_written
+= result
;
398 result
= bytes_written
;
405 unsigned long offset
= sc
->arg2
;
406 int whence
= sc
->arg3
;
408 result
= (*cb
->lseek
) (cb
, fd
, offset
, whence
);
418 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
424 result
= (*cb
->unlink
) (cb
, path
);
431 case CB_SYS_truncate
:
436 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
443 result
= (*cb
->truncate
) (cb
, path
, len
);
450 case CB_SYS_ftruncate
:
455 result
= (*cb
->ftruncate
) (cb
, fd
, len
);
465 errcode
= get_path (cb
, sc
, sc
->arg1
, &path1
);
472 errcode
= get_path (cb
, sc
, sc
->arg2
, &path2
);
480 result
= (*cb
->rename
) (cb
, path1
, path2
);
493 TADDR addr
= sc
->arg2
;
495 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
501 result
= (*cb
->to_stat
) (cb
, path
, &statbuf
);
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
)
509 /* The translation failed. This is due to an internal
510 host program error, not the target's fault. */
516 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != buflen
)
532 TADDR addr
= sc
->arg2
;
534 result
= (*cb
->to_fstat
) (cb
, sc
->arg1
, &statbuf
);
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
)
541 /* The translation failed. This is due to an internal
542 host program error, not the target's fault. */
548 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != buflen
)
564 TADDR addr
= sc
->arg2
;
566 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
572 result
= (*cb
->to_lstat
) (cb
, path
, &statbuf
);
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
)
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. */
591 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != buflen
)
606 char *target_p
= xcalloc (1, cb
->target_sizeof_int
* 2);
608 result
= (*cb
->pipe
) (cb
, p
);
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)
619 /* Close the pipe fd:s. */
620 (*cb
->close
) (cb
, p
[0]);
621 (*cb
->close
) (cb
, p
[1]);
631 /* POSIX says getpid always succeeds. */
632 result
= (*cb
->getpid
) (cb
);
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
))
645 int signum
= cb_target_to_host_signal (cb
, sc
->arg2
);
647 result
= (*cb
->kill
) (cb
, sc
->arg1
, signum
);
648 cb
->last_errno
= errno
;
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
659 time_t t
= (*cb
->time
) (cb
);
661 /* It is up to target code to process the argument to time(). */
668 /* fall through for now */
681 sc
->errcode
= cb_host_to_target_errno (cb
, errcode
);
686 sc
->errcode
= (*cb
->get_errno
) (cb
);