1 /* Remote target system call support.
2 Copyright 1997 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
47 #include <sys/types.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
68 #define TWORD unsigned long
69 #define TADDR unsigned long
71 /* Utility of cb_syscall to fetch a path name or other string from the target.
72 The result is 0 for success or a host errno value. */
75 get_string (cb
, sc
, buf
, buflen
, addr
)
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.
105 If an error occurs, no buffer is left malloc'd. */
108 get_path (cb
, sc
, addr
, bufp
)
114 char *buf
= xmalloc (MAX_PATH_LEN
);
117 result
= get_string (cb
, sc
, buf
, MAX_PATH_LEN
, addr
);
125 /* Perform a system call on behalf of the target. */
126 /* FIXME: TODO: Add magic number to CB_SYSCALL, macro to initialize it,
127 and test for the magic number here. */
134 /* ??? Need to consider target word size. */
135 long result
= 0, errcode
= 0;
137 switch (cb_target_to_host_syscall (cb
, sc
->func
))
139 #if 0 /* FIXME: wip */
140 case CB_SYS_argvlen
:
142 /* Compute how much space is required to store the argv,envp
143 strings so that the program can allocate the space and then
144 call SYS_argv to fetch the values. */
145 int addr_size
= cb
->addr_size
;
146 int argc
,envc
,arglen
,envlen
;
147 const char **argv
= cb
->init_argv
;
148 const char **envp
= cb
->init_envp
;
153 for ( ; argv
[argc
]; ++argc
)
154 arglen
+= strlen (argv
[argc
]) + 1;
159 for ( ; envp
[envc
]; ++envc
)
160 envlen
+= strlen (envp
[envc
]) + 1;
162 result
= arglen
+ envlen
;
168 /* Pointer to target's buffer. */
169 TADDR tbuf
= sc
->arg1
;
171 int bufsize
= sc
->arg2
;
172 /* Q is the target address of where all the strings go. */
174 int word_size
= cb
->word_size
;
176 const char **argv
= cb
->init_argv
;
177 const char **envp
= cb
->init_envp
;
182 for ( ; argv
[argc
]; ++argc
)
184 int len
= strlen (argv
[argc
]);
185 int written
= (*sc
->write_mem
) (cb
, sc
, tbuf
, argv
[argc
], len
+ 1);
195 if ((*sc
->write_mem
) (cb
, sc
, tbuf
, "", 1) != 1)
205 for ( ; envp
[envc
]; ++envc
)
207 int len
= strlen (envp
[envc
]);
208 int written
= (*sc
->write_mem
) (cb
, sc
, tbuf
, envp
[envc
], len
+ 1);
218 if ((*sc
->write_mem
) (cb
, sc
, tbuf
, "", 1) != 1)
231 /* Caller must catch and handle. */
238 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
244 result
= (*cb
->open
) (cb
, path
, sc
->arg2
/*, sc->arg3*/);
252 result
= (*cb
->close
) (cb
, sc
->arg1
);
259 /* ??? Perfect handling of error conditions may require only one
260 call to cb->read. One can't assume all the data is
261 contiguously stored in host memory so that would require
262 malloc'ing/free'ing the space. Maybe later. */
263 char buf
[FILE_XFR_SIZE
];
265 TADDR addr
= sc
->arg2
;
266 size_t count
= sc
->arg3
;
267 size_t bytes_read
= 0;
273 result
= (int) (*cb
->read_stdin
) (cb
, buf
,
274 (count
< FILE_XFR_SIZE
275 ? count
: FILE_XFR_SIZE
));
277 result
= (int) (*cb
->read
) (cb
, fd
, buf
,
278 (count
< FILE_XFR_SIZE
279 ? count
: FILE_XFR_SIZE
));
282 bytes_written
= (*sc
->write_mem
) (cb
, sc
, addr
, buf
, result
);
283 if (bytes_written
!= result
)
289 bytes_read
+= result
;
299 /* ??? Perfect handling of error conditions may require only one
300 call to cb->write. One can't assume all the data is
301 contiguously stored in host memory so that would require
302 malloc'ing/free'ing the space. Maybe later. */
303 char buf
[FILE_XFR_SIZE
];
305 TADDR addr
= sc
->arg2
;
306 size_t count
= sc
->arg3
;
308 size_t bytes_written
= 0;
312 int bytes_to_read
= count
< FILE_XFR_SIZE
? count
: FILE_XFR_SIZE
;
313 bytes_read
= (*sc
->read_mem
) (cb
, sc
, addr
, buf
, bytes_to_read
);
314 if (bytes_read
!= bytes_to_read
)
321 result
= (int) (*cb
->write_stdout
) (cb
, buf
, bytes_read
);
323 result
= (int) (*cb
->write_stderr
) (cb
, buf
, bytes_read
);
325 result
= (int) (*cb
->write
) (cb
, fd
, buf
, bytes_read
);
328 bytes_written
+= result
;
332 result
= bytes_written
;
339 unsigned long offset
= sc
->arg2
;
340 int whence
= sc
->arg3
;
342 result
= (*cb
->lseek
) (cb
, fd
, offset
, whence
);
352 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
358 result
= (*cb
->unlink
) (cb
, path
);
370 TADDR addr
= sc
->arg2
;
372 errcode
= get_path (cb
, sc
, sc
->arg1
, &path
);
378 result
= (*cb
->stat
) (cb
, path
, &statbuf
);
382 buflen
= cb_host_to_target_stat (cb
, NULL
, NULL
);
383 buf
= xmalloc (buflen
);
384 if (cb_host_to_target_stat (cb
, &statbuf
, buf
) != buflen
)
386 /* The translation failed. This is due to an internal
387 host program error, not the target's fault. */
393 /* ??? Coercion to unsigned avoids -Wall -Werror failure.
394 Ya, cb_host_to_target_stat could return an unsigned int,
395 but that seems worse. */
396 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != (unsigned) buflen
)
412 TADDR addr
= sc
->arg2
;
414 result
= (*cb
->fstat
) (cb
, sc
->arg1
, &statbuf
);
417 buflen
= cb_host_to_target_stat (cb
, NULL
, NULL
);
418 buf
= xmalloc (buflen
);
419 if (cb_host_to_target_stat (cb
, &statbuf
, buf
) != buflen
)
421 /* The translation failed. This is due to an internal
422 host program error, not the target's fault. */
428 /* ??? Coercion to unsigned avoids -Wall -Werror failure.
429 Ya, cb_host_to_target_stat could return an unsigned int,
430 but that seems worse. */
431 if ((*sc
->write_mem
) (cb
, sc
, addr
, buf
, buflen
) != (unsigned) buflen
)
444 /* FIXME: May wish to change CB_SYS_time to something else.
445 We might also want gettimeofday or times, but if system calls
446 can be built on others, we can keep the number we have to support
448 time_t t
= (*cb
->time
) (cb
, (time_t *) 0);
450 /* It is up to target code to process the argument to time(). */
457 /* fall through for now */
470 sc
->errcode
= cb_host_to_target_errno (cb
, errcode
);
475 sc
->errcode
= (*cb
->get_errno
) (cb
);
This page took 0.03972 seconds and 4 git commands to generate.