]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blob - sim/bfin/interp.c
Update years in copyright notice for the GDB files.
[thirdparty/binutils-gdb.git] / sim / bfin / interp.c
1 /* Simulator for Analog Devices Blackfin processors.
2
3 Copyright (C) 2005-2013 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 }