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