1 /* Remote target system call support.
2 Copyright 1997-2024 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 int argc
, envc
, len
, ret
;
217 char **argv
= cb
->argv
;
218 char **envp
= cb
->envp
;
225 for ( ; argv
[argc
]; ++argc
)
227 len
= strlen (argv
[argc
]) + 1;
228 if (written
+ len
> bufsize
)
231 ret
= (*sc
->write_mem
) (cb
, sc
, tbuf
+ written
, argv
[argc
],
239 /* Double NUL bytes indicates end of strings. */
240 if (written
>= bufsize
)
242 if ((*sc
->write_mem
) (cb
, sc
, tbuf
+ written
, "", 1) != 1)
249 for ( ; envp
[envc
]; ++envc
)
251 len
= strlen (envp
[envc
]) + 1;
252 if (written
+ len
> bufsize
)
255 ret
= (*sc
->write_mem
) (cb
, sc
, tbuf
+ written
, envp
[envc
],
262 /* Double NUL bytes indicates end of strings. */
263 if (written
>= bufsize
)
265 if ((*sc
->write_mem
) (cb
, sc
, tbuf
+ written
, "", 1) != 1)
282 /* Caller must catch and handle; see sim_syscall as an example. */
289 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
295 result
= (*cb
->open
) (cb
, path
, sc
->arg2
/*, sc->arg3*/);
303 result
= (*cb
->close
) (cb
, sc
->arg1
);
310 /* ??? Perfect handling of error conditions may require only one
311 call to cb->read. One can't assume all the data is
312 contiguously stored in host memory so that would require
313 malloc'ing/free'ing the space. Maybe later. */
314 char buf
[FILE_XFR_SIZE
];
316 TADDR addr
= sc
->arg2
;
317 size_t count
= sc
->arg3
;
318 size_t bytes_read
= 0;
323 if (cb_is_stdin (cb
, fd
))
324 result
= (int) (*cb
->read_stdin
) (cb
, buf
,
325 (count
< FILE_XFR_SIZE
326 ? count
: FILE_XFR_SIZE
));
328 result
= (int) (*cb
->read
) (cb
, fd
, buf
,
329 (count
< FILE_XFR_SIZE
330 ? count
: FILE_XFR_SIZE
));
333 if (result
== 0) /* EOF */
335 bytes_written
= (*sc
->write_mem
) (cb
, sc
, addr
, buf
, result
);
336 if (bytes_written
!= result
)
342 bytes_read
+= result
;
345 /* If this is a short read, don't go back for more */
346 if (result
!= FILE_XFR_SIZE
)
355 /* ??? Perfect handling of error conditions may require only one
356 call to cb->write. One can't assume all the data is
357 contiguously stored in host memory so that would require
358 malloc'ing/free'ing the space. Maybe later. */
359 char buf
[FILE_XFR_SIZE
];
361 TADDR addr
= sc
->arg2
;
362 size_t count
= sc
->arg3
;
364 size_t bytes_written
= 0;
368 int bytes_to_read
= count
< FILE_XFR_SIZE
? count
: FILE_XFR_SIZE
;
369 bytes_read
= (*sc
->read_mem
) (cb
, sc
, addr
, buf
, bytes_to_read
);
370 if (bytes_read
!= bytes_to_read
)
376 if (cb_is_stdout (cb
, fd
))
378 result
= (int) (*cb
->write_stdout
) (cb
, buf
, bytes_read
);
379 (*cb
->flush_stdout
) (cb
);
381 else if (cb_is_stderr (cb
, fd
))
383 result
= (int) (*cb
->write_stderr
) (cb
, buf
, bytes_read
);
384 (*cb
->flush_stderr
) (cb
);
387 result
= (int) (*cb
->write
) (cb
, fd
, buf
, bytes_read
);
390 bytes_written
+= result
;
394 result
= bytes_written
;
401 unsigned long offset
= sc
->arg2
;
402 int whence
= sc
->arg3
;
404 result
= (*cb
->lseek
) (cb
, fd
, offset
, whence
);
414 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
420 result
= (*cb
->unlink
) (cb
, path
);
427 case CB_SYS_truncate
:
432 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
439 result
= (*cb
->truncate
) (cb
, path
, len
);
446 case CB_SYS_ftruncate
:
451 result
= (*cb
->ftruncate
) (cb
, fd
, len
);
461 errcode
= get_path (cb
, sc
, sc
->arg1
, &path1
);
468 errcode
= get_path (cb
, sc
, sc
->arg2
, &path2
);
476 result
= (*cb
->rename
) (cb
, path1
, path2
);
489 TADDR addr
= sc
->arg2
;
491 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
497 result
= (*cb
->to_stat
) (cb
, path
, &statbuf
);
501 buflen
= cb_host_to_target_stat (cb
, NULL
, NULL
);
502 buf
= xmalloc (buflen
);
503 if (cb_host_to_target_stat (cb
, &statbuf
, buf
) != buflen
)
505 /* The translation failed. This is due to an internal
506 host program error, not the target's fault. */
512 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != buflen
)
528 TADDR addr
= sc
->arg2
;
530 result
= (*cb
->to_fstat
) (cb
, sc
->arg1
, &statbuf
);
533 buflen
= cb_host_to_target_stat (cb
, NULL
, NULL
);
534 buf
= xmalloc (buflen
);
535 if (cb_host_to_target_stat (cb
, &statbuf
, buf
) != buflen
)
537 /* The translation failed. This is due to an internal
538 host program error, not the target's fault. */
544 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != buflen
)
560 TADDR addr
= sc
->arg2
;
562 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
568 result
= (*cb
->to_lstat
) (cb
, path
, &statbuf
);
573 buflen
= cb_host_to_target_stat (cb
, NULL
, NULL
);
574 buf
= xmalloc (buflen
);
575 if (cb_host_to_target_stat (cb
, &statbuf
, buf
) != buflen
)
577 /* The translation failed. This is due to an internal
578 host program error, not the target's fault.
579 Unfortunately, it's hard to test this case, so there's no
580 test-case for this execution path. */
587 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != buflen
)
602 char *target_p
= xcalloc (1, cb
->target_sizeof_int
* 2);
604 result
= (*cb
->pipe
) (cb
, p
);
608 cb_store_target_endian (cb
, target_p
, cb
->target_sizeof_int
, p
[0]);
609 cb_store_target_endian (cb
, target_p
+ cb
->target_sizeof_int
,
610 cb
->target_sizeof_int
, p
[1]);
611 if ((*sc
->write_mem
) (cb
, sc
, sc
->arg1
, target_p
,
612 cb
->target_sizeof_int
* 2)
613 != cb
->target_sizeof_int
* 2)
615 /* Close the pipe fd:s. */
616 (*cb
->close
) (cb
, p
[0]);
617 (*cb
->close
) (cb
, p
[1]);
627 /* POSIX says getpid always succeeds. */
628 result
= (*cb
->getpid
) (cb
);
632 /* If killing self, leave it to the caller to process so it can send the
633 signal to the engine. */
634 if (sc
->arg1
== (*cb
->getpid
) (cb
))
641 int signum
= cb_target_to_host_signal (cb
, sc
->arg2
);
643 result
= (*cb
->kill
) (cb
, sc
->arg1
, signum
);
644 cb
->last_errno
= errno
;
651 /* FIXME: May wish to change CB_SYS_time to something else.
652 We might also want gettimeofday or times, but if system calls
653 can be built on others, we can keep the number we have to support
655 time_t t
= (*cb
->time
) (cb
);
657 /* It is up to target code to process the argument to time(). */
664 /* fall through for now */
677 sc
->errcode
= cb_host_to_target_errno (cb
, errcode
);
682 sc
->errcode
= (*cb
->get_errno
) (cb
);