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