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