1 /* Remote target system call support.
2 Copyright 1997-2021 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. */
30 #include "libiberty.h"
41 #include <sys/types.h>
43 #include "sim/callback.h"
44 #include "targ-vals.h"
50 #define ENAMETOOLONG EINVAL
53 /* Maximum length of a path name. */
55 #define MAX_PATH_LEN 1024
58 /* When doing file read/writes, do this many bytes at a time. */
59 #define FILE_XFR_SIZE 4096
61 /* FIXME: for now, need to consider target word size. */
63 #define TADDR unsigned long
65 /* Path to be prepended to syscalls with absolute paths, and to be
66 chdir:ed at startup, if not empty. */
67 char *simulator_sysroot = "";
69 /* Utility of cb_syscall to fetch a path name or other string from the target.
70 The result is 0 for success or a host errno value. */
73 cb_get_string (host_callback *cb, CB_SYSCALL *sc, char *buf, int buflen,
78 for (p = buf, pend = buf + buflen; p < pend; ++p, ++addr)
80 /* No, it isn't expected that this would cause one transaction with
81 the remote target for each byte. The target could send the
82 path name along with the syscall request, and cache the file
83 name somewhere (or otherwise tweak this as desired). */
84 unsigned int count = (*sc->read_mem) (cb, sc, addr, p, 1);
96 /* Utility of cb_syscall to fetch a path name.
97 The buffer is malloc'd and the address is stored in BUFP.
98 The result is that of get_string, but prepended with
99 simulator_sysroot if the string starts with '/'.
100 If an error occurs, no buffer is left malloc'd. */
103 get_path (host_callback *cb, CB_SYSCALL *sc, TADDR addr, char **bufp)
105 char *buf = xmalloc (MAX_PATH_LEN);
107 int sysroot_len = strlen (simulator_sysroot);
109 result = cb_get_string (cb, sc, buf, MAX_PATH_LEN - sysroot_len, addr);
112 /* Prepend absolute paths with simulator_sysroot. Relative paths
113 are supposed to be relative to a chdir within that path, but at
114 this point unknown where. */
115 if (simulator_sysroot[0] != '\0' && *buf == '/')
117 /* Considering expected rareness of syscalls with absolute
118 file paths (compared to relative file paths and insn
119 execution), it does not seem worthwhile to rearrange things
120 to get rid of the string moves here; we'd need at least an
121 extra call to check the initial '/' in the path. */
122 memmove (buf + sysroot_len, buf, sysroot_len);
123 memcpy (buf, simulator_sysroot, sysroot_len);
133 /* Perform a system call on behalf of the target. */
136 cb_syscall (host_callback *cb, CB_SYSCALL *sc)
138 TWORD result = 0, errcode = 0;
140 if (sc->magic != CB_SYSCALL_MAGIC)
143 switch (cb_target_to_host_syscall (cb, sc->func))
145 #if 0 /* FIXME: wip */
146 case CB_SYS_argvlen :
148 /* Compute how much space is required to store the argv,envp
149 strings so that the program can allocate the space and then
150 call SYS_argv to fetch the values. */
151 int addr_size = cb->addr_size;
152 int argc,envc,arglen,envlen;
153 const char **argv = cb->init_argv;
154 const char **envp = cb->init_envp;
159 for ( ; argv[argc]; ++argc)
160 arglen += strlen (argv[argc]) + 1;
165 for ( ; envp[envc]; ++envc)
166 envlen += strlen (envp[envc]) + 1;
168 result = arglen + envlen;
174 /* Pointer to target's buffer. */
175 TADDR tbuf = sc->arg1;
177 int bufsize = sc->arg2;
178 /* Q is the target address of where all the strings go. */
180 int word_size = cb->word_size;
182 const char **argv = cb->init_argv;
183 const char **envp = cb->init_envp;
188 for ( ; argv[argc]; ++argc)
190 int len = strlen (argv[argc]);
191 int written = (*sc->write_mem) (cb, sc, tbuf, argv[argc], len + 1);
201 if ((*sc->write_mem) (cb, sc, tbuf, "", 1) != 1)
211 for ( ; envp[envc]; ++envc)
213 int len = strlen (envp[envc]);
214 int written = (*sc->write_mem) (cb, sc, tbuf, envp[envc], len + 1);
224 if ((*sc->write_mem) (cb, sc, tbuf, "", 1) != 1)
237 /* Caller must catch and handle; see sim_syscall as an example. */
244 errcode = get_path (cb, sc, sc->arg1, &path);
250 result = (*cb->open) (cb, path, sc->arg2 /*, sc->arg3*/);
258 result = (*cb->close) (cb, sc->arg1);
265 /* ??? Perfect handling of error conditions may require only one
266 call to cb->read. One can't assume all the data is
267 contiguously stored in host memory so that would require
268 malloc'ing/free'ing the space. Maybe later. */
269 char buf[FILE_XFR_SIZE];
271 TADDR addr = sc->arg2;
272 size_t count = sc->arg3;
273 size_t bytes_read = 0;
278 if (cb_is_stdin (cb, fd))
279 result = (int) (*cb->read_stdin) (cb, buf,
280 (count < FILE_XFR_SIZE
281 ? count : FILE_XFR_SIZE));
283 result = (int) (*cb->read) (cb, fd, buf,
284 (count < FILE_XFR_SIZE
285 ? count : FILE_XFR_SIZE));
288 if (result == 0) /* EOF */
290 bytes_written = (*sc->write_mem) (cb, sc, addr, buf, result);
291 if (bytes_written != result)
297 bytes_read += result;
300 /* If this is a short read, don't go back for more */
301 if (result != FILE_XFR_SIZE)
310 /* ??? Perfect handling of error conditions may require only one
311 call to cb->write. 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;
319 size_t bytes_written = 0;
323 int bytes_to_read = count < FILE_XFR_SIZE ? count : FILE_XFR_SIZE;
324 bytes_read = (*sc->read_mem) (cb, sc, addr, buf, bytes_to_read);
325 if (bytes_read != bytes_to_read)
331 if (cb_is_stdout (cb, fd))
333 result = (int) (*cb->write_stdout) (cb, buf, bytes_read);
334 (*cb->flush_stdout) (cb);
336 else if (cb_is_stderr (cb, fd))
338 result = (int) (*cb->write_stderr) (cb, buf, bytes_read);
339 (*cb->flush_stderr) (cb);
342 result = (int) (*cb->write) (cb, fd, buf, bytes_read);
345 bytes_written += result;
349 result = bytes_written;
356 unsigned long offset = sc->arg2;
357 int whence = sc->arg3;
359 result = (*cb->lseek) (cb, fd, offset, whence);
369 errcode = get_path (cb, sc, sc->arg1, &path);
375 result = (*cb->unlink) (cb, path);
382 case CB_SYS_truncate :
387 errcode = get_path (cb, sc, sc->arg1, &path);
394 result = (*cb->truncate) (cb, path, len);
401 case CB_SYS_ftruncate :
406 result = (*cb->ftruncate) (cb, fd, len);
416 errcode = get_path (cb, sc, sc->arg1, &path1);
423 errcode = get_path (cb, sc, sc->arg2, &path2);
431 result = (*cb->rename) (cb, path1, path2);
444 TADDR addr = sc->arg2;
446 errcode = get_path (cb, sc, sc->arg1, &path);
452 result = (*cb->to_stat) (cb, path, &statbuf);
456 buflen = cb_host_to_target_stat (cb, NULL, NULL);
457 buf = xmalloc (buflen);
458 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
460 /* The translation failed. This is due to an internal
461 host program error, not the target's fault. */
467 if ((*sc->write_mem) (cb, sc, addr, buf, buflen) != buflen)
483 TADDR addr = sc->arg2;
485 result = (*cb->to_fstat) (cb, sc->arg1, &statbuf);
488 buflen = cb_host_to_target_stat (cb, NULL, NULL);
489 buf = xmalloc (buflen);
490 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
492 /* The translation failed. This is due to an internal
493 host program error, not the target's fault. */
499 if ((*sc->write_mem) (cb, sc, addr, buf, buflen) != buflen)
515 TADDR addr = sc->arg2;
517 errcode = get_path (cb, sc, sc->arg1, &path);
523 result = (*cb->to_lstat) (cb, path, &statbuf);
528 buflen = cb_host_to_target_stat (cb, NULL, NULL);
529 buf = xmalloc (buflen);
530 if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
532 /* The translation failed. This is due to an internal
533 host program error, not the target's fault.
534 Unfortunately, it's hard to test this case, so there's no
535 test-case for this execution path. */
542 if ((*sc->write_mem) (cb, sc, addr, buf, buflen) != buflen)
557 char *target_p = xcalloc (1, cb->target_sizeof_int * 2);
559 result = (*cb->pipe) (cb, p);
563 cb_store_target_endian (cb, target_p, cb->target_sizeof_int, p[0]);
564 cb_store_target_endian (cb, target_p + cb->target_sizeof_int,
565 cb->target_sizeof_int, p[1]);
566 if ((*sc->write_mem) (cb, sc, sc->arg1, target_p,
567 cb->target_sizeof_int * 2)
568 != cb->target_sizeof_int * 2)
570 /* Close the pipe fd:s. */
571 (*cb->close) (cb, p[0]);
572 (*cb->close) (cb, p[1]);
587 /* FIXME: May wish to change CB_SYS_time to something else.
588 We might also want gettimeofday or times, but if system calls
589 can be built on others, we can keep the number we have to support
591 time_t t = (*cb->time) (cb);
593 /* It is up to target code to process the argument to time(). */
600 /* fall through for now */
613 sc->errcode = cb_host_to_target_errno (cb, errcode);
618 sc->errcode = (*cb->get_errno) (cb);