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. */
38 #include <sys/types.h>
41 #include "libiberty.h"
43 #include "sim/callback.h"
49 #define ENAMETOOLONG EINVAL
52 /* Maximum length of a path name. */
54 #define MAX_PATH_LEN 1024
57 /* When doing file read/writes, do this many bytes at a time. */
58 #define FILE_XFR_SIZE 4096
60 /* FIXME: for now, need to consider target word size. */
62 #define TADDR unsigned long
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
= "";
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. */
72 cb_get_string (host_callback
*cb
, CB_SYSCALL
*sc
, char *buf
, int buflen
,
77 for (p
= buf
, pend
= buf
+ buflen
; p
< pend
; ++p
, ++addr
)
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);
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. */
102 get_path (host_callback
*cb
, CB_SYSCALL
*sc
, TADDR addr
, char **bufp
)
104 char *buf
= xmalloc (MAX_PATH_LEN
);
106 int sysroot_len
= strlen (simulator_sysroot
);
108 result
= cb_get_string (cb
, sc
, buf
, MAX_PATH_LEN
- sysroot_len
, addr
);
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
== '/')
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
);
132 /* Perform a system call on behalf of the target. */
135 cb_syscall (host_callback
*cb
, CB_SYSCALL
*sc
)
137 TWORD result
= 0, errcode
= 0;
139 if (sc
->magic
!= CB_SYSCALL_MAGIC
)
142 switch (cb_target_to_host_syscall (cb
, sc
->func
))
145 result
= countargv (cb
->argv
);
150 if (sc
->arg1
>= 0 && sc
->arg1
< countargv (cb
->argv
))
151 result
= strlen (cb
->argv
[sc
->arg1
]);
162 if (sc
->arg1
>= 0 && sc
->arg1
< countargv (cb
->argv
))
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);
168 if (written
== len
+ 1)
184 case CB_SYS_argvlen
:
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
;
196 for ( ; argv
[argc
]; ++argc
)
197 arglen
+= strlen (argv
[argc
]) + 1;
202 for ( ; envp
[envc
]; ++envc
)
203 envlen
+= strlen (envp
[envc
]) + 1;
205 result
= arglen
+ 1 + envlen
+ 1;
211 /* Pointer to target's buffer. */
212 TADDR tbuf
= sc
->arg1
;
214 int bufsize
= sc
->arg2
;
216 /* Q is the target address of where all the strings go. */
218 int i
, argc
, envc
, len
, ret
;
219 char **argv
= cb
->argv
;
220 char **envp
= cb
->envp
;
227 for ( ; argv
[argc
]; ++argc
)
229 len
= strlen (argv
[argc
]) + 1;
230 if (written
+ len
> bufsize
)
233 ret
= (*sc
->write_mem
) (cb
, sc
, tbuf
+ written
, argv
[argc
],
241 /* Double NUL bytes indicates end of strings. */
242 if (written
>= bufsize
)
244 if ((*sc
->write_mem
) (cb
, sc
, tbuf
+ written
, "", 1) != 1)
251 for ( ; envp
[envc
]; ++envc
)
253 len
= strlen (envp
[envc
]) + 1;
254 if (written
+ len
> bufsize
)
257 ret
= (*sc
->write_mem
) (cb
, sc
, tbuf
+ written
, envp
[envc
],
264 /* Double NUL bytes indicates end of strings. */
265 if (written
>= bufsize
)
267 if ((*sc
->write_mem
) (cb
, sc
, tbuf
+ written
, "", 1) != 1)
284 /* Caller must catch and handle; see sim_syscall as an example. */
291 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
297 result
= (*cb
->open
) (cb
, path
, sc
->arg2
/*, sc->arg3*/);
305 result
= (*cb
->close
) (cb
, sc
->arg1
);
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
];
318 TADDR addr
= sc
->arg2
;
319 size_t count
= sc
->arg3
;
320 size_t bytes_read
= 0;
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
));
330 result
= (int) (*cb
->read
) (cb
, fd
, buf
,
331 (count
< FILE_XFR_SIZE
332 ? count
: FILE_XFR_SIZE
));
335 if (result
== 0) /* EOF */
337 bytes_written
= (*sc
->write_mem
) (cb
, sc
, addr
, buf
, result
);
338 if (bytes_written
!= result
)
344 bytes_read
+= result
;
347 /* If this is a short read, don't go back for more */
348 if (result
!= FILE_XFR_SIZE
)
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
];
363 TADDR addr
= sc
->arg2
;
364 size_t count
= sc
->arg3
;
366 size_t bytes_written
= 0;
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
)
378 if (cb_is_stdout (cb
, fd
))
380 result
= (int) (*cb
->write_stdout
) (cb
, buf
, bytes_read
);
381 (*cb
->flush_stdout
) (cb
);
383 else if (cb_is_stderr (cb
, fd
))
385 result
= (int) (*cb
->write_stderr
) (cb
, buf
, bytes_read
);
386 (*cb
->flush_stderr
) (cb
);
389 result
= (int) (*cb
->write
) (cb
, fd
, buf
, bytes_read
);
392 bytes_written
+= result
;
396 result
= bytes_written
;
403 unsigned long offset
= sc
->arg2
;
404 int whence
= sc
->arg3
;
406 result
= (*cb
->lseek
) (cb
, fd
, offset
, whence
);
416 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
422 result
= (*cb
->unlink
) (cb
, path
);
429 case CB_SYS_truncate
:
434 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
441 result
= (*cb
->truncate
) (cb
, path
, len
);
448 case CB_SYS_ftruncate
:
453 result
= (*cb
->ftruncate
) (cb
, fd
, len
);
463 errcode
= get_path (cb
, sc
, sc
->arg1
, &path1
);
470 errcode
= get_path (cb
, sc
, sc
->arg2
, &path2
);
478 result
= (*cb
->rename
) (cb
, path1
, path2
);
491 TADDR addr
= sc
->arg2
;
493 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
499 result
= (*cb
->to_stat
) (cb
, path
, &statbuf
);
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
)
507 /* The translation failed. This is due to an internal
508 host program error, not the target's fault. */
514 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != buflen
)
530 TADDR addr
= sc
->arg2
;
532 result
= (*cb
->to_fstat
) (cb
, sc
->arg1
, &statbuf
);
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
)
539 /* The translation failed. This is due to an internal
540 host program error, not the target's fault. */
546 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != buflen
)
562 TADDR addr
= sc
->arg2
;
564 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
570 result
= (*cb
->to_lstat
) (cb
, path
, &statbuf
);
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
)
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. */
589 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != buflen
)
604 char *target_p
= xcalloc (1, cb
->target_sizeof_int
* 2);
606 result
= (*cb
->pipe
) (cb
, p
);
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)
617 /* Close the pipe fd:s. */
618 (*cb
->close
) (cb
, p
[0]);
619 (*cb
->close
) (cb
, p
[1]);
629 /* POSIX says getpid always succeeds. */
630 result
= (*cb
->getpid
) (cb
);
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
))
643 int signum
= cb_target_to_host_signal (cb
, sc
->arg2
);
645 result
= (*cb
->kill
) (cb
, sc
->arg1
, signum
);
646 cb
->last_errno
= errno
;
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
657 time_t t
= (*cb
->time
) (cb
);
659 /* It is up to target code to process the argument to time(). */
666 /* fall through for now */
679 sc
->errcode
= cb_host_to_target_errno (cb
, errcode
);
684 sc
->errcode
= (*cb
->get_errno
) (cb
);