1 /* Remote target system call support.
2 Copyright 1997-2019 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
30 #include "libiberty.h"
38 #elif defined (HAVE_STRINGS_H)
47 #include <sys/types.h>
49 #include "gdb/callback.h"
50 #include "targ-vals.h"
56 #define ENAMETOOLONG EINVAL
59 /* Maximum length of a path name. */
61 #define MAX_PATH_LEN 1024
64 /* When doing file read/writes, do this many bytes at a time. */
65 #define FILE_XFR_SIZE 4096
67 /* FIXME: for now, need to consider target word size. */
69 #define TADDR unsigned long
71 /* Path to be prepended to syscalls with absolute paths, and to be
72 chdir:ed at startup, if not empty. */
73 char *simulator_sysroot
= "";
75 /* Utility of cb_syscall to fetch a path name or other string from the target.
76 The result is 0 for success or a host errno value. */
79 cb_get_string (host_callback
*cb
, CB_SYSCALL
*sc
, char *buf
, int buflen
,
84 for (p
= buf
, pend
= buf
+ buflen
; p
< pend
; ++p
, ++addr
)
86 /* No, it isn't expected that this would cause one transaction with
87 the remote target for each byte. The target could send the
88 path name along with the syscall request, and cache the file
89 name somewhere (or otherwise tweak this as desired). */
90 unsigned int count
= (*sc
->read_mem
) (cb
, sc
, addr
, p
, 1);
102 /* Utility of cb_syscall to fetch a path name.
103 The buffer is malloc'd and the address is stored in BUFP.
104 The result is that of get_string, but prepended with
105 simulator_sysroot if the string starts with '/'.
106 If an error occurs, no buffer is left malloc'd. */
109 get_path (host_callback
*cb
, CB_SYSCALL
*sc
, TADDR addr
, char **bufp
)
111 char *buf
= xmalloc (MAX_PATH_LEN
);
113 int sysroot_len
= strlen (simulator_sysroot
);
115 result
= cb_get_string (cb
, sc
, buf
, MAX_PATH_LEN
- sysroot_len
, addr
);
118 /* Prepend absolute paths with simulator_sysroot. Relative paths
119 are supposed to be relative to a chdir within that path, but at
120 this point unknown where. */
121 if (simulator_sysroot
[0] != '\0' && *buf
== '/')
123 /* Considering expected rareness of syscalls with absolute
124 file paths (compared to relative file paths and insn
125 execution), it does not seem worthwhile to rearrange things
126 to get rid of the string moves here; we'd need at least an
127 extra call to check the initial '/' in the path. */
128 memmove (buf
+ sysroot_len
, buf
, sysroot_len
);
129 memcpy (buf
, simulator_sysroot
, sysroot_len
);
139 /* Perform a system call on behalf of the target. */
142 cb_syscall (host_callback
*cb
, CB_SYSCALL
*sc
)
144 TWORD result
= 0, errcode
= 0;
146 if (sc
->magic
!= CB_SYSCALL_MAGIC
)
149 switch (cb_target_to_host_syscall (cb
, sc
->func
))
151 #if 0 /* FIXME: wip */
152 case CB_SYS_argvlen
:
154 /* Compute how much space is required to store the argv,envp
155 strings so that the program can allocate the space and then
156 call SYS_argv to fetch the values. */
157 int addr_size
= cb
->addr_size
;
158 int argc
,envc
,arglen
,envlen
;
159 const char **argv
= cb
->init_argv
;
160 const char **envp
= cb
->init_envp
;
165 for ( ; argv
[argc
]; ++argc
)
166 arglen
+= strlen (argv
[argc
]) + 1;
171 for ( ; envp
[envc
]; ++envc
)
172 envlen
+= strlen (envp
[envc
]) + 1;
174 result
= arglen
+ envlen
;
180 /* Pointer to target's buffer. */
181 TADDR tbuf
= sc
->arg1
;
183 int bufsize
= sc
->arg2
;
184 /* Q is the target address of where all the strings go. */
186 int word_size
= cb
->word_size
;
188 const char **argv
= cb
->init_argv
;
189 const char **envp
= cb
->init_envp
;
194 for ( ; argv
[argc
]; ++argc
)
196 int len
= strlen (argv
[argc
]);
197 int written
= (*sc
->write_mem
) (cb
, sc
, tbuf
, argv
[argc
], len
+ 1);
207 if ((*sc
->write_mem
) (cb
, sc
, tbuf
, "", 1) != 1)
217 for ( ; envp
[envc
]; ++envc
)
219 int len
= strlen (envp
[envc
]);
220 int written
= (*sc
->write_mem
) (cb
, sc
, tbuf
, envp
[envc
], len
+ 1);
230 if ((*sc
->write_mem
) (cb
, sc
, tbuf
, "", 1) != 1)
243 /* Caller must catch and handle; see sim_syscall as an example. */
250 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
256 result
= (*cb
->open
) (cb
, path
, sc
->arg2
/*, sc->arg3*/);
264 result
= (*cb
->close
) (cb
, sc
->arg1
);
271 /* ??? Perfect handling of error conditions may require only one
272 call to cb->read. One can't assume all the data is
273 contiguously stored in host memory so that would require
274 malloc'ing/free'ing the space. Maybe later. */
275 char buf
[FILE_XFR_SIZE
];
277 TADDR addr
= sc
->arg2
;
278 size_t count
= sc
->arg3
;
279 size_t bytes_read
= 0;
284 if (cb_is_stdin (cb
, fd
))
285 result
= (int) (*cb
->read_stdin
) (cb
, buf
,
286 (count
< FILE_XFR_SIZE
287 ? count
: FILE_XFR_SIZE
));
289 result
= (int) (*cb
->read
) (cb
, fd
, buf
,
290 (count
< FILE_XFR_SIZE
291 ? count
: FILE_XFR_SIZE
));
294 if (result
== 0) /* EOF */
296 bytes_written
= (*sc
->write_mem
) (cb
, sc
, addr
, buf
, result
);
297 if (bytes_written
!= result
)
303 bytes_read
+= result
;
306 /* If this is a short read, don't go back for more */
307 if (result
!= FILE_XFR_SIZE
)
316 /* ??? Perfect handling of error conditions may require only one
317 call to cb->write. One can't assume all the data is
318 contiguously stored in host memory so that would require
319 malloc'ing/free'ing the space. Maybe later. */
320 char buf
[FILE_XFR_SIZE
];
322 TADDR addr
= sc
->arg2
;
323 size_t count
= sc
->arg3
;
325 size_t bytes_written
= 0;
329 int bytes_to_read
= count
< FILE_XFR_SIZE
? count
: FILE_XFR_SIZE
;
330 bytes_read
= (*sc
->read_mem
) (cb
, sc
, addr
, buf
, bytes_to_read
);
331 if (bytes_read
!= bytes_to_read
)
337 if (cb_is_stdout (cb
, fd
))
339 result
= (int) (*cb
->write_stdout
) (cb
, buf
, bytes_read
);
340 (*cb
->flush_stdout
) (cb
);
342 else if (cb_is_stderr (cb
, fd
))
344 result
= (int) (*cb
->write_stderr
) (cb
, buf
, bytes_read
);
345 (*cb
->flush_stderr
) (cb
);
348 result
= (int) (*cb
->write
) (cb
, fd
, buf
, bytes_read
);
351 bytes_written
+= result
;
355 result
= bytes_written
;
362 unsigned long offset
= sc
->arg2
;
363 int whence
= sc
->arg3
;
365 result
= (*cb
->lseek
) (cb
, fd
, offset
, whence
);
375 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
381 result
= (*cb
->unlink
) (cb
, path
);
388 case CB_SYS_truncate
:
393 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
400 result
= (*cb
->truncate
) (cb
, path
, len
);
407 case CB_SYS_ftruncate
:
412 result
= (*cb
->ftruncate
) (cb
, fd
, len
);
422 errcode
= get_path (cb
, sc
, sc
->arg1
, &path1
);
429 errcode
= get_path (cb
, sc
, sc
->arg2
, &path2
);
437 result
= (*cb
->rename
) (cb
, path1
, path2
);
450 TADDR addr
= sc
->arg2
;
452 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
458 result
= (*cb
->to_stat
) (cb
, path
, &statbuf
);
462 buflen
= cb_host_to_target_stat (cb
, NULL
, NULL
);
463 buf
= xmalloc (buflen
);
464 if (cb_host_to_target_stat (cb
, &statbuf
, buf
) != buflen
)
466 /* The translation failed. This is due to an internal
467 host program error, not the target's fault. */
473 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != buflen
)
489 TADDR addr
= sc
->arg2
;
491 result
= (*cb
->to_fstat
) (cb
, sc
->arg1
, &statbuf
);
494 buflen
= cb_host_to_target_stat (cb
, NULL
, NULL
);
495 buf
= xmalloc (buflen
);
496 if (cb_host_to_target_stat (cb
, &statbuf
, buf
) != buflen
)
498 /* The translation failed. This is due to an internal
499 host program error, not the target's fault. */
505 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != buflen
)
521 TADDR addr
= sc
->arg2
;
523 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
529 result
= (*cb
->to_lstat
) (cb
, path
, &statbuf
);
534 buflen
= cb_host_to_target_stat (cb
, NULL
, NULL
);
535 buf
= xmalloc (buflen
);
536 if (cb_host_to_target_stat (cb
, &statbuf
, buf
) != buflen
)
538 /* The translation failed. This is due to an internal
539 host program error, not the target's fault.
540 Unfortunately, it's hard to test this case, so there's no
541 test-case for this execution path. */
548 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != buflen
)
563 char *target_p
= xcalloc (1, cb
->target_sizeof_int
* 2);
565 result
= (*cb
->pipe
) (cb
, p
);
569 cb_store_target_endian (cb
, target_p
, cb
->target_sizeof_int
, p
[0]);
570 cb_store_target_endian (cb
, target_p
+ cb
->target_sizeof_int
,
571 cb
->target_sizeof_int
, p
[1]);
572 if ((*sc
->write_mem
) (cb
, sc
, sc
->arg1
, target_p
,
573 cb
->target_sizeof_int
* 2)
574 != cb
->target_sizeof_int
* 2)
576 /* Close the pipe fd:s. */
577 (*cb
->close
) (cb
, p
[0]);
578 (*cb
->close
) (cb
, p
[1]);
589 /* FIXME: May wish to change CB_SYS_time to something else.
590 We might also want gettimeofday or times, but if system calls
591 can be built on others, we can keep the number we have to support
593 time_t t
= (*cb
->time
) (cb
, (time_t *) 0);
595 /* It is up to target code to process the argument to time(). */
602 /* fall through for now */
615 sc
->errcode
= cb_host_to_target_errno (cb
, errcode
);
620 sc
->errcode
= (*cb
->get_errno
) (cb
);