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