1 /* Remote target system call support.
2 Copyright 1997, 1998, 2002, 2004 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 2 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 GAS; see the file COPYING. If not, write to the Free Software
19 Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
21 /* This interface isn't intended to be specific to any particular kind
22 of remote (hardware, simulator, whatever). As such, support for it
23 (e.g. sim/common/callback.c) should *not* live in the simulator source
24 tree, nor should it live in the gdb source tree. K&R C must be
31 #include "libiberty.h"
39 #elif defined (HAVE_STRINGS_H)
48 #include <sys/types.h>
50 #include "gdb/callback.h"
51 #include "targ-vals.h"
57 #define ENAMETOOLONG EINVAL
60 /* Maximum length of a path name. */
62 #define MAX_PATH_LEN 1024
65 /* When doing file read/writes, do this many bytes at a time. */
66 #define FILE_XFR_SIZE 4096
68 /* FIXME: for now, need to consider target word size. */
70 #define TADDR unsigned long
72 /* Path to be prepended to syscalls with absolute paths, and to be
73 chdir:ed at startup, if not empty. */
74 char *simulator_sysroot
= "";
76 /* Utility of cb_syscall to fetch a path name or other string from the target.
77 The result is 0 for success or a host errno value. */
80 get_string (cb
, sc
, buf
, buflen
, addr
)
89 for (p
= buf
, pend
= buf
+ buflen
; p
< pend
; ++p
, ++addr
)
91 /* No, it isn't expected that this would cause one transaction with
92 the remote target for each byte. The target could send the
93 path name along with the syscall request, and cache the file
94 name somewhere (or otherwise tweak this as desired). */
95 unsigned int count
= (*sc
->read_mem
) (cb
, sc
, addr
, p
, 1);
107 /* Utility of cb_syscall to fetch a path name.
108 The buffer is malloc'd and the address is stored in BUFP.
109 The result is that of get_string, but prepended with
110 simulator_sysroot if the string starts with '/'.
111 If an error occurs, no buffer is left malloc'd. */
114 get_path (cb
, sc
, addr
, bufp
)
120 char *buf
= xmalloc (MAX_PATH_LEN
);
122 int sysroot_len
= strlen (simulator_sysroot
);
124 result
= get_string (cb
, sc
, buf
, MAX_PATH_LEN
- sysroot_len
, addr
);
127 /* Prepend absolute paths with simulator_sysroot. Relative paths
128 are supposed to be relative to a chdir within that path, but at
129 this point unknown where. */
130 if (simulator_sysroot
[0] != '\0' && *buf
== '/')
132 /* Considering expected rareness of syscalls with absolute
133 file paths (compared to relative file paths and insn
134 execution), it does not seem worthwhile to rearrange things
135 to get rid of the string moves here; we'd need at least an
136 extra call to check the initial '/' in the path. */
137 memmove (buf
+ sysroot_len
, buf
, sysroot_len
);
138 memcpy (buf
, simulator_sysroot
, sysroot_len
);
148 /* Perform a system call on behalf of the target. */
155 TWORD result
= 0, errcode
= 0;
157 if (sc
->magic
!= CB_SYSCALL_MAGIC
)
160 switch (cb_target_to_host_syscall (cb
, sc
->func
))
162 #if 0 /* FIXME: wip */
163 case CB_SYS_argvlen
:
165 /* Compute how much space is required to store the argv,envp
166 strings so that the program can allocate the space and then
167 call SYS_argv to fetch the values. */
168 int addr_size
= cb
->addr_size
;
169 int argc
,envc
,arglen
,envlen
;
170 const char **argv
= cb
->init_argv
;
171 const char **envp
= cb
->init_envp
;
176 for ( ; argv
[argc
]; ++argc
)
177 arglen
+= strlen (argv
[argc
]) + 1;
182 for ( ; envp
[envc
]; ++envc
)
183 envlen
+= strlen (envp
[envc
]) + 1;
185 result
= arglen
+ envlen
;
191 /* Pointer to target's buffer. */
192 TADDR tbuf
= sc
->arg1
;
194 int bufsize
= sc
->arg2
;
195 /* Q is the target address of where all the strings go. */
197 int word_size
= cb
->word_size
;
199 const char **argv
= cb
->init_argv
;
200 const char **envp
= cb
->init_envp
;
205 for ( ; argv
[argc
]; ++argc
)
207 int len
= strlen (argv
[argc
]);
208 int written
= (*sc
->write_mem
) (cb
, sc
, tbuf
, argv
[argc
], len
+ 1);
218 if ((*sc
->write_mem
) (cb
, sc
, tbuf
, "", 1) != 1)
228 for ( ; envp
[envc
]; ++envc
)
230 int len
= strlen (envp
[envc
]);
231 int written
= (*sc
->write_mem
) (cb
, sc
, tbuf
, envp
[envc
], len
+ 1);
241 if ((*sc
->write_mem
) (cb
, sc
, tbuf
, "", 1) != 1)
254 /* Caller must catch and handle. */
261 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
267 result
= (*cb
->open
) (cb
, path
, sc
->arg2
/*, sc->arg3*/);
275 result
= (*cb
->close
) (cb
, sc
->arg1
);
282 /* ??? Perfect handling of error conditions may require only one
283 call to cb->read. One can't assume all the data is
284 contiguously stored in host memory so that would require
285 malloc'ing/free'ing the space. Maybe later. */
286 char buf
[FILE_XFR_SIZE
];
288 TADDR addr
= sc
->arg2
;
289 size_t count
= sc
->arg3
;
290 size_t bytes_read
= 0;
296 result
= (int) (*cb
->read_stdin
) (cb
, buf
,
297 (count
< FILE_XFR_SIZE
298 ? count
: FILE_XFR_SIZE
));
300 result
= (int) (*cb
->read
) (cb
, fd
, buf
,
301 (count
< FILE_XFR_SIZE
302 ? count
: FILE_XFR_SIZE
));
305 if (result
== 0) /* EOF */
307 bytes_written
= (*sc
->write_mem
) (cb
, sc
, addr
, buf
, result
);
308 if (bytes_written
!= result
)
314 bytes_read
+= result
;
317 /* If this is a short read, don't go back for more */
318 if (result
!= FILE_XFR_SIZE
)
327 /* ??? Perfect handling of error conditions may require only one
328 call to cb->write. One can't assume all the data is
329 contiguously stored in host memory so that would require
330 malloc'ing/free'ing the space. Maybe later. */
331 char buf
[FILE_XFR_SIZE
];
333 TADDR addr
= sc
->arg2
;
334 size_t count
= sc
->arg3
;
336 size_t bytes_written
= 0;
340 int bytes_to_read
= count
< FILE_XFR_SIZE
? count
: FILE_XFR_SIZE
;
341 bytes_read
= (*sc
->read_mem
) (cb
, sc
, addr
, buf
, bytes_to_read
);
342 if (bytes_read
!= bytes_to_read
)
350 result
= (int) (*cb
->write_stdout
) (cb
, buf
, bytes_read
);
351 (*cb
->flush_stdout
) (cb
);
355 result
= (int) (*cb
->write_stderr
) (cb
, buf
, bytes_read
);
356 (*cb
->flush_stderr
) (cb
);
359 result
= (int) (*cb
->write
) (cb
, fd
, buf
, bytes_read
);
362 bytes_written
+= result
;
366 result
= bytes_written
;
373 unsigned long offset
= sc
->arg2
;
374 int whence
= sc
->arg3
;
376 result
= (*cb
->lseek
) (cb
, fd
, offset
, whence
);
386 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
392 result
= (*cb
->unlink
) (cb
, path
);
399 case CB_SYS_truncate
:
404 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
411 result
= (*cb
->truncate
) (cb
, path
, len
);
418 case CB_SYS_ftruncate
:
423 result
= (*cb
->ftruncate
) (cb
, fd
, len
);
433 errcode
= get_path (cb
, sc
, sc
->arg1
, &path1
);
440 errcode
= get_path (cb
, sc
, sc
->arg2
, &path2
);
448 result
= (*cb
->rename
) (cb
, path1
, path2
);
461 TADDR addr
= sc
->arg2
;
463 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
469 result
= (*cb
->stat
) (cb
, path
, &statbuf
);
473 buflen
= cb_host_to_target_stat (cb
, NULL
, NULL
);
474 buf
= xmalloc (buflen
);
475 if (cb_host_to_target_stat (cb
, &statbuf
, buf
) != buflen
)
477 /* The translation failed. This is due to an internal
478 host program error, not the target's fault. */
484 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != buflen
)
500 TADDR addr
= sc
->arg2
;
502 result
= (*cb
->fstat
) (cb
, sc
->arg1
, &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 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
540 result
= (*cb
->lstat
) (cb
, path
, &statbuf
);
545 buflen
= cb_host_to_target_stat (cb
, NULL
, NULL
);
546 buf
= xmalloc (buflen
);
547 if (cb_host_to_target_stat (cb
, &statbuf
, buf
) != buflen
)
549 /* The translation failed. This is due to an internal
550 host program error, not the target's fault.
551 Unfortunately, it's hard to test this case, so there's no
552 test-case for this execution path. */
559 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != buflen
)
574 char *target_p
= xcalloc (1, cb
->target_sizeof_int
* 2);
576 result
= (*cb
->pipe
) (cb
, p
);
580 cb_store_target_endian (cb
, target_p
, cb
->target_sizeof_int
, p
[0]);
581 cb_store_target_endian (cb
, target_p
+ cb
->target_sizeof_int
,
582 cb
->target_sizeof_int
, p
[1]);
583 if ((*sc
->write_mem
) (cb
, sc
, sc
->arg1
, target_p
,
584 cb
->target_sizeof_int
* 2)
585 != cb
->target_sizeof_int
* 2)
587 /* Close the pipe fd:s. */
588 (*cb
->close
) (cb
, p
[0]);
589 (*cb
->close
) (cb
, p
[1]);
600 /* FIXME: May wish to change CB_SYS_time to something else.
601 We might also want gettimeofday or times, but if system calls
602 can be built on others, we can keep the number we have to support
604 time_t t
= (*cb
->time
) (cb
, (time_t *) 0);
606 /* It is up to target code to process the argument to time(). */
613 /* fall through for now */
626 sc
->errcode
= cb_host_to_target_errno (cb
, errcode
);
631 sc
->errcode
= (*cb
->get_errno
) (cb
);
This page took 0.041094 seconds and 4 git commands to generate.