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