1 /* Remote target system call support.
2    Copyright 1997-2013 Free Software Foundation, Inc.
3    Contributed by Cygnus Solutions.
4 
5    This file is part of GDB.
6 
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.
11 
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.
16 
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/>.  */
19 
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
24    supported.  */
25 
26 #ifdef HAVE_CONFIG_H
27 #include "cconfig.h"
28 #endif
29 #include "ansidecl.h"
30 #include "libiberty.h"
31 #include <stdarg.h>
32 #include <stdio.h>
33 #ifdef HAVE_STDLIB_H
34 #include <stdlib.h>
35 #endif
36 #ifdef HAVE_STRING_H
37 #include <string.h>
38 #elif defined (HAVE_STRINGS_H)
39 #include <strings.h>
40 #endif
41 #ifdef HAVE_UNISTD_H
42 #include <unistd.h>
43 #endif
44 #include <errno.h>
45 #include <fcntl.h>
46 #include <time.h>
47 #include <sys/types.h>
48 #include <sys/stat.h>
49 #include "gdb/callback.h"
50 #include "targ-vals.h"
51 
52 #ifndef ENOSYS
53 #define ENOSYS EINVAL
54 #endif
55 #ifndef ENAMETOOLONG
56 #define ENAMETOOLONG EINVAL
57 #endif
58 
59 /* Maximum length of a path name.  */
60 #ifndef MAX_PATH_LEN
61 #define MAX_PATH_LEN 1024
62 #endif
63 
64 /* When doing file read/writes, do this many bytes at a time.  */
65 #define FILE_XFR_SIZE 4096
66 
67 /* FIXME: for now, need to consider target word size.  */
68 #define TWORD long
69 #define TADDR unsigned long
70 
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 = "";
74 
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.  */
77 
78 int
cb_get_string(cb,sc,buf,buflen,addr)79 cb_get_string (cb, sc, buf, buflen, addr)
80      host_callback *cb;
81      CB_SYSCALL *sc;
82      char *buf;
83      int buflen;
84      TADDR addr;
85 {
86   char *p, *pend;
87 
88   for (p = buf, pend = buf + buflen; p < pend; ++p, ++addr)
89     {
90       /* No, it isn't expected that this would cause one transaction with
91 	 the remote target for each byte.  The target could send the
92 	 path name along with the syscall request, and cache the file
93 	 name somewhere (or otherwise tweak this as desired).  */
94       unsigned int count = (*sc->read_mem) (cb, sc, addr, p, 1);
95 
96       if (count != 1)
97 	return EINVAL;
98       if (*p == 0)
99 	break;
100     }
101   if (p == pend)
102     return ENAMETOOLONG;
103   return 0;
104 }
105 
106 /* Utility of cb_syscall to fetch a path name.
107    The buffer is malloc'd and the address is stored in BUFP.
108    The result is that of get_string, but prepended with
109    simulator_sysroot if the string starts with '/'.
110    If an error occurs, no buffer is left malloc'd.  */
111 
112 static int
get_path(cb,sc,addr,bufp)113 get_path (cb, sc, addr, bufp)
114      host_callback *cb;
115      CB_SYSCALL *sc;
116      TADDR addr;
117      char **bufp;
118 {
119   char *buf = xmalloc (MAX_PATH_LEN);
120   int result;
121   int sysroot_len = strlen (simulator_sysroot);
122 
123   result = cb_get_string (cb, sc, buf, MAX_PATH_LEN - sysroot_len, addr);
124   if (result == 0)
125     {
126       /* Prepend absolute paths with simulator_sysroot.  Relative paths
127 	 are supposed to be relative to a chdir within that path, but at
128 	 this point unknown where.  */
129       if (simulator_sysroot[0] != '\0' && *buf == '/')
130 	{
131 	  /* Considering expected rareness of syscalls with absolute
132 	     file paths (compared to relative file paths and insn
133 	     execution), it does not seem worthwhile to rearrange things
134 	     to get rid of the string moves here; we'd need at least an
135 	     extra call to check the initial '/' in the path.  */
136 	  memmove (buf + sysroot_len, buf, sysroot_len);
137 	  memcpy (buf, simulator_sysroot, sysroot_len);
138 	}
139 
140       *bufp = buf;
141     }
142   else
143     free (buf);
144   return result;
145 }
146 
147 /* Perform a system call on behalf of the target.  */
148 
149 CB_RC
cb_syscall(cb,sc)150 cb_syscall (cb, sc)
151      host_callback *cb;
152      CB_SYSCALL *sc;
153 {
154   TWORD result = 0, errcode = 0;
155 
156   if (sc->magic != CB_SYSCALL_MAGIC)
157     abort ();
158 
159   switch (cb_target_to_host_syscall (cb, sc->func))
160     {
161 #if 0 /* FIXME: wip */
162     case CB_SYS_argvlen :
163       {
164 	/* Compute how much space is required to store the argv,envp
165 	   strings so that the program can allocate the space and then
166 	   call SYS_argv to fetch the values.  */
167 	int addr_size = cb->addr_size;
168 	int argc,envc,arglen,envlen;
169 	const char **argv = cb->init_argv;
170 	const char **envp = cb->init_envp;
171 
172 	argc = arglen = 0;
173 	if (argv)
174 	  {
175 	    for ( ; argv[argc]; ++argc)
176 	      arglen += strlen (argv[argc]) + 1;
177 	  }
178 	envc = envlen = 0;
179 	if (envp)
180 	  {
181 	    for ( ; envp[envc]; ++envc)
182 	      envlen += strlen (envp[envc]) + 1;
183 	  }
184 	result = arglen + envlen;
185 	break;
186       }
187 
188     case CB_SYS_argv :
189       {
190 	/* Pointer to target's buffer.  */
191 	TADDR tbuf = sc->arg1;
192 	/* Buffer size.  */
193 	int bufsize = sc->arg2;
194 	/* Q is the target address of where all the strings go.  */
195 	TADDR q;
196 	int word_size = cb->word_size;
197 	int i,argc,envc,len;
198 	const char **argv = cb->init_argv;
199 	const char **envp = cb->init_envp;
200 
201 	argc = 0;
202 	if (argv)
203 	  {
204 	    for ( ; argv[argc]; ++argc)
205 	      {
206 		int len = strlen (argv[argc]);
207 		int written = (*sc->write_mem) (cb, sc, tbuf, argv[argc], len + 1);
208 		if (written != len)
209 		  {
210 		    result = -1;
211 		    errcode = EINVAL;
212 		    goto FinishSyscall;
213 		  }
214 		tbuf = len + 1;
215 	      }
216 	  }
217 	if ((*sc->write_mem) (cb, sc, tbuf, "", 1) != 1)
218 	  {
219 	    result = -1;
220 	    errcode = EINVAL;
221 	    goto FinishSyscall;
222 	  }
223 	tbuf++;
224 	envc = 0;
225 	if (envp)
226 	  {
227 	    for ( ; envp[envc]; ++envc)
228 	      {
229 		int len = strlen (envp[envc]);
230 		int written = (*sc->write_mem) (cb, sc, tbuf, envp[envc], len + 1);
231 		if (written != len)
232 		  {
233 		    result = -1;
234 		    errcode = EINVAL;
235 		    goto FinishSyscall;
236 		  }
237 		tbuf = len + 1;
238 	      }
239 	  }
240 	if ((*sc->write_mem) (cb, sc, tbuf, "", 1) != 1)
241 	  {
242 	    result = -1;
243 	    errcode = EINVAL;
244 	    goto FinishSyscall;
245 	  }
246 	result = argc;
247 	sc->result2 = envc;
248 	break;
249       }
250 #endif /* wip */
251 
252     case CB_SYS_exit :
253       /* Caller must catch and handle.  */
254       break;
255 
256     case CB_SYS_open :
257       {
258 	char *path;
259 
260 	errcode = get_path (cb, sc, sc->arg1, &path);
261 	if (errcode != 0)
262 	  {
263 	    result = -1;
264 	    goto FinishSyscall;
265 	  }
266 	result = (*cb->open) (cb, path, sc->arg2 /*, sc->arg3*/);
267 	free (path);
268 	if (result < 0)
269 	  goto ErrorFinish;
270       }
271       break;
272 
273     case CB_SYS_close :
274       result = (*cb->close) (cb, sc->arg1);
275       if (result < 0)
276 	goto ErrorFinish;
277       break;
278 
279     case CB_SYS_read :
280       {
281 	/* ??? Perfect handling of error conditions may require only one
282 	   call to cb->read.  One can't assume all the data is
283 	   contiguously stored in host memory so that would require
284 	   malloc'ing/free'ing the space.  Maybe later.  */
285 	char buf[FILE_XFR_SIZE];
286 	int fd = sc->arg1;
287 	TADDR addr = sc->arg2;
288 	size_t count = sc->arg3;
289 	size_t bytes_read = 0;
290 	int bytes_written;
291 
292 	while (count > 0)
293 	  {
294 	    if (cb_is_stdin (cb, fd))
295 	      result = (int) (*cb->read_stdin) (cb, buf,
296 						(count < FILE_XFR_SIZE
297 						 ? count : FILE_XFR_SIZE));
298 	    else
299 	      result = (int) (*cb->read) (cb, fd, buf,
300 					  (count < FILE_XFR_SIZE
301 					   ? count : FILE_XFR_SIZE));
302 	    if (result == -1)
303 	      goto ErrorFinish;
304 	    if (result == 0)	/* EOF */
305 	      break;
306 	    bytes_written = (*sc->write_mem) (cb, sc, addr, buf, result);
307 	    if (bytes_written != result)
308 	      {
309 		result = -1;
310 		errcode = EINVAL;
311 		goto FinishSyscall;
312 	      }
313 	    bytes_read += result;
314 	    count -= result;
315 	    addr += result;
316 	    /* If this is a short read, don't go back for more */
317 	    if (result != FILE_XFR_SIZE)
318 	      break;
319 	  }
320 	result = bytes_read;
321       }
322       break;
323 
324     case CB_SYS_write :
325       {
326 	/* ??? Perfect handling of error conditions may require only one
327 	   call to cb->write.  One can't assume all the data is
328 	   contiguously stored in host memory so that would require
329 	   malloc'ing/free'ing the space.  Maybe later.  */
330 	char buf[FILE_XFR_SIZE];
331 	int fd = sc->arg1;
332 	TADDR addr = sc->arg2;
333 	size_t count = sc->arg3;
334 	int bytes_read;
335 	size_t bytes_written = 0;
336 
337 	while (count > 0)
338 	  {
339 	    int bytes_to_read = count < FILE_XFR_SIZE ? count : FILE_XFR_SIZE;
340 	    bytes_read = (*sc->read_mem) (cb, sc, addr, buf, bytes_to_read);
341 	    if (bytes_read != bytes_to_read)
342 	      {
343 		result = -1;
344 		errcode = EINVAL;
345 		goto FinishSyscall;
346 	      }
347 	    if (cb_is_stdout (cb, fd))
348 	      {
349 		result = (int) (*cb->write_stdout) (cb, buf, bytes_read);
350 		(*cb->flush_stdout) (cb);
351 	      }
352 	    else if (cb_is_stderr (cb, fd))
353 	      {
354 		result = (int) (*cb->write_stderr) (cb, buf, bytes_read);
355 		(*cb->flush_stderr) (cb);
356 	      }
357 	    else
358 	      result = (int) (*cb->write) (cb, fd, buf, bytes_read);
359 	    if (result == -1)
360 	      goto ErrorFinish;
361 	    bytes_written += result;
362 	    count -= result;
363 	    addr += result;
364 	  }
365 	result = bytes_written;
366       }
367       break;
368 
369     case CB_SYS_lseek :
370       {
371 	int fd = sc->arg1;
372 	unsigned long offset = sc->arg2;
373 	int whence = sc->arg3;
374 
375 	result = (*cb->lseek) (cb, fd, offset, whence);
376 	if (result < 0)
377 	  goto ErrorFinish;
378       }
379       break;
380 
381     case CB_SYS_unlink :
382       {
383 	char *path;
384 
385 	errcode = get_path (cb, sc, sc->arg1, &path);
386 	if (errcode != 0)
387 	  {
388 	    result = -1;
389 	    goto FinishSyscall;
390 	  }
391 	result = (*cb->unlink) (cb, path);
392 	free (path);
393 	if (result < 0)
394 	  goto ErrorFinish;
395       }
396       break;
397 
398     case CB_SYS_truncate :
399       {
400 	char *path;
401 	long len = sc->arg2;
402 
403 	errcode = get_path (cb, sc, sc->arg1, &path);
404 	if (errcode != 0)
405 	  {
406 	    result = -1;
407 	    errcode = EFAULT;
408 	    goto FinishSyscall;
409 	  }
410 	result = (*cb->truncate) (cb, path, len);
411 	free (path);
412 	if (result < 0)
413 	  goto ErrorFinish;
414       }
415       break;
416 
417     case CB_SYS_ftruncate :
418       {
419 	int fd = sc->arg1;
420 	long len = sc->arg2;
421 
422 	result = (*cb->ftruncate) (cb, fd, len);
423 	if (result < 0)
424 	  goto ErrorFinish;
425       }
426       break;
427 
428     case CB_SYS_rename :
429       {
430 	char *path1, *path2;
431 
432 	errcode = get_path (cb, sc, sc->arg1, &path1);
433 	if (errcode != 0)
434 	  {
435 	    result = -1;
436 	    errcode = EFAULT;
437 	    goto FinishSyscall;
438 	  }
439 	errcode = get_path (cb, sc, sc->arg2, &path2);
440 	if (errcode != 0)
441 	  {
442 	    result = -1;
443 	    errcode = EFAULT;
444 	    free (path1);
445 	    goto FinishSyscall;
446 	  }
447 	result = (*cb->rename) (cb, path1, path2);
448 	free (path1);
449 	free (path2);
450 	if (result < 0)
451 	  goto ErrorFinish;
452       }
453       break;
454 
455     case CB_SYS_stat :
456       {
457 	char *path,*buf;
458 	int buflen;
459 	struct stat statbuf;
460 	TADDR addr = sc->arg2;
461 
462 	errcode = get_path (cb, sc, sc->arg1, &path);
463 	if (errcode != 0)
464 	  {
465 	    result = -1;
466 	    goto FinishSyscall;
467 	  }
468 	result = (*cb->stat) (cb, path, &statbuf);
469 	free (path);
470 	if (result < 0)
471 	  goto ErrorFinish;
472 	buflen = cb_host_to_target_stat (cb, NULL, NULL);
473 	buf = xmalloc (buflen);
474 	if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
475 	  {
476 	    /* The translation failed.  This is due to an internal
477 	       host program error, not the target's fault.  */
478 	    free (buf);
479 	    errcode = ENOSYS;
480 	    result = -1;
481 	    goto FinishSyscall;
482 	  }
483 	if ((*sc->write_mem) (cb, sc, addr, buf, buflen) != buflen)
484 	  {
485 	    free (buf);
486 	    errcode = EINVAL;
487 	    result = -1;
488 	    goto FinishSyscall;
489 	  }
490 	free (buf);
491       }
492       break;
493 
494     case CB_SYS_fstat :
495       {
496 	char *buf;
497 	int buflen;
498 	struct stat statbuf;
499 	TADDR addr = sc->arg2;
500 
501 	result = (*cb->fstat) (cb, sc->arg1, &statbuf);
502 	if (result < 0)
503 	  goto ErrorFinish;
504 	buflen = cb_host_to_target_stat (cb, NULL, NULL);
505 	buf = xmalloc (buflen);
506 	if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
507 	  {
508 	    /* The translation failed.  This is due to an internal
509 	       host program error, not the target's fault.  */
510 	    free (buf);
511 	    errcode = ENOSYS;
512 	    result = -1;
513 	    goto FinishSyscall;
514 	  }
515 	if ((*sc->write_mem) (cb, sc, addr, buf, buflen) != buflen)
516 	  {
517 	    free (buf);
518 	    errcode = EINVAL;
519 	    result = -1;
520 	    goto FinishSyscall;
521 	  }
522 	free (buf);
523       }
524       break;
525 
526     case CB_SYS_lstat :
527       {
528 	char *path, *buf;
529 	int buflen;
530 	struct stat statbuf;
531 	TADDR addr = sc->arg2;
532 
533 	errcode = get_path (cb, sc, sc->arg1, &path);
534 	if (errcode != 0)
535 	  {
536 	    result = -1;
537 	    goto FinishSyscall;
538 	  }
539 	result = (*cb->lstat) (cb, path, &statbuf);
540 	free (path);
541 	if (result < 0)
542 	  goto ErrorFinish;
543 
544 	buflen = cb_host_to_target_stat (cb, NULL, NULL);
545 	buf = xmalloc (buflen);
546 	if (cb_host_to_target_stat (cb, &statbuf, buf) != buflen)
547 	  {
548 	    /* The translation failed.  This is due to an internal
549 	       host program error, not the target's fault.
550 	       Unfortunately, it's hard to test this case, so there's no
551 	       test-case for this execution path.  */
552 	    free (buf);
553 	    errcode = ENOSYS;
554 	    result = -1;
555 	    goto FinishSyscall;
556 	  }
557 
558 	if ((*sc->write_mem) (cb, sc, addr, buf, buflen) != buflen)
559 	  {
560 	    free (buf);
561 	    errcode = EINVAL;
562 	    result = -1;
563 	    goto FinishSyscall;
564 	  }
565 
566 	free (buf);
567       }
568       break;
569 
570     case CB_SYS_pipe :
571       {
572 	int p[2];
573 	char *target_p = xcalloc (1, cb->target_sizeof_int * 2);
574 
575 	result = (*cb->pipe) (cb, p);
576 	if (result != 0)
577 	  goto ErrorFinish;
578 
579 	cb_store_target_endian (cb, target_p, cb->target_sizeof_int, p[0]);
580 	cb_store_target_endian (cb, target_p + cb->target_sizeof_int,
581 				cb->target_sizeof_int, p[1]);
582 	if ((*sc->write_mem) (cb, sc, sc->arg1, target_p,
583 			      cb->target_sizeof_int * 2)
584 	    != cb->target_sizeof_int * 2)
585 	  {
586 	    /* Close the pipe fd:s.  */
587 	    (*cb->close) (cb, p[0]);
588 	    (*cb->close) (cb, p[1]);
589 	    errcode = EFAULT;
590 	    result = -1;
591 	  }
592 
593 	free (target_p);
594       }
595       break;
596 
597     case CB_SYS_time :
598       {
599 	/* FIXME: May wish to change CB_SYS_time to something else.
600 	   We might also want gettimeofday or times, but if system calls
601 	   can be built on others, we can keep the number we have to support
602 	   here down.  */
603 	time_t t = (*cb->time) (cb, (time_t *) 0);
604 	result = t;
605 	/* It is up to target code to process the argument to time().  */
606       }
607       break;
608 
609     case CB_SYS_chdir :
610     case CB_SYS_chmod :
611     case CB_SYS_utime :
612       /* fall through for now */
613 
614     default :
615       result = -1;
616       errcode = ENOSYS;
617       break;
618     }
619 
620  FinishSyscall:
621   sc->result = result;
622   if (errcode == 0)
623     sc->errcode = 0;
624   else
625     sc->errcode = cb_host_to_target_errno (cb, errcode);
626   return CB_RC_OK;
627 
628  ErrorFinish:
629   sc->result = result;
630   sc->errcode = (*cb->get_errno) (cb);
631   return CB_RC_OK;
632 }
633