Home | History | Annotate | Line # | Download | only in bfin
interp.c revision 1.1
      1  1.1  christos /* Simulator for Analog Devices Blackfin processors.
      2  1.1  christos 
      3  1.1  christos    Copyright (C) 2005-2014 Free Software Foundation, Inc.
      4  1.1  christos    Contributed by Analog Devices, Inc.
      5  1.1  christos 
      6  1.1  christos    This file is part of simulators.
      7  1.1  christos 
      8  1.1  christos    This program is free software; you can redistribute it and/or modify
      9  1.1  christos    it under the terms of the GNU General Public License as published by
     10  1.1  christos    the Free Software Foundation; either version 3 of the License, or
     11  1.1  christos    (at your option) any later version.
     12  1.1  christos 
     13  1.1  christos    This program is distributed in the hope that it will be useful,
     14  1.1  christos    but WITHOUT ANY WARRANTY; without even the implied warranty of
     15  1.1  christos    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     16  1.1  christos    GNU General Public License for more details.
     17  1.1  christos 
     18  1.1  christos    You should have received a copy of the GNU General Public License
     19  1.1  christos    along with this program.  If not, see <http://www.gnu.org/licenses/>.  */
     20  1.1  christos 
     21  1.1  christos #include "config.h"
     22  1.1  christos 
     23  1.1  christos #include <stdio.h>
     24  1.1  christos #include <stdlib.h>
     25  1.1  christos #include <string.h>
     26  1.1  christos #include <signal.h>
     27  1.1  christos #include <errno.h>
     28  1.1  christos #include <fcntl.h>
     29  1.1  christos #include <unistd.h>
     30  1.1  christos #include <sys/time.h>
     31  1.1  christos 
     32  1.1  christos #include "gdb/callback.h"
     33  1.1  christos #include "gdb/signals.h"
     34  1.1  christos #include "sim-main.h"
     35  1.1  christos #include "sim-hw.h"
     36  1.1  christos 
     37  1.1  christos #include "targ-vals.h"
     38  1.1  christos 
     39  1.1  christos /* The numbers here do not matter.  They just need to be unique.  */
     40  1.1  christos #define CB_SYS_ioctl        201
     41  1.1  christos #define CB_SYS_mmap2        202
     42  1.1  christos #define CB_SYS_munmap       203
     43  1.1  christos #define CB_SYS_dup2         204
     44  1.1  christos #define CB_SYS_getuid       205
     45  1.1  christos #define CB_SYS_getuid32     206
     46  1.1  christos #define CB_SYS_getgid       207
     47  1.1  christos #define CB_SYS_getgid32     208
     48  1.1  christos #define CB_SYS_setuid       209
     49  1.1  christos #define CB_SYS_setuid32     210
     50  1.1  christos #define CB_SYS_setgid       211
     51  1.1  christos #define CB_SYS_setgid32     212
     52  1.1  christos #define CB_SYS_pread        213
     53  1.1  christos #define CB_SYS__llseek      214
     54  1.1  christos #define CB_SYS_getcwd       215
     55  1.1  christos #define CB_SYS_stat64       216
     56  1.1  christos #define CB_SYS_lstat64      217
     57  1.1  christos #define CB_SYS_fstat64      218
     58  1.1  christos #define CB_SYS_ftruncate64  219
     59  1.1  christos #define CB_SYS_gettimeofday 220
     60  1.1  christos #define CB_SYS_access       221
     61  1.1  christos #include "linux-targ-map.h"
     62  1.1  christos #include "linux-fixed-code.h"
     63  1.1  christos 
     64  1.1  christos #include "elf/common.h"
     65  1.1  christos #include "elf/external.h"
     66  1.1  christos #include "elf/internal.h"
     67  1.1  christos #include "elf/bfin.h"
     68  1.1  christos #include "elf-bfd.h"
     69  1.1  christos 
     70  1.1  christos #include "dv-bfin_cec.h"
     71  1.1  christos #include "dv-bfin_mmu.h"
     72  1.1  christos 
     73  1.1  christos #ifndef HAVE_GETUID
     74  1.1  christos # define getuid() 0
     75  1.1  christos #endif
     76  1.1  christos #ifndef HAVE_GETGID
     77  1.1  christos # define getgid() 0
     78  1.1  christos #endif
     79  1.1  christos #ifndef HAVE_GETEUID
     80  1.1  christos # define geteuid() 0
     81  1.1  christos #endif
     82  1.1  christos #ifndef HAVE_GETEGID
     83  1.1  christos # define getegid() 0
     84  1.1  christos #endif
     85  1.1  christos #ifndef HAVE_SETUID
     86  1.1  christos # define setuid(uid) -1
     87  1.1  christos #endif
     88  1.1  christos #ifndef HAVE_SETGID
     89  1.1  christos # define setgid(gid) -1
     90  1.1  christos #endif
     91  1.1  christos 
     92  1.1  christos static const char cb_linux_stat_map_32[] =
     93  1.1  christos /* Linux kernel 32bit layout:  */
     94  1.1  christos "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
     95  1.1  christos "space,2:st_size,4:st_blksize,4:st_blocks,4:st_atime,4:st_atimensec,4:"
     96  1.1  christos "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:space,4";
     97  1.1  christos /* uClibc public ABI 32bit layout:
     98  1.1  christos "st_dev,8:space,2:space,2:st_ino,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:"
     99  1.1  christos "st_rdev,8:space,2:space,2:st_size,4:st_blksiez,4:st_blocks,4:st_atime,4:"
    100  1.1  christos "st_atimensec,4:st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:"
    101  1.1  christos "space,4";  */
    102  1.1  christos static const char cb_linux_stat_map_64[] =
    103  1.1  christos "st_dev,8:space,4:space,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:st_rdev,8:"
    104  1.1  christos "space,4:st_size,8:st_blksize,4:st_blocks,8:st_atime,4:st_atimensec,4:"
    105  1.1  christos "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:st_ino,8";
    106  1.1  christos static const char cb_libgloss_stat_map_32[] =
    107  1.1  christos "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
    108  1.1  christos "st_size,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:"
    109  1.1  christos "space,4:st_blksize,4:st_blocks,4:space,8";
    110  1.1  christos static const char *stat_map_32, *stat_map_64;
    111  1.1  christos 
    112  1.1  christos /* Count the number of arguments in an argv.  */
    113  1.1  christos static int
    114  1.1  christos count_argc (const char * const *argv)
    115  1.1  christos {
    116  1.1  christos   int i;
    117  1.1  christos 
    118  1.1  christos   if (! argv)
    119  1.1  christos     return -1;
    120  1.1  christos 
    121  1.1  christos   for (i = 0; argv[i] != NULL; ++i)
    122  1.1  christos     continue;
    123  1.1  christos   return i;
    124  1.1  christos }
    125  1.1  christos 
    126  1.1  christos /* Read/write functions for system call interface.  */
    127  1.1  christos 
    128  1.1  christos static int
    129  1.1  christos syscall_read_mem (host_callback *cb, struct cb_syscall *sc,
    130  1.1  christos 		  unsigned long taddr, char *buf, int bytes)
    131  1.1  christos {
    132  1.1  christos   SIM_DESC sd = (SIM_DESC) sc->p1;
    133  1.1  christos   SIM_CPU *cpu = (SIM_CPU *) sc->p2;
    134  1.1  christos 
    135  1.1  christos   MAYBE_TRACE (CORE, cpu, "DBUS FETCH (syscall) %i bytes @ 0x%08lx", bytes, taddr);
    136  1.1  christos 
    137  1.1  christos   return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
    138  1.1  christos }
    139  1.1  christos 
    140  1.1  christos static int
    141  1.1  christos syscall_write_mem (host_callback *cb, struct cb_syscall *sc,
    142  1.1  christos 		  unsigned long taddr, const char *buf, int bytes)
    143  1.1  christos {
    144  1.1  christos   SIM_DESC sd = (SIM_DESC) sc->p1;
    145  1.1  christos   SIM_CPU *cpu = (SIM_CPU *) sc->p2;
    146  1.1  christos 
    147  1.1  christos   MAYBE_TRACE (CORE, cpu, "DBUS STORE (syscall) %i bytes @ 0x%08lx", bytes, taddr);
    148  1.1  christos 
    149  1.1  christos   return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
    150  1.1  christos }
    151  1.1  christos 
    152  1.1  christos /* Simulate a monitor trap, put the result into r0 and errno into r1
    153  1.1  christos    return offset by which to adjust pc.  */
    154  1.1  christos 
    155  1.1  christos void
    156  1.1  christos bfin_syscall (SIM_CPU *cpu)
    157  1.1  christos {
    158  1.1  christos   SIM_DESC sd = CPU_STATE (cpu);
    159  1.1  christos   const char * const *argv = (void *)STATE_PROG_ARGV (sd);
    160  1.1  christos   host_callback *cb = STATE_CALLBACK (sd);
    161  1.1  christos   bu32 args[6];
    162  1.1  christos   CB_SYSCALL sc;
    163  1.1  christos   char *p;
    164  1.1  christos   char _tbuf[1024 * 3], *tbuf = _tbuf, tstr[1024];
    165  1.1  christos   int fmt_ret_hex = 0;
    166  1.1  christos 
    167  1.1  christos   CB_SYSCALL_INIT (&sc);
    168  1.1  christos 
    169  1.1  christos   if (STATE_ENVIRONMENT (sd) == USER_ENVIRONMENT)
    170  1.1  christos     {
    171  1.1  christos       /* Linux syscall.  */
    172  1.1  christos       sc.func = PREG (0);
    173  1.1  christos       sc.arg1 = args[0] = DREG (0);
    174  1.1  christos       sc.arg2 = args[1] = DREG (1);
    175  1.1  christos       sc.arg3 = args[2] = DREG (2);
    176  1.1  christos       sc.arg4 = args[3] = DREG (3);
    177  1.1  christos       /*sc.arg5 =*/ args[4] = DREG (4);
    178  1.1  christos       /*sc.arg6 =*/ args[5] = DREG (5);
    179  1.1  christos     }
    180  1.1  christos   else
    181  1.1  christos     {
    182  1.1  christos       /* libgloss syscall.  */
    183  1.1  christos       sc.func = PREG (0);
    184  1.1  christos       sc.arg1 = args[0] = GET_LONG (DREG (0));
    185  1.1  christos       sc.arg2 = args[1] = GET_LONG (DREG (0) + 4);
    186  1.1  christos       sc.arg3 = args[2] = GET_LONG (DREG (0) + 8);
    187  1.1  christos       sc.arg4 = args[3] = GET_LONG (DREG (0) + 12);
    188  1.1  christos       /*sc.arg5 =*/ args[4] = GET_LONG (DREG (0) + 16);
    189  1.1  christos       /*sc.arg6 =*/ args[5] = GET_LONG (DREG (0) + 20);
    190  1.1  christos     }
    191  1.1  christos   sc.p1 = (PTR) sd;
    192  1.1  christos   sc.p2 = (PTR) cpu;
    193  1.1  christos   sc.read_mem = syscall_read_mem;
    194  1.1  christos   sc.write_mem = syscall_write_mem;
    195  1.1  christos 
    196  1.1  christos   /* Common cb_syscall() handles most functions.  */
    197  1.1  christos   switch (cb_target_to_host_syscall (cb, sc.func))
    198  1.1  christos     {
    199  1.1  christos     case CB_SYS_exit:
    200  1.1  christos       tbuf += sprintf (tbuf, "exit(%i)", args[0]);
    201  1.1  christos       sim_engine_halt (sd, cpu, NULL, PCREG, sim_exited, sc.arg1);
    202  1.1  christos 
    203  1.1  christos #ifdef CB_SYS_argc
    204  1.1  christos     case CB_SYS_argc:
    205  1.1  christos       tbuf += sprintf (tbuf, "argc()");
    206  1.1  christos       sc.result = count_argc (argv);
    207  1.1  christos       break;
    208  1.1  christos     case CB_SYS_argnlen:
    209  1.1  christos       {
    210  1.1  christos       tbuf += sprintf (tbuf, "argnlen(%u)", args[0]);
    211  1.1  christos 	if (sc.arg1 < count_argc (argv))
    212  1.1  christos 	  sc.result = strlen (argv[sc.arg1]);
    213  1.1  christos 	else
    214  1.1  christos 	  sc.result = -1;
    215  1.1  christos       }
    216  1.1  christos       break;
    217  1.1  christos     case CB_SYS_argn:
    218  1.1  christos       {
    219  1.1  christos 	tbuf += sprintf (tbuf, "argn(%u)", args[0]);
    220  1.1  christos 	if (sc.arg1 < count_argc (argv))
    221  1.1  christos 	  {
    222  1.1  christos 	    const char *argn = argv[sc.arg1];
    223  1.1  christos 	    int len = strlen (argn);
    224  1.1  christos 	    int written = sc.write_mem (cb, &sc, sc.arg2, argn, len + 1);
    225  1.1  christos 	    if (written == len + 1)
    226  1.1  christos 	      sc.result = sc.arg2;
    227  1.1  christos 	    else
    228  1.1  christos 	      sc.result = -1;
    229  1.1  christos 	  }
    230  1.1  christos 	else
    231  1.1  christos 	  sc.result = -1;
    232  1.1  christos       }
    233  1.1  christos       break;
    234  1.1  christos #endif
    235  1.1  christos 
    236  1.1  christos     case CB_SYS_gettimeofday:
    237  1.1  christos       {
    238  1.1  christos 	struct timeval _tv, *tv = &_tv;
    239  1.1  christos 	struct timezone _tz, *tz = &_tz;
    240  1.1  christos 
    241  1.1  christos 	tbuf += sprintf (tbuf, "gettimeofday(%#x, %#x)", args[0], args[1]);
    242  1.1  christos 
    243  1.1  christos 	if (sc.arg1 == 0)
    244  1.1  christos 	  tv = NULL;
    245  1.1  christos 	if (sc.arg2 == 0)
    246  1.1  christos 	  tz = NULL;
    247  1.1  christos 	sc.result = gettimeofday (tv, tz);
    248  1.1  christos 
    249  1.1  christos 	if (sc.result == 0)
    250  1.1  christos 	  {
    251  1.1  christos 	    bu32 t;
    252  1.1  christos 
    253  1.1  christos 	    if (tv)
    254  1.1  christos 	      {
    255  1.1  christos 		t = tv->tv_sec;
    256  1.1  christos 		sc.write_mem (cb, &sc, sc.arg1, (void *)&t, 4);
    257  1.1  christos 		t = tv->tv_usec;
    258  1.1  christos 		sc.write_mem (cb, &sc, sc.arg1 + 4, (void *)&t, 4);
    259  1.1  christos 	      }
    260  1.1  christos 
    261  1.1  christos 	    if (sc.arg2)
    262  1.1  christos 	      {
    263  1.1  christos 		t = tz->tz_minuteswest;
    264  1.1  christos 		sc.write_mem (cb, &sc, sc.arg1, (void *)&t, 4);
    265  1.1  christos 		t = tz->tz_dsttime;
    266  1.1  christos 		sc.write_mem (cb, &sc, sc.arg1 + 4, (void *)&t, 4);
    267  1.1  christos 	      }
    268  1.1  christos 	  }
    269  1.1  christos 	else
    270  1.1  christos 	  goto sys_finish;
    271  1.1  christos       }
    272  1.1  christos       break;
    273  1.1  christos 
    274  1.1  christos     case CB_SYS_ioctl:
    275  1.1  christos       /* XXX: hack just enough to get basic stdio w/uClibc ...  */
    276  1.1  christos       tbuf += sprintf (tbuf, "ioctl(%i, %#x, %u)", args[0], args[1], args[2]);
    277  1.1  christos       if (sc.arg2 == 0x5401)
    278  1.1  christos 	{
    279  1.1  christos 	  sc.result = !isatty (sc.arg1);
    280  1.1  christos 	  sc.errcode = 0;
    281  1.1  christos 	}
    282  1.1  christos       else
    283  1.1  christos 	{
    284  1.1  christos 	  sc.result = -1;
    285  1.1  christos 	  sc.errcode = TARGET_EINVAL;
    286  1.1  christos 	}
    287  1.1  christos       break;
    288  1.1  christos 
    289  1.1  christos     case CB_SYS_mmap2:
    290  1.1  christos       {
    291  1.1  christos 	static bu32 heap = BFIN_DEFAULT_MEM_SIZE / 2;
    292  1.1  christos 
    293  1.1  christos 	fmt_ret_hex = 1;
    294  1.1  christos 	tbuf += sprintf (tbuf, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
    295  1.1  christos 			 args[0], args[1], args[2], args[3], args[4], args[5]);
    296  1.1  christos 
    297  1.1  christos 	sc.errcode = 0;
    298  1.1  christos 
    299  1.1  christos 	if (sc.arg4 & 0x20 /*MAP_ANONYMOUS*/)
    300  1.1  christos 	  /* XXX: We don't handle zeroing, but default is all zeros.  */;
    301  1.1  christos 	else if (args[4] >= MAX_CALLBACK_FDS)
    302  1.1  christos 	  sc.errcode = TARGET_ENOSYS;
    303  1.1  christos 	else
    304  1.1  christos 	  {
    305  1.1  christos #ifdef HAVE_PREAD
    306  1.1  christos 	    char *data = xmalloc (sc.arg2);
    307  1.1  christos 
    308  1.1  christos 	    /* XXX: Should add a cb->pread.  */
    309  1.1  christos 	    if (pread (cb->fdmap[args[4]], data, sc.arg2, args[5] << 12) == sc.arg2)
    310  1.1  christos 	      sc.write_mem (cb, &sc, heap, data, sc.arg2);
    311  1.1  christos 	    else
    312  1.1  christos 	      sc.errcode = TARGET_EINVAL;
    313  1.1  christos 
    314  1.1  christos 	    free (data);
    315  1.1  christos #else
    316  1.1  christos 	    sc.errcode = TARGET_ENOSYS;
    317  1.1  christos #endif
    318  1.1  christos 	  }
    319  1.1  christos 
    320  1.1  christos 	if (sc.errcode)
    321  1.1  christos 	  {
    322  1.1  christos 	    sc.result = -1;
    323  1.1  christos 	    break;
    324  1.1  christos 	  }
    325  1.1  christos 
    326  1.1  christos 	sc.result = heap;
    327  1.1  christos 	heap += sc.arg2;
    328  1.1  christos 	/* Keep it page aligned.  */
    329  1.1  christos 	heap = ALIGN (heap, 4096);
    330  1.1  christos 
    331  1.1  christos 	break;
    332  1.1  christos       }
    333  1.1  christos 
    334  1.1  christos     case CB_SYS_munmap:
    335  1.1  christos       /* XXX: meh, just lie for mmap().  */
    336  1.1  christos       tbuf += sprintf (tbuf, "munmap(%#x, %u)", args[0], args[1]);
    337  1.1  christos       sc.result = 0;
    338  1.1  christos       break;
    339  1.1  christos 
    340  1.1  christos     case CB_SYS_dup2:
    341  1.1  christos       tbuf += sprintf (tbuf, "dup2(%i, %i)", args[0], args[1]);
    342  1.1  christos       if (sc.arg1 >= MAX_CALLBACK_FDS || sc.arg2 >= MAX_CALLBACK_FDS)
    343  1.1  christos 	{
    344  1.1  christos 	  sc.result = -1;
    345  1.1  christos 	  sc.errcode = TARGET_EINVAL;
    346  1.1  christos 	}
    347  1.1  christos       else
    348  1.1  christos 	{
    349  1.1  christos 	  sc.result = dup2 (cb->fdmap[sc.arg1], cb->fdmap[sc.arg2]);
    350  1.1  christos 	  goto sys_finish;
    351  1.1  christos 	}
    352  1.1  christos       break;
    353  1.1  christos 
    354  1.1  christos     case CB_SYS__llseek:
    355  1.1  christos       tbuf += sprintf (tbuf, "llseek(%i, %u, %u, %#x, %u)",
    356  1.1  christos 		       args[0], args[1], args[2], args[3], args[4]);
    357  1.1  christos       sc.func = TARGET_LINUX_SYS_lseek;
    358  1.1  christos       if (sc.arg2)
    359  1.1  christos 	{
    360  1.1  christos 	  sc.result = -1;
    361  1.1  christos 	  sc.errcode = TARGET_EINVAL;
    362  1.1  christos 	}
    363  1.1  christos       else
    364  1.1  christos 	{
    365  1.1  christos 	  sc.arg2 = sc.arg3;
    366  1.1  christos 	  sc.arg3 = args[4];
    367  1.1  christos 	  cb_syscall (cb, &sc);
    368  1.1  christos 	  if (sc.result != -1)
    369  1.1  christos 	    {
    370  1.1  christos 	      bu32 z = 0;
    371  1.1  christos 	      sc.write_mem (cb, &sc, args[3], (void *)&sc.result, 4);
    372  1.1  christos 	      sc.write_mem (cb, &sc, args[3] + 4, (void *)&z, 4);
    373  1.1  christos 	    }
    374  1.1  christos 	}
    375  1.1  christos       break;
    376  1.1  christos 
    377  1.1  christos     /* XXX: Should add a cb->pread.  */
    378  1.1  christos     case CB_SYS_pread:
    379  1.1  christos       tbuf += sprintf (tbuf, "pread(%i, %#x, %u, %i)",
    380  1.1  christos 		       args[0], args[1], args[2], args[3]);
    381  1.1  christos       if (sc.arg1 >= MAX_CALLBACK_FDS)
    382  1.1  christos 	{
    383  1.1  christos 	  sc.result = -1;
    384  1.1  christos 	  sc.errcode = TARGET_EINVAL;
    385  1.1  christos 	}
    386  1.1  christos       else
    387  1.1  christos 	{
    388  1.1  christos 	  long old_pos, read_result, read_errcode;
    389  1.1  christos 
    390  1.1  christos 	  /* Get current filepos.  */
    391  1.1  christos 	  sc.func = TARGET_LINUX_SYS_lseek;
    392  1.1  christos 	  sc.arg2 = 0;
    393  1.1  christos 	  sc.arg3 = SEEK_CUR;
    394  1.1  christos 	  cb_syscall (cb, &sc);
    395  1.1  christos 	  if (sc.result == -1)
    396  1.1  christos 	    break;
    397  1.1  christos 	  old_pos = sc.result;
    398  1.1  christos 
    399  1.1  christos 	  /* Move to the new pos.  */
    400  1.1  christos 	  sc.func = TARGET_LINUX_SYS_lseek;
    401  1.1  christos 	  sc.arg2 = args[3];
    402  1.1  christos 	  sc.arg3 = SEEK_SET;
    403  1.1  christos 	  cb_syscall (cb, &sc);
    404  1.1  christos 	  if (sc.result == -1)
    405  1.1  christos 	    break;
    406  1.1  christos 
    407  1.1  christos 	  /* Read the data.  */
    408  1.1  christos 	  sc.func = TARGET_LINUX_SYS_read;
    409  1.1  christos 	  sc.arg2 = args[1];
    410  1.1  christos 	  sc.arg3 = args[2];
    411  1.1  christos 	  cb_syscall (cb, &sc);
    412  1.1  christos 	  read_result = sc.result;
    413  1.1  christos 	  read_errcode = sc.errcode;
    414  1.1  christos 
    415  1.1  christos 	  /* Move back to the old pos.  */
    416  1.1  christos 	  sc.func = TARGET_LINUX_SYS_lseek;
    417  1.1  christos 	  sc.arg2 = old_pos;
    418  1.1  christos 	  sc.arg3 = SEEK_SET;
    419  1.1  christos 	  cb_syscall (cb, &sc);
    420  1.1  christos 
    421  1.1  christos 	  sc.result = read_result;
    422  1.1  christos 	  sc.errcode = read_errcode;
    423  1.1  christos 	}
    424  1.1  christos       break;
    425  1.1  christos 
    426  1.1  christos     case CB_SYS_getcwd:
    427  1.1  christos       tbuf += sprintf (tbuf, "getcwd(%#x, %u)", args[0], args[1]);
    428  1.1  christos 
    429  1.1  christos       p = alloca (sc.arg2);
    430  1.1  christos       if (getcwd (p, sc.arg2) == NULL)
    431  1.1  christos 	{
    432  1.1  christos 	  sc.result = -1;
    433  1.1  christos 	  sc.errcode = TARGET_EINVAL;
    434  1.1  christos 	}
    435  1.1  christos       else
    436  1.1  christos 	{
    437  1.1  christos 	  sc.write_mem (cb, &sc, sc.arg1, p, sc.arg2);
    438  1.1  christos 	  sc.result = sc.arg1;
    439  1.1  christos 	}
    440  1.1  christos       break;
    441  1.1  christos 
    442  1.1  christos     case CB_SYS_stat64:
    443  1.1  christos       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
    444  1.1  christos 	strcpy (tstr, "???");
    445  1.1  christos       tbuf += sprintf (tbuf, "stat64(%#x:\"%s\", %u)", args[0], tstr, args[1]);
    446  1.1  christos       cb->stat_map = stat_map_64;
    447  1.1  christos       sc.func = TARGET_LINUX_SYS_stat;
    448  1.1  christos       cb_syscall (cb, &sc);
    449  1.1  christos       cb->stat_map = stat_map_32;
    450  1.1  christos       break;
    451  1.1  christos     case CB_SYS_lstat64:
    452  1.1  christos       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
    453  1.1  christos 	strcpy (tstr, "???");
    454  1.1  christos       tbuf += sprintf (tbuf, "lstat64(%#x:\"%s\", %u)", args[0], tstr, args[1]);
    455  1.1  christos       cb->stat_map = stat_map_64;
    456  1.1  christos       sc.func = TARGET_LINUX_SYS_lstat;
    457  1.1  christos       cb_syscall (cb, &sc);
    458  1.1  christos       cb->stat_map = stat_map_32;
    459  1.1  christos       break;
    460  1.1  christos     case CB_SYS_fstat64:
    461  1.1  christos       tbuf += sprintf (tbuf, "fstat64(%#x, %u)", args[0], args[1]);
    462  1.1  christos       cb->stat_map = stat_map_64;
    463  1.1  christos       sc.func = TARGET_LINUX_SYS_fstat;
    464  1.1  christos       cb_syscall (cb, &sc);
    465  1.1  christos       cb->stat_map = stat_map_32;
    466  1.1  christos       break;
    467  1.1  christos 
    468  1.1  christos     case CB_SYS_ftruncate64:
    469  1.1  christos       tbuf += sprintf (tbuf, "ftruncate64(%u, %u)", args[0], args[1]);
    470  1.1  christos       sc.func = TARGET_LINUX_SYS_ftruncate;
    471  1.1  christos       cb_syscall (cb, &sc);
    472  1.1  christos       break;
    473  1.1  christos 
    474  1.1  christos     case CB_SYS_getuid:
    475  1.1  christos     case CB_SYS_getuid32:
    476  1.1  christos       tbuf += sprintf (tbuf, "getuid()");
    477  1.1  christos       sc.result = getuid ();
    478  1.1  christos       goto sys_finish;
    479  1.1  christos     case CB_SYS_getgid:
    480  1.1  christos     case CB_SYS_getgid32:
    481  1.1  christos       tbuf += sprintf (tbuf, "getgid()");
    482  1.1  christos       sc.result = getgid ();
    483  1.1  christos       goto sys_finish;
    484  1.1  christos     case CB_SYS_setuid:
    485  1.1  christos       sc.arg1 &= 0xffff;
    486  1.1  christos     case CB_SYS_setuid32:
    487  1.1  christos       tbuf += sprintf (tbuf, "setuid(%u)", args[0]);
    488  1.1  christos       sc.result = setuid (sc.arg1);
    489  1.1  christos       goto sys_finish;
    490  1.1  christos     case CB_SYS_setgid:
    491  1.1  christos       sc.arg1 &= 0xffff;
    492  1.1  christos     case CB_SYS_setgid32:
    493  1.1  christos       tbuf += sprintf (tbuf, "setgid(%u)", args[0]);
    494  1.1  christos       sc.result = setgid (sc.arg1);
    495  1.1  christos       goto sys_finish;
    496  1.1  christos 
    497  1.1  christos     case CB_SYS_getpid:
    498  1.1  christos       tbuf += sprintf (tbuf, "getpid()");
    499  1.1  christos       sc.result = getpid ();
    500  1.1  christos       goto sys_finish;
    501  1.1  christos     case CB_SYS_kill:
    502  1.1  christos       tbuf += sprintf (tbuf, "kill(%u, %i)", args[0], args[1]);
    503  1.1  christos       /* Only let the app kill itself.  */
    504  1.1  christos       if (sc.arg1 != getpid ())
    505  1.1  christos 	{
    506  1.1  christos 	  sc.result = -1;
    507  1.1  christos 	  sc.errcode = TARGET_EPERM;
    508  1.1  christos 	}
    509  1.1  christos       else
    510  1.1  christos 	{
    511  1.1  christos #ifdef HAVE_KILL
    512  1.1  christos 	  sc.result = kill (sc.arg1, sc.arg2);
    513  1.1  christos 	  goto sys_finish;
    514  1.1  christos #else
    515  1.1  christos 	  sc.result = -1;
    516  1.1  christos 	  sc.errcode = TARGET_ENOSYS;
    517  1.1  christos #endif
    518  1.1  christos 	}
    519  1.1  christos       break;
    520  1.1  christos 
    521  1.1  christos     case CB_SYS_open:
    522  1.1  christos       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
    523  1.1  christos 	strcpy (tstr, "???");
    524  1.1  christos       tbuf += sprintf (tbuf, "open(%#x:\"%s\", %#x, %o)",
    525  1.1  christos 		       args[0], tstr, args[1], args[2]);
    526  1.1  christos       goto case_default;
    527  1.1  christos     case CB_SYS_close:
    528  1.1  christos       tbuf += sprintf (tbuf, "close(%i)", args[0]);
    529  1.1  christos       goto case_default;
    530  1.1  christos     case CB_SYS_read:
    531  1.1  christos       tbuf += sprintf (tbuf, "read(%i, %#x, %u)", args[0], args[1], args[2]);
    532  1.1  christos       goto case_default;
    533  1.1  christos     case CB_SYS_write:
    534  1.1  christos       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[1]))
    535  1.1  christos 	strcpy (tstr, "???");
    536  1.1  christos       tbuf += sprintf (tbuf, "write(%i, %#x:\"%s\", %u)",
    537  1.1  christos 		       args[0], args[1], tstr, args[2]);
    538  1.1  christos       goto case_default;
    539  1.1  christos     case CB_SYS_lseek:
    540  1.1  christos       tbuf += sprintf (tbuf, "lseek(%i, %i, %i)", args[0], args[1], args[2]);
    541  1.1  christos       goto case_default;
    542  1.1  christos     case CB_SYS_unlink:
    543  1.1  christos       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
    544  1.1  christos 	strcpy (tstr, "???");
    545  1.1  christos       tbuf += sprintf (tbuf, "unlink(%#x:\"%s\")", args[0], tstr);
    546  1.1  christos       goto case_default;
    547  1.1  christos     case CB_SYS_truncate:
    548  1.1  christos       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
    549  1.1  christos 	strcpy (tstr, "???");
    550  1.1  christos       tbuf += sprintf (tbuf, "truncate(%#x:\"%s\", %i)", args[0], tstr, args[1]);
    551  1.1  christos       goto case_default;
    552  1.1  christos     case CB_SYS_ftruncate:
    553  1.1  christos       tbuf += sprintf (tbuf, "ftruncate(%i, %i)", args[0], args[1]);
    554  1.1  christos       goto case_default;
    555  1.1  christos     case CB_SYS_rename:
    556  1.1  christos       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
    557  1.1  christos 	strcpy (tstr, "???");
    558  1.1  christos       tbuf += sprintf (tbuf, "rename(%#x:\"%s\", ", args[0], tstr);
    559  1.1  christos       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[1]))
    560  1.1  christos 	strcpy (tstr, "???");
    561  1.1  christos       tbuf += sprintf (tbuf, "%#x:\"%s\")", args[1], tstr);
    562  1.1  christos       goto case_default;
    563  1.1  christos     case CB_SYS_stat:
    564  1.1  christos       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
    565  1.1  christos 	strcpy (tstr, "???");
    566  1.1  christos       tbuf += sprintf (tbuf, "stat(%#x:\"%s\", %#x)", args[0], tstr, args[1]);
    567  1.1  christos       goto case_default;
    568  1.1  christos     case CB_SYS_fstat:
    569  1.1  christos       tbuf += sprintf (tbuf, "fstat(%i, %#x)", args[0], args[1]);
    570  1.1  christos       goto case_default;
    571  1.1  christos     case CB_SYS_lstat:
    572  1.1  christos       if (cb_get_string (cb, &sc, tstr, sizeof (tstr), args[0]))
    573  1.1  christos 	strcpy (tstr, "???");
    574  1.1  christos       tbuf += sprintf (tbuf, "lstat(%#x:\"%s\", %#x)", args[0], tstr, args[1]);
    575  1.1  christos       goto case_default;
    576  1.1  christos     case CB_SYS_pipe:
    577  1.1  christos       tbuf += sprintf (tbuf, "pipe(%#x, %#x)", args[0], args[1]);
    578  1.1  christos       goto case_default;
    579  1.1  christos 
    580  1.1  christos     default:
    581  1.1  christos       tbuf += sprintf (tbuf, "???_%i(%#x, %#x, %#x, %#x, %#x, %#x)", sc.func,
    582  1.1  christos 		       args[0], args[1], args[2], args[3], args[4], args[5]);
    583  1.1  christos     case_default:
    584  1.1  christos       cb_syscall (cb, &sc);
    585  1.1  christos       break;
    586  1.1  christos 
    587  1.1  christos     sys_finish:
    588  1.1  christos       if (sc.result == -1)
    589  1.1  christos 	{
    590  1.1  christos 	  cb->last_errno = errno;
    591  1.1  christos 	  sc.errcode = cb->get_errno (cb);
    592  1.1  christos 	}
    593  1.1  christos     }
    594  1.1  christos 
    595  1.1  christos   TRACE_EVENTS (cpu, "syscall_%i(%#x, %#x, %#x, %#x, %#x, %#x) = %li (error = %i)",
    596  1.1  christos 		sc.func, args[0], args[1], args[2], args[3], args[4], args[5],
    597  1.1  christos 		sc.result, sc.errcode);
    598  1.1  christos 
    599  1.1  christos   tbuf += sprintf (tbuf, " = ");
    600  1.1  christos   if (STATE_ENVIRONMENT (sd) == USER_ENVIRONMENT)
    601  1.1  christos     {
    602  1.1  christos       if (sc.result == -1)
    603  1.1  christos 	{
    604  1.1  christos 	  tbuf += sprintf (tbuf, "-1 (error = %i)", sc.errcode);
    605  1.1  christos 	  if (sc.errcode == cb_host_to_target_errno (cb, ENOSYS))
    606  1.1  christos 	    {
    607  1.1  christos 	      sim_io_eprintf (sd, "bfin-sim: %#x: unimplemented syscall %i\n",
    608  1.1  christos 			      PCREG, sc.func);
    609  1.1  christos 	    }
    610  1.1  christos 	  SET_DREG (0, -sc.errcode);
    611  1.1  christos 	}
    612  1.1  christos       else
    613  1.1  christos 	{
    614  1.1  christos 	  if (fmt_ret_hex)
    615  1.1  christos 	    tbuf += sprintf (tbuf, "%#lx", sc.result);
    616  1.1  christos 	  else
    617  1.1  christos 	    tbuf += sprintf (tbuf, "%lu", sc.result);
    618  1.1  christos 	  SET_DREG (0, sc.result);
    619  1.1  christos 	}
    620  1.1  christos     }
    621  1.1  christos   else
    622  1.1  christos     {
    623  1.1  christos       tbuf += sprintf (tbuf, "%lu (error = %i)", sc.result, sc.errcode);
    624  1.1  christos       SET_DREG (0, sc.result);
    625  1.1  christos       SET_DREG (1, sc.result2);
    626  1.1  christos       SET_DREG (2, sc.errcode);
    627  1.1  christos     }
    628  1.1  christos 
    629  1.1  christos   TRACE_SYSCALL (cpu, "%s", _tbuf);
    630  1.1  christos }
    631  1.1  christos 
    632  1.1  christos void
    633  1.1  christos trace_register (SIM_DESC sd,
    634  1.1  christos 		sim_cpu *cpu,
    635  1.1  christos 		const char *fmt,
    636  1.1  christos 		...)
    637  1.1  christos {
    638  1.1  christos   va_list ap;
    639  1.1  christos   trace_printf (sd, cpu, "%s %s",
    640  1.1  christos 		"reg:     ",
    641  1.1  christos 		TRACE_PREFIX (CPU_TRACE_DATA (cpu)));
    642  1.1  christos   va_start (ap, fmt);
    643  1.1  christos   trace_vprintf (sd, cpu, fmt, ap);
    644  1.1  christos   va_end (ap);
    645  1.1  christos   trace_printf (sd, cpu, "\n");
    646  1.1  christos }
    647  1.1  christos 
    648  1.1  christos /* Execute a single instruction.  */
    649  1.1  christos 
    650  1.1  christos static sim_cia
    651  1.1  christos step_once (SIM_CPU *cpu)
    652  1.1  christos {
    653  1.1  christos   SIM_DESC sd = CPU_STATE (cpu);
    654  1.1  christos   bu32 insn_len, oldpc = PCREG;
    655  1.1  christos   int i;
    656  1.1  christos   bool ssstep;
    657  1.1  christos 
    658  1.1  christos   if (TRACE_ANY_P (cpu))
    659  1.1  christos     trace_prefix (sd, cpu, NULL_CIA, oldpc, TRACE_LINENUM_P (cpu),
    660  1.1  christos 		  NULL, 0, " "); /* Use a space for gcc warnings.  */
    661  1.1  christos 
    662  1.1  christos   /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
    663  1.1  christos      has already had the SSSTEP bit enabled.  */
    664  1.1  christos   ssstep = false;
    665  1.1  christos   if (STATE_ENVIRONMENT (sd) == OPERATING_ENVIRONMENT
    666  1.1  christos       && (SYSCFGREG & SYSCFG_SSSTEP))
    667  1.1  christos     {
    668  1.1  christos       int ivg = cec_get_ivg (cpu);
    669  1.1  christos       if (ivg == -1 || ivg > 3)
    670  1.1  christos 	ssstep = true;
    671  1.1  christos     }
    672  1.1  christos 
    673  1.1  christos #if 0
    674  1.1  christos   /* XXX: Is this what happens on the hardware ?  */
    675  1.1  christos   if (cec_get_ivg (cpu) == EVT_EMU)
    676  1.1  christos     cec_return (cpu, EVT_EMU);
    677  1.1  christos #endif
    678  1.1  christos 
    679  1.1  christos   BFIN_CPU_STATE.did_jump = false;
    680  1.1  christos 
    681  1.1  christos   insn_len = interp_insn_bfin (cpu, oldpc);
    682  1.1  christos 
    683  1.1  christos   /* If we executed this insn successfully, then we always decrement
    684  1.1  christos      the loop counter.  We don't want to update the PC though if the
    685  1.1  christos      last insn happened to be a change in code flow (jump/etc...).  */
    686  1.1  christos   if (!BFIN_CPU_STATE.did_jump)
    687  1.1  christos     SET_PCREG (hwloop_get_next_pc (cpu, oldpc, insn_len));
    688  1.1  christos   for (i = 1; i >= 0; --i)
    689  1.1  christos     if (LCREG (i) && oldpc == LBREG (i))
    690  1.1  christos       {
    691  1.1  christos 	SET_LCREG (i, LCREG (i) - 1);
    692  1.1  christos 	if (LCREG (i))
    693  1.1  christos 	  break;
    694  1.1  christos       }
    695  1.1  christos 
    696  1.1  christos   ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu));
    697  1.1  christos 
    698  1.1  christos   /* Handle hardware single stepping only if we're still lower than EVT3.
    699  1.1  christos      XXX: May not be entirely correct wrt EXCPT insns.  */
    700  1.1  christos   if (ssstep)
    701  1.1  christos     {
    702  1.1  christos       int ivg = cec_get_ivg (cpu);
    703  1.1  christos       if (ivg == -1 || ivg > 3)
    704  1.1  christos 	{
    705  1.1  christos 	  INSN_LEN = 0;
    706  1.1  christos 	  cec_exception (cpu, VEC_STEP);
    707  1.1  christos 	}
    708  1.1  christos     }
    709  1.1  christos 
    710  1.1  christos   return oldpc;
    711  1.1  christos }
    712  1.1  christos 
    713  1.1  christos void
    714  1.1  christos sim_engine_run (SIM_DESC sd,
    715  1.1  christos 		int next_cpu_nr, /* ignore  */
    716  1.1  christos 		int nr_cpus, /* ignore  */
    717  1.1  christos 		int siggnal) /* ignore  */
    718  1.1  christos {
    719  1.1  christos   bu32 ticks;
    720  1.1  christos   SIM_CPU *cpu;
    721  1.1  christos 
    722  1.1  christos   SIM_ASSERT (STATE_MAGIC (sd) == SIM_MAGIC_NUMBER);
    723  1.1  christos 
    724  1.1  christos   cpu = STATE_CPU (sd, 0);
    725  1.1  christos 
    726  1.1  christos   while (1)
    727  1.1  christos     {
    728  1.1  christos       step_once (cpu);
    729  1.1  christos       /* Process any events -- can't use tickn because it may
    730  1.1  christos          advance right over the next event.  */
    731  1.1  christos       for (ticks = 0; ticks < CYCLE_DELAY; ++ticks)
    732  1.1  christos 	if (sim_events_tick (sd))
    733  1.1  christos 	  sim_events_process (sd);
    734  1.1  christos     }
    735  1.1  christos }
    736  1.1  christos 
    737  1.1  christos /* Cover function of sim_state_free to free the cpu buffers as well.  */
    738  1.1  christos 
    739  1.1  christos static void
    740  1.1  christos free_state (SIM_DESC sd)
    741  1.1  christos {
    742  1.1  christos   if (STATE_MODULES (sd) != NULL)
    743  1.1  christos     sim_module_uninstall (sd);
    744  1.1  christos   sim_cpu_free_all (sd);
    745  1.1  christos   sim_state_free (sd);
    746  1.1  christos }
    747  1.1  christos 
    748  1.1  christos /* Create an instance of the simulator.  */
    749  1.1  christos 
    750  1.1  christos static void
    751  1.1  christos bfin_initialize_cpu (SIM_DESC sd, SIM_CPU *cpu)
    752  1.1  christos {
    753  1.1  christos   memset (&cpu->state, 0, sizeof (cpu->state));
    754  1.1  christos 
    755  1.1  christos   PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu)) = 0;
    756  1.1  christos 
    757  1.1  christos   bfin_model_cpu_init (sd, cpu);
    758  1.1  christos 
    759  1.1  christos   /* Set default stack to top of scratch pad.  */
    760  1.1  christos   SET_SPREG (BFIN_DEFAULT_MEM_SIZE);
    761  1.1  christos   SET_KSPREG (BFIN_DEFAULT_MEM_SIZE);
    762  1.1  christos   SET_USPREG (BFIN_DEFAULT_MEM_SIZE);
    763  1.1  christos 
    764  1.1  christos   /* This is what the hardware likes.  */
    765  1.1  christos   SET_SYSCFGREG (0x30);
    766  1.1  christos }
    767  1.1  christos 
    768  1.1  christos SIM_DESC
    769  1.1  christos sim_open (SIM_OPEN_KIND kind, host_callback *callback,
    770  1.1  christos 	  struct bfd *abfd, char **argv)
    771  1.1  christos {
    772  1.1  christos   char c;
    773  1.1  christos   int i;
    774  1.1  christos   SIM_DESC sd = sim_state_alloc (kind, callback);
    775  1.1  christos 
    776  1.1  christos   /* The cpu data is kept in a separately allocated chunk of memory.  */
    777  1.1  christos   if (sim_cpu_alloc_all (sd, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK)
    778  1.1  christos     {
    779  1.1  christos       free_state (sd);
    780  1.1  christos       return 0;
    781  1.1  christos     }
    782  1.1  christos 
    783  1.1  christos   {
    784  1.1  christos     /* XXX: Only first core gets profiled ?  */
    785  1.1  christos     SIM_CPU *cpu = STATE_CPU (sd, 0);
    786  1.1  christos     STATE_WATCHPOINTS (sd)->pc = &PCREG;
    787  1.1  christos     STATE_WATCHPOINTS (sd)->sizeof_pc = sizeof (PCREG);
    788  1.1  christos   }
    789  1.1  christos 
    790  1.1  christos   if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
    791  1.1  christos     {
    792  1.1  christos       free_state (sd);
    793  1.1  christos       return 0;
    794  1.1  christos     }
    795  1.1  christos 
    796  1.1  christos   /* XXX: Default to the Virtual environment.  */
    797  1.1  christos   if (STATE_ENVIRONMENT (sd) == ALL_ENVIRONMENT)
    798  1.1  christos     STATE_ENVIRONMENT (sd) = VIRTUAL_ENVIRONMENT;
    799  1.1  christos 
    800  1.1  christos   /* These options override any module options.
    801  1.1  christos      Obviously ambiguity should be avoided, however the caller may wish to
    802  1.1  christos      augment the meaning of an option.  */
    803  1.1  christos #define e_sim_add_option_table(sd, options) \
    804  1.1  christos   do { \
    805  1.1  christos     extern const OPTION options[]; \
    806  1.1  christos     sim_add_option_table (sd, NULL, options); \
    807  1.1  christos   } while (0)
    808  1.1  christos   e_sim_add_option_table (sd, bfin_mmu_options);
    809  1.1  christos   e_sim_add_option_table (sd, bfin_mach_options);
    810  1.1  christos 
    811  1.1  christos   /* getopt will print the error message so we just have to exit if this fails.
    812  1.1  christos      FIXME: Hmmm...  in the case of gdb we need getopt to call
    813  1.1  christos      print_filtered.  */
    814  1.1  christos   if (sim_parse_args (sd, argv) != SIM_RC_OK)
    815  1.1  christos     {
    816  1.1  christos       free_state (sd);
    817  1.1  christos       return 0;
    818  1.1  christos     }
    819  1.1  christos 
    820  1.1  christos   /* Allocate external memory if none specified by user.
    821  1.1  christos      Use address 4 here in case the user wanted address 0 unmapped.  */
    822  1.1  christos   if (sim_core_read_buffer (sd, NULL, read_map, &c, 4, 1) == 0)
    823  1.1  christos     {
    824  1.1  christos       bu16 emuexcpt = 0x25;
    825  1.1  christos       sim_do_commandf (sd, "memory-size 0x%lx", BFIN_DEFAULT_MEM_SIZE);
    826  1.1  christos       sim_write (sd, 0, (void *)&emuexcpt, 2);
    827  1.1  christos     }
    828  1.1  christos 
    829  1.1  christos   /* Check for/establish the a reference program image.  */
    830  1.1  christos   if (sim_analyze_program (sd,
    831  1.1  christos 			   (STATE_PROG_ARGV (sd) != NULL
    832  1.1  christos 			    ? *STATE_PROG_ARGV (sd)
    833  1.1  christos 			    : NULL), abfd) != SIM_RC_OK)
    834  1.1  christos     {
    835  1.1  christos       free_state (sd);
    836  1.1  christos       return 0;
    837  1.1  christos     }
    838  1.1  christos 
    839  1.1  christos   /* Establish any remaining configuration options.  */
    840  1.1  christos   if (sim_config (sd) != SIM_RC_OK)
    841  1.1  christos     {
    842  1.1  christos       free_state (sd);
    843  1.1  christos       return 0;
    844  1.1  christos     }
    845  1.1  christos 
    846  1.1  christos   if (sim_post_argv_init (sd) != SIM_RC_OK)
    847  1.1  christos     {
    848  1.1  christos       free_state (sd);
    849  1.1  christos       return 0;
    850  1.1  christos     }
    851  1.1  christos 
    852  1.1  christos   /* CPU specific initialization.  */
    853  1.1  christos   for (i = 0; i < MAX_NR_PROCESSORS; ++i)
    854  1.1  christos     {
    855  1.1  christos       SIM_CPU *cpu = STATE_CPU (sd, i);
    856  1.1  christos       bfin_initialize_cpu (sd, cpu);
    857  1.1  christos     }
    858  1.1  christos 
    859  1.1  christos   return sd;
    860  1.1  christos }
    861  1.1  christos 
    862  1.1  christos void
    863  1.1  christos sim_close (SIM_DESC sd, int quitting)
    864  1.1  christos {
    865  1.1  christos   sim_module_uninstall (sd);
    866  1.1  christos }
    867  1.1  christos 
    868  1.1  christos /* Some utils don't like having a NULL environ.  */
    869  1.1  christos static const char * const simple_env[] = { "HOME=/", "PATH=/bin", NULL };
    870  1.1  christos 
    871  1.1  christos static bu32 fdpic_load_offset;
    872  1.1  christos 
    873  1.1  christos static bool
    874  1.1  christos bfin_fdpic_load (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd, bu32 *sp,
    875  1.1  christos 		 bu32 *elf_addrs, char **ldso_path)
    876  1.1  christos {
    877  1.1  christos   bool ret;
    878  1.1  christos   int i;
    879  1.1  christos 
    880  1.1  christos   Elf_Internal_Ehdr *iehdr;
    881  1.1  christos   Elf32_External_Ehdr ehdr;
    882  1.1  christos   Elf_Internal_Phdr *phdrs;
    883  1.1  christos   unsigned char *data;
    884  1.1  christos   long phdr_size;
    885  1.1  christos   int phdrc;
    886  1.1  christos   bu32 nsegs;
    887  1.1  christos 
    888  1.1  christos   bu32 max_load_addr;
    889  1.1  christos 
    890  1.1  christos   unsigned char null[4] = { 0, 0, 0, 0 };
    891  1.1  christos 
    892  1.1  christos   ret = false;
    893  1.1  christos   *ldso_path = NULL;
    894  1.1  christos 
    895  1.1  christos   /* See if this an FDPIC ELF.  */
    896  1.1  christos   phdrs = NULL;
    897  1.1  christos   if (!abfd)
    898  1.1  christos     goto skip_fdpic_init;
    899  1.1  christos   if (bfd_seek (abfd, 0, SEEK_SET) != 0)
    900  1.1  christos     goto skip_fdpic_init;
    901  1.1  christos   if (bfd_bread (&ehdr, sizeof (ehdr), abfd) != sizeof (ehdr))
    902  1.1  christos     goto skip_fdpic_init;
    903  1.1  christos   iehdr = elf_elfheader (abfd);
    904  1.1  christos   if (!(iehdr->e_flags & EF_BFIN_FDPIC))
    905  1.1  christos     goto skip_fdpic_init;
    906  1.1  christos 
    907  1.1  christos   if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
    908  1.1  christos     sim_io_printf (sd, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
    909  1.1  christos 		   bfd_get_filename (abfd), fdpic_load_offset, elf_addrs[0]);
    910  1.1  christos 
    911  1.1  christos   /* Grab the Program Headers to set up the loadsegs on the stack.  */
    912  1.1  christos   phdr_size = bfd_get_elf_phdr_upper_bound (abfd);
    913  1.1  christos   if (phdr_size == -1)
    914  1.1  christos     goto skip_fdpic_init;
    915  1.1  christos   phdrs = xmalloc (phdr_size);
    916  1.1  christos   phdrc = bfd_get_elf_phdrs (abfd, phdrs);
    917  1.1  christos   if (phdrc == -1)
    918  1.1  christos     goto skip_fdpic_init;
    919  1.1  christos 
    920  1.1  christos   /* Push the Ehdr onto the stack.  */
    921  1.1  christos   *sp -= sizeof (ehdr);
    922  1.1  christos   elf_addrs[3] = *sp;
    923  1.1  christos   sim_write (sd, *sp, (void *)&ehdr, sizeof (ehdr));
    924  1.1  christos   if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
    925  1.1  christos     sim_io_printf (sd, " Elf_Ehdr: %#x\n", *sp);
    926  1.1  christos 
    927  1.1  christos   /* Since we're relocating things ourselves, we need to relocate
    928  1.1  christos      the start address as well.  */
    929  1.1  christos   elf_addrs[0] = bfd_get_start_address (abfd) + fdpic_load_offset;
    930  1.1  christos 
    931  1.1  christos   /* And the Exec's Phdrs onto the stack.  */
    932  1.1  christos   if (STATE_PROG_BFD (sd) == abfd)
    933  1.1  christos     {
    934  1.1  christos       elf_addrs[4] = elf_addrs[0];
    935  1.1  christos 
    936  1.1  christos       phdr_size = iehdr->e_phentsize * iehdr->e_phnum;
    937  1.1  christos       if (bfd_seek (abfd, iehdr->e_phoff, SEEK_SET) != 0)
    938  1.1  christos 	goto skip_fdpic_init;
    939  1.1  christos       data = xmalloc (phdr_size);
    940  1.1  christos       if (bfd_bread (data, phdr_size, abfd) != phdr_size)
    941  1.1  christos 	goto skip_fdpic_init;
    942  1.1  christos       *sp -= phdr_size;
    943  1.1  christos       elf_addrs[1] = *sp;
    944  1.1  christos       elf_addrs[2] = phdrc;
    945  1.1  christos       sim_write (sd, *sp, data, phdr_size);
    946  1.1  christos       free (data);
    947  1.1  christos       if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
    948  1.1  christos 	sim_io_printf (sd, " Elf_Phdrs: %#x\n", *sp);
    949  1.1  christos     }
    950  1.1  christos 
    951  1.1  christos   /* Now push all the loadsegs.  */
    952  1.1  christos   nsegs = 0;
    953  1.1  christos   max_load_addr = 0;
    954  1.1  christos   for (i = phdrc; i >= 0; --i)
    955  1.1  christos     if (phdrs[i].p_type == PT_LOAD)
    956  1.1  christos       {
    957  1.1  christos 	Elf_Internal_Phdr *p = &phdrs[i];
    958  1.1  christos 	bu32 paddr, vaddr, memsz, filesz;
    959  1.1  christos 
    960  1.1  christos 	paddr = p->p_paddr + fdpic_load_offset;
    961  1.1  christos 	vaddr = p->p_vaddr;
    962  1.1  christos 	memsz = p->p_memsz;
    963  1.1  christos 	filesz = p->p_filesz;
    964  1.1  christos 
    965  1.1  christos 	if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
    966  1.1  christos 	  sim_io_printf (sd, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
    967  1.1  christos 			 i, vaddr, paddr, filesz, memsz);
    968  1.1  christos 
    969  1.1  christos 	data = xmalloc (memsz);
    970  1.1  christos 	if (memsz != filesz)
    971  1.1  christos 	  memset (data + filesz, 0, memsz - filesz);
    972  1.1  christos 
    973  1.1  christos 	if (bfd_seek (abfd, p->p_offset, SEEK_SET) == 0
    974  1.1  christos 	    && bfd_bread (data, filesz, abfd) == filesz)
    975  1.1  christos 	  sim_write (sd, paddr, data, memsz);
    976  1.1  christos 
    977  1.1  christos 	free (data);
    978  1.1  christos 
    979  1.1  christos 	max_load_addr = MAX (paddr + memsz, max_load_addr);
    980  1.1  christos 
    981  1.1  christos 	*sp -= 12;
    982  1.1  christos 	sim_write (sd, *sp+0, (void *)&paddr, 4); /* loadseg.addr  */
    983  1.1  christos 	sim_write (sd, *sp+4, (void *)&vaddr, 4); /* loadseg.p_vaddr  */
    984  1.1  christos 	sim_write (sd, *sp+8, (void *)&memsz, 4); /* loadseg.p_memsz  */
    985  1.1  christos 	++nsegs;
    986  1.1  christos       }
    987  1.1  christos     else if (phdrs[i].p_type == PT_DYNAMIC)
    988  1.1  christos       {
    989  1.1  christos 	elf_addrs[5] = phdrs[i].p_paddr + fdpic_load_offset;
    990  1.1  christos 	if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
    991  1.1  christos 	  sim_io_printf (sd, " PT_DYNAMIC: %#x\n", elf_addrs[5]);
    992  1.1  christos       }
    993  1.1  christos     else if (phdrs[i].p_type == PT_INTERP)
    994  1.1  christos       {
    995  1.1  christos 	uint32_t off = phdrs[i].p_offset;
    996  1.1  christos 	uint32_t len = phdrs[i].p_filesz;
    997  1.1  christos 
    998  1.1  christos 	*ldso_path = xmalloc (len);
    999  1.1  christos 	if (bfd_seek (abfd, off, SEEK_SET) != 0
   1000  1.1  christos 	    || bfd_bread (*ldso_path, len, abfd) != len)
   1001  1.1  christos 	  {
   1002  1.1  christos 	    free (*ldso_path);
   1003  1.1  christos 	    *ldso_path = NULL;
   1004  1.1  christos 	  }
   1005  1.1  christos 	else if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
   1006  1.1  christos 	  sim_io_printf (sd, " PT_INTERP: %s\n", *ldso_path);
   1007  1.1  christos       }
   1008  1.1  christos 
   1009  1.1  christos   /* Update the load offset with a few extra pages.  */
   1010  1.1  christos   fdpic_load_offset = ALIGN (MAX (max_load_addr, fdpic_load_offset), 0x10000);
   1011  1.1  christos   fdpic_load_offset += 0x10000;
   1012  1.1  christos 
   1013  1.1  christos   /* Push the summary loadmap info onto the stack last.  */
   1014  1.1  christos   *sp -= 4;
   1015  1.1  christos   sim_write (sd, *sp+0, null, 2); /* loadmap.version  */
   1016  1.1  christos   sim_write (sd, *sp+2, (void *)&nsegs, 2); /* loadmap.nsegs  */
   1017  1.1  christos 
   1018  1.1  christos   ret = true;
   1019  1.1  christos  skip_fdpic_init:
   1020  1.1  christos   free (phdrs);
   1021  1.1  christos 
   1022  1.1  christos   return ret;
   1023  1.1  christos }
   1024  1.1  christos 
   1025  1.1  christos static void
   1026  1.1  christos bfin_user_init (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd,
   1027  1.1  christos 		const char * const *argv, const char * const *env)
   1028  1.1  christos {
   1029  1.1  christos   /* XXX: Missing host -> target endian ...  */
   1030  1.1  christos   /* Linux starts the user app with the stack:
   1031  1.1  christos        argc
   1032  1.1  christos        argv[0]          -- pointers to the actual strings
   1033  1.1  christos        argv[1..N]
   1034  1.1  christos        NULL
   1035  1.1  christos        env[0]
   1036  1.1  christos        env[1..N]
   1037  1.1  christos        NULL
   1038  1.1  christos        auxvt[0].type    -- ELF Auxiliary Vector Table
   1039  1.1  christos        auxvt[0].value
   1040  1.1  christos        auxvt[1..N]
   1041  1.1  christos        AT_NULL
   1042  1.1  christos        0
   1043  1.1  christos        argv[0..N][0..M] -- actual argv/env strings
   1044  1.1  christos        env[0..N][0..M]
   1045  1.1  christos        FDPIC loadmaps   -- for FDPIC apps
   1046  1.1  christos      So set things up the same way.  */
   1047  1.1  christos   int i, argc, envc;
   1048  1.1  christos   bu32 argv_flat, env_flat;
   1049  1.1  christos 
   1050  1.1  christos   bu32 sp, sp_flat;
   1051  1.1  christos 
   1052  1.1  christos   /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic  */
   1053  1.1  christos   bu32 elf_addrs[6];
   1054  1.1  christos   bu32 auxvt;
   1055  1.1  christos   bu32 exec_loadmap, ldso_loadmap;
   1056  1.1  christos   char *ldso_path;
   1057  1.1  christos 
   1058  1.1  christos   unsigned char null[4] = { 0, 0, 0, 0 };
   1059  1.1  christos 
   1060  1.1  christos   host_callback *cb = STATE_CALLBACK (sd);
   1061  1.1  christos 
   1062  1.1  christos   elf_addrs[0] = elf_addrs[4] = bfd_get_start_address (abfd);
   1063  1.1  christos   elf_addrs[1] = elf_addrs[2] = elf_addrs[3] = elf_addrs[5] = 0;
   1064  1.1  christos 
   1065  1.1  christos   /* Keep the load addresses consistent between runs.  Also make sure we make
   1066  1.1  christos      space for the fixed code region (part of the Blackfin Linux ABI).  */
   1067  1.1  christos   fdpic_load_offset = 0x1000;
   1068  1.1  christos 
   1069  1.1  christos   /* First try to load this as an FDPIC executable.  */
   1070  1.1  christos   sp = SPREG;
   1071  1.1  christos   if (!bfin_fdpic_load (sd, cpu, STATE_PROG_BFD (sd), &sp, elf_addrs, &ldso_path))
   1072  1.1  christos     goto skip_fdpic_init;
   1073  1.1  christos   exec_loadmap = sp;
   1074  1.1  christos 
   1075  1.1  christos   /* If that worked, then load the fixed code region.  We only do this for
   1076  1.1  christos      FDPIC ELFs atm because they are PIEs and let us relocate them without
   1077  1.1  christos      manual fixups.  FLAT files however require location processing which
   1078  1.1  christos      we do not do ourselves, and they link with a VMA of 0.  */
   1079  1.1  christos   sim_write (sd, 0x400, bfin_linux_fixed_code, sizeof (bfin_linux_fixed_code));
   1080  1.1  christos 
   1081  1.1  christos   /* If the FDPIC needs an interpreter, then load it up too.  */
   1082  1.1  christos   if (ldso_path)
   1083  1.1  christos     {
   1084  1.1  christos       const char *ldso_full_path = concat (simulator_sysroot, ldso_path, NULL);
   1085  1.1  christos       struct bfd *ldso_bfd;
   1086  1.1  christos 
   1087  1.1  christos       ldso_bfd = bfd_openr (ldso_full_path, STATE_TARGET (sd));
   1088  1.1  christos       if (!ldso_bfd)
   1089  1.1  christos 	{
   1090  1.1  christos 	  sim_io_eprintf (sd, "bfin-sim: bfd open failed: %s\n", ldso_full_path);
   1091  1.1  christos 	  goto static_fdpic;
   1092  1.1  christos 	}
   1093  1.1  christos       if (!bfd_check_format (ldso_bfd, bfd_object))
   1094  1.1  christos 	sim_io_eprintf (sd, "bfin-sim: bfd format not valid: %s\n", ldso_full_path);
   1095  1.1  christos       bfd_set_arch_info (ldso_bfd, STATE_ARCHITECTURE (sd));
   1096  1.1  christos 
   1097  1.1  christos       if (!bfin_fdpic_load (sd, cpu, ldso_bfd, &sp, elf_addrs, &ldso_path))
   1098  1.1  christos 	sim_io_eprintf (sd, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path);
   1099  1.1  christos       if (ldso_path)
   1100  1.1  christos 	sim_io_eprintf (sd, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
   1101  1.1  christos 			ldso_full_path, ldso_path);
   1102  1.1  christos 
   1103  1.1  christos       ldso_loadmap = sp;
   1104  1.1  christos     }
   1105  1.1  christos   else
   1106  1.1  christos  static_fdpic:
   1107  1.1  christos     ldso_loadmap = 0;
   1108  1.1  christos 
   1109  1.1  christos   /* Finally setup the registers required by the FDPIC ABI.  */
   1110  1.1  christos   SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up.  */
   1111  1.1  christos   SET_PREG (0, exec_loadmap); /* Exec loadmap addr.  */
   1112  1.1  christos   SET_PREG (1, ldso_loadmap); /* Interp loadmap addr.  */
   1113  1.1  christos   SET_PREG (2, elf_addrs[5]); /* PT_DYNAMIC map addr.  */
   1114  1.1  christos 
   1115  1.1  christos   auxvt = 1;
   1116  1.1  christos   SET_SPREG (sp);
   1117  1.1  christos  skip_fdpic_init:
   1118  1.1  christos   sim_pc_set (cpu, elf_addrs[0]);
   1119  1.1  christos 
   1120  1.1  christos   /* Figure out how much storage the argv/env strings need.  */
   1121  1.1  christos   argc = count_argc (argv);
   1122  1.1  christos   if (argc == -1)
   1123  1.1  christos     argc = 0;
   1124  1.1  christos   argv_flat = argc; /* NUL bytes  */
   1125  1.1  christos   for (i = 0; i < argc; ++i)
   1126  1.1  christos     argv_flat += strlen (argv[i]);
   1127  1.1  christos 
   1128  1.1  christos   if (!env)
   1129  1.1  christos     env = simple_env;
   1130  1.1  christos   envc = count_argc (env);
   1131  1.1  christos   env_flat = envc; /* NUL bytes  */
   1132  1.1  christos   for (i = 0; i < envc; ++i)
   1133  1.1  christos     env_flat += strlen (env[i]);
   1134  1.1  christos 
   1135  1.1  christos   /* Push the Auxiliary Vector Table between argv/env and actual strings.  */
   1136  1.1  christos   sp_flat = sp = ALIGN (SPREG - argv_flat - env_flat - 4, 4);
   1137  1.1  christos   if (auxvt)
   1138  1.1  christos     {
   1139  1.1  christos # define AT_PUSH(at, val) \
   1140  1.1  christos   auxvt_size += 8; \
   1141  1.1  christos   sp -= 4; \
   1142  1.1  christos   auxvt = (val); \
   1143  1.1  christos   sim_write (sd, sp, (void *)&auxvt, 4); \
   1144  1.1  christos   sp -= 4; \
   1145  1.1  christos   auxvt = (at); \
   1146  1.1  christos   sim_write (sd, sp, (void *)&auxvt, 4)
   1147  1.1  christos       unsigned int egid = getegid (), gid = getgid ();
   1148  1.1  christos       unsigned int euid = geteuid (), uid = getuid ();
   1149  1.1  christos       bu32 auxvt_size = 0;
   1150  1.1  christos       AT_PUSH (AT_NULL, 0);
   1151  1.1  christos       AT_PUSH (AT_SECURE, egid != gid || euid != uid);
   1152  1.1  christos       AT_PUSH (AT_EGID, egid);
   1153  1.1  christos       AT_PUSH (AT_GID, gid);
   1154  1.1  christos       AT_PUSH (AT_EUID, euid);
   1155  1.1  christos       AT_PUSH (AT_UID, uid);
   1156  1.1  christos       AT_PUSH (AT_ENTRY, elf_addrs[4]);
   1157  1.1  christos       AT_PUSH (AT_FLAGS, 0);
   1158  1.1  christos       AT_PUSH (AT_BASE, elf_addrs[3]);
   1159  1.1  christos       AT_PUSH (AT_PHNUM, elf_addrs[2]);
   1160  1.1  christos       AT_PUSH (AT_PHENT, sizeof (Elf32_External_Phdr));
   1161  1.1  christos       AT_PUSH (AT_PHDR, elf_addrs[1]);
   1162  1.1  christos       AT_PUSH (AT_CLKTCK, 100); /* XXX: This ever not 100 ?  */
   1163  1.1  christos       AT_PUSH (AT_PAGESZ, 4096);
   1164  1.1  christos       AT_PUSH (AT_HWCAP, 0);
   1165  1.1  christos #undef AT_PUSH
   1166  1.1  christos     }
   1167  1.1  christos   SET_SPREG (sp);
   1168  1.1  christos 
   1169  1.1  christos   /* Push the argc/argv/env after the auxvt.  */
   1170  1.1  christos   sp -= ((1 + argc + 1 + envc + 1) * 4);
   1171  1.1  christos   SET_SPREG (sp);
   1172  1.1  christos 
   1173  1.1  christos   /* First push the argc value.  */
   1174  1.1  christos   sim_write (sd, sp, (void *)&argc, 4);
   1175  1.1  christos   sp += 4;
   1176  1.1  christos 
   1177  1.1  christos   /* Then the actual argv strings so we know where to point argv[].  */
   1178  1.1  christos   for (i = 0; i < argc; ++i)
   1179  1.1  christos     {
   1180  1.1  christos       unsigned len = strlen (argv[i]) + 1;
   1181  1.1  christos       sim_write (sd, sp_flat, (void *)argv[i], len);
   1182  1.1  christos       sim_write (sd, sp, (void *)&sp_flat, 4);
   1183  1.1  christos       sp_flat += len;
   1184  1.1  christos       sp += 4;
   1185  1.1  christos     }
   1186  1.1  christos   sim_write (sd, sp, null, 4);
   1187  1.1  christos   sp += 4;
   1188  1.1  christos 
   1189  1.1  christos   /* Then the actual env strings so we know where to point env[].  */
   1190  1.1  christos   for (i = 0; i < envc; ++i)
   1191  1.1  christos     {
   1192  1.1  christos       unsigned len = strlen (env[i]) + 1;
   1193  1.1  christos       sim_write (sd, sp_flat, (void *)env[i], len);
   1194  1.1  christos       sim_write (sd, sp, (void *)&sp_flat, 4);
   1195  1.1  christos       sp_flat += len;
   1196  1.1  christos       sp += 4;
   1197  1.1  christos     }
   1198  1.1  christos 
   1199  1.1  christos   /* Set some callbacks.  */
   1200  1.1  christos   cb->syscall_map = cb_linux_syscall_map;
   1201  1.1  christos   cb->errno_map = cb_linux_errno_map;
   1202  1.1  christos   cb->open_map = cb_linux_open_map;
   1203  1.1  christos   cb->signal_map = cb_linux_signal_map;
   1204  1.1  christos   cb->stat_map = stat_map_32 = cb_linux_stat_map_32;
   1205  1.1  christos   stat_map_64 = cb_linux_stat_map_64;
   1206  1.1  christos }
   1207  1.1  christos 
   1208  1.1  christos static void
   1209  1.1  christos bfin_os_init (SIM_DESC sd, SIM_CPU *cpu, const char * const *argv)
   1210  1.1  christos {
   1211  1.1  christos   /* Pass the command line via a string in R0 like Linux expects.  */
   1212  1.1  christos   int i;
   1213  1.1  christos   bu8 byte;
   1214  1.1  christos   bu32 cmdline = BFIN_L1_SRAM_SCRATCH;
   1215  1.1  christos 
   1216  1.1  christos   SET_DREG (0, cmdline);
   1217  1.1  christos   if (argv && argv[0])
   1218  1.1  christos     {
   1219  1.1  christos       i = 1;
   1220  1.1  christos       byte = ' ';
   1221  1.1  christos       while (argv[i])
   1222  1.1  christos 	{
   1223  1.1  christos 	  bu32 len = strlen (argv[i]);
   1224  1.1  christos 	  sim_write (sd, cmdline, (void *)argv[i], len);
   1225  1.1  christos 	  cmdline += len;
   1226  1.1  christos 	  sim_write (sd, cmdline, &byte, 1);
   1227  1.1  christos 	  ++cmdline;
   1228  1.1  christos 	  ++i;
   1229  1.1  christos 	}
   1230  1.1  christos     }
   1231  1.1  christos   byte = 0;
   1232  1.1  christos   sim_write (sd, cmdline, &byte, 1);
   1233  1.1  christos }
   1234  1.1  christos 
   1235  1.1  christos static void
   1236  1.1  christos bfin_virtual_init (SIM_DESC sd, SIM_CPU *cpu)
   1237  1.1  christos {
   1238  1.1  christos   host_callback *cb = STATE_CALLBACK (sd);
   1239  1.1  christos 
   1240  1.1  christos   cb->stat_map = stat_map_32 = cb_libgloss_stat_map_32;
   1241  1.1  christos   stat_map_64 = NULL;
   1242  1.1  christos }
   1243  1.1  christos 
   1244  1.1  christos SIM_RC
   1245  1.1  christos sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
   1246  1.1  christos 		     char **argv, char **env)
   1247  1.1  christos {
   1248  1.1  christos   SIM_CPU *cpu = STATE_CPU (sd, 0);
   1249  1.1  christos   SIM_ADDR addr;
   1250  1.1  christos 
   1251  1.1  christos   /* Set the PC.  */
   1252  1.1  christos   if (abfd != NULL)
   1253  1.1  christos     addr = bfd_get_start_address (abfd);
   1254  1.1  christos   else
   1255  1.1  christos     addr = 0;
   1256  1.1  christos   sim_pc_set (cpu, addr);
   1257  1.1  christos 
   1258  1.1  christos   /* Standalone mode (i.e. `bfin-...-run`) will take care of the argv
   1259  1.1  christos      for us in sim_open() -> sim_parse_args().  But in debug mode (i.e.
   1260  1.1  christos      'target sim' with `bfin-...-gdb`), we need to handle it.  */
   1261  1.1  christos   if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
   1262  1.1  christos     {
   1263  1.1  christos       freeargv (STATE_PROG_ARGV (sd));
   1264  1.1  christos       STATE_PROG_ARGV (sd) = dupargv (argv);
   1265  1.1  christos     }
   1266  1.1  christos 
   1267  1.1  christos   switch (STATE_ENVIRONMENT (sd))
   1268  1.1  christos     {
   1269  1.1  christos     case USER_ENVIRONMENT:
   1270  1.1  christos       bfin_user_init (sd, cpu, abfd, (void *)argv, (void *)env);
   1271  1.1  christos       break;
   1272  1.1  christos     case OPERATING_ENVIRONMENT:
   1273  1.1  christos       bfin_os_init (sd, cpu, (void *)argv);
   1274  1.1  christos       break;
   1275  1.1  christos     default:
   1276  1.1  christos       bfin_virtual_init (sd, cpu);
   1277  1.1  christos       break;
   1278  1.1  christos     }
   1279  1.1  christos 
   1280  1.1  christos   return SIM_RC_OK;
   1281  1.1  christos }
   1282