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"
32 #ifdef ANSI_PROTOTYPES
43 #elif defined (HAVE_STRINGS_H)
52 #include <sys/types.h>
54 #include "gdb/callback.h"
55 #include "targ-vals.h"
61 #define ENAMETOOLONG EINVAL
64 /* Maximum length of a path name. */
66 #define MAX_PATH_LEN 1024
69 /* When doing file read/writes, do this many bytes at a time. */
70 #define FILE_XFR_SIZE 4096
72 /* FIXME: for now, need to consider target word size. */
74 #define TADDR unsigned long
76 /* Path to be prepended to syscalls with absolute paths, and to be
77 chdir:ed at startup, if not empty. */
78 char *simulator_sysroot
= "";
80 /* Utility of cb_syscall to fetch a path name or other string from the target.
81 The result is 0 for success or a host errno value. */
84 get_string (cb
, sc
, buf
, buflen
, addr
)
93 for (p
= buf
, pend
= buf
+ buflen
; p
< pend
; ++p
, ++addr
)
95 /* No, it isn't expected that this would cause one transaction with
96 the remote target for each byte. The target could send the
97 path name along with the syscall request, and cache the file
98 name somewhere (or otherwise tweak this as desired). */
99 unsigned int count
= (*sc
->read_mem
) (cb
, sc
, addr
, p
, 1);
111 /* Utility of cb_syscall to fetch a path name.
112 The buffer is malloc'd and the address is stored in BUFP.
113 The result is that of get_string, but prepended with
114 simulator_sysroot if the string starts with '/'.
115 If an error occurs, no buffer is left malloc'd. */
118 get_path (cb
, sc
, addr
, bufp
)
124 char *buf
= xmalloc (MAX_PATH_LEN
);
126 int sysroot_len
= strlen (simulator_sysroot
);
128 result
= get_string (cb
, sc
, buf
, MAX_PATH_LEN
- sysroot_len
, addr
);
131 /* Prepend absolute paths with simulator_sysroot. Relative paths
132 are supposed to be relative to a chdir within that path, but at
133 this point unknown where. */
134 if (simulator_sysroot
[0] != '\0' && *buf
== '/')
136 /* Considering expected rareness of syscalls with absolute
137 file paths (compared to relative file paths and insn
138 execution), it does not seem worthwhile to rearrange things
139 to get rid of the string moves here; we'd need at least an
140 extra call to check the initial '/' in the path. */
141 memmove (buf
+ sysroot_len
, buf
, sysroot_len
);
142 memcpy (buf
, simulator_sysroot
, sysroot_len
);
152 /* Perform a system call on behalf of the target. */
159 TWORD result
= 0, errcode
= 0;
161 if (sc
->magic
!= CB_SYSCALL_MAGIC
)
164 switch (cb_target_to_host_syscall (cb
, sc
->func
))
166 #if 0 /* FIXME: wip */
167 case CB_SYS_argvlen
:
169 /* Compute how much space is required to store the argv,envp
170 strings so that the program can allocate the space and then
171 call SYS_argv to fetch the values. */
172 int addr_size
= cb
->addr_size
;
173 int argc
,envc
,arglen
,envlen
;
174 const char **argv
= cb
->init_argv
;
175 const char **envp
= cb
->init_envp
;
180 for ( ; argv
[argc
]; ++argc
)
181 arglen
+= strlen (argv
[argc
]) + 1;
186 for ( ; envp
[envc
]; ++envc
)
187 envlen
+= strlen (envp
[envc
]) + 1;
189 result
= arglen
+ envlen
;
195 /* Pointer to target's buffer. */
196 TADDR tbuf
= sc
->arg1
;
198 int bufsize
= sc
->arg2
;
199 /* Q is the target address of where all the strings go. */
201 int word_size
= cb
->word_size
;
203 const char **argv
= cb
->init_argv
;
204 const char **envp
= cb
->init_envp
;
209 for ( ; argv
[argc
]; ++argc
)
211 int len
= strlen (argv
[argc
]);
212 int written
= (*sc
->write_mem
) (cb
, sc
, tbuf
, argv
[argc
], len
+ 1);
222 if ((*sc
->write_mem
) (cb
, sc
, tbuf
, "", 1) != 1)
232 for ( ; envp
[envc
]; ++envc
)
234 int len
= strlen (envp
[envc
]);
235 int written
= (*sc
->write_mem
) (cb
, sc
, tbuf
, envp
[envc
], len
+ 1);
245 if ((*sc
->write_mem
) (cb
, sc
, tbuf
, "", 1) != 1)
258 /* Caller must catch and handle. */
265 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
271 result
= (*cb
->open
) (cb
, path
, sc
->arg2
/*, sc->arg3*/);
279 result
= (*cb
->close
) (cb
, sc
->arg1
);
286 /* ??? Perfect handling of error conditions may require only one
287 call to cb->read. One can't assume all the data is
288 contiguously stored in host memory so that would require
289 malloc'ing/free'ing the space. Maybe later. */
290 char buf
[FILE_XFR_SIZE
];
292 TADDR addr
= sc
->arg2
;
293 size_t count
= sc
->arg3
;
294 size_t bytes_read
= 0;
300 result
= (int) (*cb
->read_stdin
) (cb
, buf
,
301 (count
< FILE_XFR_SIZE
302 ? count
: FILE_XFR_SIZE
));
304 result
= (int) (*cb
->read
) (cb
, fd
, buf
,
305 (count
< FILE_XFR_SIZE
306 ? count
: FILE_XFR_SIZE
));
309 if (result
== 0) /* EOF */
311 bytes_written
= (*sc
->write_mem
) (cb
, sc
, addr
, buf
, result
);
312 if (bytes_written
!= result
)
318 bytes_read
+= result
;
321 /* If this is a short read, don't go back for more */
322 if (result
!= FILE_XFR_SIZE
)
331 /* ??? Perfect handling of error conditions may require only one
332 call to cb->write. One can't assume all the data is
333 contiguously stored in host memory so that would require
334 malloc'ing/free'ing the space. Maybe later. */
335 char buf
[FILE_XFR_SIZE
];
337 TADDR addr
= sc
->arg2
;
338 size_t count
= sc
->arg3
;
340 size_t bytes_written
= 0;
344 int bytes_to_read
= count
< FILE_XFR_SIZE
? count
: FILE_XFR_SIZE
;
345 bytes_read
= (*sc
->read_mem
) (cb
, sc
, addr
, buf
, bytes_to_read
);
346 if (bytes_read
!= bytes_to_read
)
354 result
= (int) (*cb
->write_stdout
) (cb
, buf
, bytes_read
);
355 (*cb
->flush_stdout
) (cb
);
359 result
= (int) (*cb
->write_stderr
) (cb
, buf
, bytes_read
);
360 (*cb
->flush_stderr
) (cb
);
363 result
= (int) (*cb
->write
) (cb
, fd
, buf
, bytes_read
);
366 bytes_written
+= result
;
370 result
= bytes_written
;
377 unsigned long offset
= sc
->arg2
;
378 int whence
= sc
->arg3
;
380 result
= (*cb
->lseek
) (cb
, fd
, offset
, whence
);
390 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
396 result
= (*cb
->unlink
) (cb
, path
);
408 TADDR addr
= sc
->arg2
;
410 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
416 result
= (*cb
->stat
) (cb
, path
, &statbuf
);
420 buflen
= cb_host_to_target_stat (cb
, NULL
, NULL
);
421 buf
= xmalloc (buflen
);
422 if (cb_host_to_target_stat (cb
, &statbuf
, buf
) != buflen
)
424 /* The translation failed. This is due to an internal
425 host program error, not the target's fault. */
431 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != buflen
)
447 TADDR addr
= sc
->arg2
;
449 result
= (*cb
->fstat
) (cb
, sc
->arg1
, &statbuf
);
452 buflen
= cb_host_to_target_stat (cb
, NULL
, NULL
);
453 buf
= xmalloc (buflen
);
454 if (cb_host_to_target_stat (cb
, &statbuf
, buf
) != buflen
)
456 /* The translation failed. This is due to an internal
457 host program error, not the target's fault. */
463 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != buflen
)
476 /* FIXME: May wish to change CB_SYS_time to something else.
477 We might also want gettimeofday or times, but if system calls
478 can be built on others, we can keep the number we have to support
480 time_t t
= (*cb
->time
) (cb
, (time_t *) 0);
482 /* It is up to target code to process the argument to time(). */
489 /* fall through for now */
502 sc
->errcode
= cb_host_to_target_errno (cb
, errcode
);
507 sc
->errcode
= (*cb
->get_errno
) (cb
);
This page took 0.039084 seconds and 4 git commands to generate.