Silence uninitialized warning on ehdr_start_save
[platform/upstream/binutils.git] / sim / common / syscall.c
1 /* Remote target system call support.
2    Copyright 1997-2014 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
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
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
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 }