1 /* Simulator for Analog Devices Blackfin processors.
3 Copyright (C) 2005-2021 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. */
33 #include "portability.h"
34 #include "sim/callback.h"
35 #include "gdb/signals.h"
37 #include "sim-syscall.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"
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:"
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. */
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
);
108 char _tbuf
[1024 * 3], *tbuf
= _tbuf
, tstr
[1024];
111 CB_SYSCALL_INIT (&sc
);
113 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
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);
126 /* libgloss syscall. */
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);
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
))
144 tbuf
+= sprintf (tbuf
, "exit(%i)", args
[0]);
145 sim_engine_halt (sd
, cpu
, NULL
, PCREG
, sim_exited
, sc
.arg1
);
149 tbuf
+= sprintf (tbuf
, "argc()");
150 sc
.result
= countargv ((char **)argv
);
154 tbuf
+= sprintf (tbuf
, "argnlen(%u)", args
[0]);
155 if (sc
.arg1
< countargv ((char **)argv
))
156 sc
.result
= strlen (argv
[sc
.arg1
]);
163 tbuf
+= sprintf (tbuf
, "argn(%u)", args
[0]);
164 if (sc
.arg1
< countargv ((char **)argv
))
166 const char *argn
= argv
[sc
.arg1
];
167 int len
= strlen (argn
);
168 int written
= sc
.write_mem (cb
, &sc
, sc
.arg2
, argn
, len
+ 1);
169 if (written
== len
+ 1)
180 case CB_SYS_gettimeofday
:
182 struct timeval _tv
, *tv
= &_tv
;
183 struct timezone _tz
, *tz
= &_tz
;
185 tbuf
+= sprintf (tbuf
, "gettimeofday(%#x, %#x)", args
[0], args
[1]);
191 sc
.result
= gettimeofday (tv
, tz
);
200 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
202 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
207 t
= tz
->tz_minuteswest
;
208 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
210 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
219 /* XXX: hack just enough to get basic stdio w/uClibc ... */
220 tbuf
+= sprintf (tbuf
, "ioctl(%i, %#x, %u)", args
[0], args
[1], args
[2]);
221 if (sc
.arg2
== 0x5401)
223 sc
.result
= !isatty (sc
.arg1
);
229 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
235 static bu32 heap
= BFIN_DEFAULT_MEM_SIZE
/ 2;
238 tbuf
+= sprintf (tbuf
, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
239 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
243 if (sc
.arg4
& 0x20 /*MAP_ANONYMOUS*/)
244 /* XXX: We don't handle zeroing, but default is all zeros. */;
245 else if (args
[4] >= MAX_CALLBACK_FDS
)
246 sc
.errcode
= cb_host_to_target_errno (cb
, ENOSYS
);
250 char *data
= xmalloc (sc
.arg2
);
252 /* XXX: Should add a cb->pread. */
253 if (pread (cb
->fdmap
[args
[4]], data
, sc
.arg2
, args
[5] << 12) == sc
.arg2
)
254 sc
.write_mem (cb
, &sc
, heap
, data
, sc
.arg2
);
256 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
260 sc
.errcode
= cb_host_to_target_errno (cb
, ENOSYS
);
272 /* Keep it page aligned. */
273 heap
= align_up (heap
, 4096);
279 /* XXX: meh, just lie for mmap(). */
280 tbuf
+= sprintf (tbuf
, "munmap(%#x, %u)", args
[0], args
[1]);
285 tbuf
+= sprintf (tbuf
, "dup2(%i, %i)", args
[0], args
[1]);
286 if (sc
.arg1
>= MAX_CALLBACK_FDS
|| sc
.arg2
>= MAX_CALLBACK_FDS
)
289 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
293 sc
.result
= dup2 (cb
->fdmap
[sc
.arg1
], cb
->fdmap
[sc
.arg2
]);
299 tbuf
+= sprintf (tbuf
, "llseek(%i, %u, %u, %#x, %u)",
300 args
[0], args
[1], args
[2], args
[3], args
[4]);
301 sc
.func
= TARGET_LINUX_SYS_lseek
;
305 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
311 cb_syscall (cb
, &sc
);
315 sc
.write_mem (cb
, &sc
, args
[3], (void *)&sc
.result
, 4);
316 sc
.write_mem (cb
, &sc
, args
[3] + 4, (void *)&z
, 4);
321 /* XXX: Should add a cb->pread. */
323 tbuf
+= sprintf (tbuf
, "pread(%i, %#x, %u, %i)",
324 args
[0], args
[1], args
[2], args
[3]);
325 if (sc
.arg1
>= MAX_CALLBACK_FDS
)
328 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
332 long old_pos
, read_result
, read_errcode
;
334 /* Get current filepos. */
335 sc
.func
= TARGET_LINUX_SYS_lseek
;
338 cb_syscall (cb
, &sc
);
343 /* Move to the new pos. */
344 sc
.func
= TARGET_LINUX_SYS_lseek
;
347 cb_syscall (cb
, &sc
);
352 sc
.func
= TARGET_LINUX_SYS_read
;
355 cb_syscall (cb
, &sc
);
356 read_result
= sc
.result
;
357 read_errcode
= sc
.errcode
;
359 /* Move back to the old pos. */
360 sc
.func
= TARGET_LINUX_SYS_lseek
;
363 cb_syscall (cb
, &sc
);
365 sc
.result
= read_result
;
366 sc
.errcode
= read_errcode
;
371 tbuf
+= sprintf (tbuf
, "getcwd(%#x, %u)", args
[0], args
[1]);
373 p
= alloca (sc
.arg2
);
374 if (getcwd (p
, sc
.arg2
) == NULL
)
377 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
381 sc
.write_mem (cb
, &sc
, sc
.arg1
, p
, sc
.arg2
);
387 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
388 strcpy (tstr
, "???");
389 tbuf
+= sprintf (tbuf
, "stat64(%#x:\"%s\", %u)", args
[0], tstr
, args
[1]);
390 cb
->stat_map
= stat_map_64
;
391 sc
.func
= TARGET_LINUX_SYS_stat
;
392 cb_syscall (cb
, &sc
);
393 cb
->stat_map
= stat_map_32
;
396 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
397 strcpy (tstr
, "???");
398 tbuf
+= sprintf (tbuf
, "lstat64(%#x:\"%s\", %u)", args
[0], tstr
, args
[1]);
399 cb
->stat_map
= stat_map_64
;
400 sc
.func
= TARGET_LINUX_SYS_lstat
;
401 cb_syscall (cb
, &sc
);
402 cb
->stat_map
= stat_map_32
;
405 tbuf
+= sprintf (tbuf
, "fstat64(%#x, %u)", args
[0], args
[1]);
406 cb
->stat_map
= stat_map_64
;
407 sc
.func
= TARGET_LINUX_SYS_fstat
;
408 cb_syscall (cb
, &sc
);
409 cb
->stat_map
= stat_map_32
;
412 case CB_SYS_ftruncate64
:
413 tbuf
+= sprintf (tbuf
, "ftruncate64(%u, %u)", args
[0], args
[1]);
414 sc
.func
= TARGET_LINUX_SYS_ftruncate
;
415 cb_syscall (cb
, &sc
);
419 case CB_SYS_getuid32
:
420 tbuf
+= sprintf (tbuf
, "getuid()");
421 sc
.result
= getuid ();
424 case CB_SYS_getgid32
:
425 tbuf
+= sprintf (tbuf
, "getgid()");
426 sc
.result
= getgid ();
430 case CB_SYS_setuid32
:
431 tbuf
+= sprintf (tbuf
, "setuid(%u)", args
[0]);
432 sc
.result
= setuid (sc
.arg1
);
436 case CB_SYS_setgid32
:
437 tbuf
+= sprintf (tbuf
, "setgid(%u)", args
[0]);
438 sc
.result
= setgid (sc
.arg1
);
442 tbuf
+= sprintf (tbuf
, "kill(%u, %i)", args
[0], args
[1]);
443 /* Only let the app kill itself. */
444 if (sc
.arg1
!= getpid ())
447 sc
.errcode
= cb_host_to_target_errno (cb
, EPERM
);
452 sc
.result
= kill (sc
.arg1
, sc
.arg2
);
456 sc
.errcode
= cb_host_to_target_errno (cb
, ENOSYS
);
462 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
463 strcpy (tstr
, "???");
464 tbuf
+= sprintf (tbuf
, "open(%#x:\"%s\", %#x, %o)",
465 args
[0], tstr
, args
[1], args
[2]);
468 tbuf
+= sprintf (tbuf
, "close(%i)", args
[0]);
471 tbuf
+= sprintf (tbuf
, "read(%i, %#x, %u)", args
[0], args
[1], args
[2]);
474 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[1]))
475 strcpy (tstr
, "???");
476 tbuf
+= sprintf (tbuf
, "write(%i, %#x:\"%s\", %u)",
477 args
[0], args
[1], tstr
, args
[2]);
480 tbuf
+= sprintf (tbuf
, "lseek(%i, %i, %i)", args
[0], args
[1], args
[2]);
483 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
484 strcpy (tstr
, "???");
485 tbuf
+= sprintf (tbuf
, "unlink(%#x:\"%s\")", args
[0], tstr
);
487 case CB_SYS_truncate
:
488 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
489 strcpy (tstr
, "???");
490 tbuf
+= sprintf (tbuf
, "truncate(%#x:\"%s\", %i)", args
[0], tstr
, args
[1]);
492 case CB_SYS_ftruncate
:
493 tbuf
+= sprintf (tbuf
, "ftruncate(%i, %i)", args
[0], args
[1]);
496 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
497 strcpy (tstr
, "???");
498 tbuf
+= sprintf (tbuf
, "rename(%#x:\"%s\", ", args
[0], tstr
);
499 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[1]))
500 strcpy (tstr
, "???");
501 tbuf
+= sprintf (tbuf
, "%#x:\"%s\")", args
[1], tstr
);
504 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
505 strcpy (tstr
, "???");
506 tbuf
+= sprintf (tbuf
, "stat(%#x:\"%s\", %#x)", args
[0], tstr
, args
[1]);
509 tbuf
+= sprintf (tbuf
, "fstat(%i, %#x)", args
[0], args
[1]);
512 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
513 strcpy (tstr
, "???");
514 tbuf
+= sprintf (tbuf
, "lstat(%#x:\"%s\", %#x)", args
[0], tstr
, args
[1]);
517 tbuf
+= sprintf (tbuf
, "pipe(%#x, %#x)", args
[0], args
[1]);
521 tbuf
+= sprintf (tbuf
, "???_%i(%#x, %#x, %#x, %#x, %#x, %#x)", sc
.func
,
522 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
524 cb_syscall (cb
, &sc
);
530 cb
->last_errno
= errno
;
531 sc
.errcode
= cb
->get_errno (cb
);
535 TRACE_EVENTS (cpu
, "syscall_%i(%#x, %#x, %#x, %#x, %#x, %#x) = %li (error = %i)",
536 sc
.func
, args
[0], args
[1], args
[2], args
[3], args
[4], args
[5],
537 sc
.result
, sc
.errcode
);
539 tbuf
+= sprintf (tbuf
, " = ");
540 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
544 tbuf
+= sprintf (tbuf
, "-1 (error = %i)", sc
.errcode
);
545 if (sc
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
547 sim_io_eprintf (sd
, "bfin-sim: %#x: unimplemented syscall %i\n",
550 SET_DREG (0, -sc
.errcode
);
555 tbuf
+= sprintf (tbuf
, "%#lx", sc
.result
);
557 tbuf
+= sprintf (tbuf
, "%lu", sc
.result
);
558 SET_DREG (0, sc
.result
);
563 tbuf
+= sprintf (tbuf
, "%lu (error = %i)", sc
.result
, sc
.errcode
);
564 SET_DREG (0, sc
.result
);
565 SET_DREG (1, sc
.result2
);
566 SET_DREG (2, sc
.errcode
);
569 TRACE_SYSCALL (cpu
, "%s", _tbuf
);
572 /* Execute a single instruction. */
575 step_once (SIM_CPU
*cpu
)
577 SIM_DESC sd
= CPU_STATE (cpu
);
578 bu32 insn_len
, oldpc
= PCREG
;
582 if (TRACE_ANY_P (cpu
))
583 trace_prefix (sd
, cpu
, NULL_CIA
, oldpc
, TRACE_LINENUM_P (cpu
),
584 NULL
, 0, " "); /* Use a space for gcc warnings. */
586 TRACE_DISASM (cpu
, oldpc
);
588 /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
589 has already had the SSSTEP bit enabled. */
591 if (STATE_ENVIRONMENT (sd
) == OPERATING_ENVIRONMENT
592 && (SYSCFGREG
& SYSCFG_SSSTEP
))
594 int ivg
= cec_get_ivg (cpu
);
595 if (ivg
== -1 || ivg
> 3)
600 /* XXX: Is this what happens on the hardware ? */
601 if (cec_get_ivg (cpu
) == EVT_EMU
)
602 cec_return (cpu
, EVT_EMU
);
605 BFIN_CPU_STATE
.did_jump
= false;
607 insn_len
= interp_insn_bfin (cpu
, oldpc
);
609 /* If we executed this insn successfully, then we always decrement
610 the loop counter. We don't want to update the PC though if the
611 last insn happened to be a change in code flow (jump/etc...). */
612 if (!BFIN_CPU_STATE
.did_jump
)
613 SET_PCREG (hwloop_get_next_pc (cpu
, oldpc
, insn_len
));
614 for (i
= 1; i
>= 0; --i
)
615 if (LCREG (i
) && oldpc
== LBREG (i
))
617 SET_LCREG (i
, LCREG (i
) - 1);
622 ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
));
624 /* Handle hardware single stepping only if we're still lower than EVT3.
625 XXX: May not be entirely correct wrt EXCPT insns. */
628 int ivg
= cec_get_ivg (cpu
);
629 if (ivg
== -1 || ivg
> 3)
632 cec_exception (cpu
, VEC_STEP
);
640 sim_engine_run (SIM_DESC sd
,
641 int next_cpu_nr
, /* ignore */
642 int nr_cpus
, /* ignore */
643 int siggnal
) /* ignore */
648 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
650 cpu
= STATE_CPU (sd
, 0);
655 /* Process any events -- can't use tickn because it may
656 advance right over the next event. */
657 for (ticks
= 0; ticks
< CYCLE_DELAY
; ++ticks
)
658 if (sim_events_tick (sd
))
659 sim_events_process (sd
);
663 /* Cover function of sim_state_free to free the cpu buffers as well. */
666 free_state (SIM_DESC sd
)
668 if (STATE_MODULES (sd
) != NULL
)
669 sim_module_uninstall (sd
);
670 sim_cpu_free_all (sd
);
674 /* Create an instance of the simulator. */
677 bfin_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
679 memset (&cpu
->state
, 0, sizeof (cpu
->state
));
681 PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
)) = 0;
683 bfin_model_cpu_init (sd
, cpu
);
685 /* Set default stack to top of scratch pad. */
686 SET_SPREG (BFIN_DEFAULT_MEM_SIZE
);
687 SET_KSPREG (BFIN_DEFAULT_MEM_SIZE
);
688 SET_USPREG (BFIN_DEFAULT_MEM_SIZE
);
690 /* This is what the hardware likes. */
691 SET_SYSCFGREG (0x30);
695 sim_open (SIM_OPEN_KIND kind
, host_callback
*callback
,
696 struct bfd
*abfd
, char * const *argv
)
700 SIM_DESC sd
= sim_state_alloc_extra (kind
, callback
,
701 sizeof (struct bfin_board_data
));
703 /* Set default options before parsing user options. */
704 STATE_MACHS (sd
) = bfin_sim_machs
;
705 STATE_MODEL_NAME (sd
) = "bf537";
706 current_alignment
= STRICT_ALIGNMENT
;
707 current_target_byte_order
= BFD_ENDIAN_LITTLE
;
709 /* The cpu data is kept in a separately allocated chunk of memory. */
710 if (sim_cpu_alloc_all (sd
, 1) != SIM_RC_OK
)
716 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
722 /* XXX: Default to the Virtual environment. */
723 if (STATE_ENVIRONMENT (sd
) == ALL_ENVIRONMENT
)
724 STATE_ENVIRONMENT (sd
) = VIRTUAL_ENVIRONMENT
;
726 /* The parser will print an error message for us, so we silently return. */
727 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
733 /* Allocate external memory if none specified by user.
734 Use address 4 here in case the user wanted address 0 unmapped. */
735 if (sim_core_read_buffer (sd
, NULL
, read_map
, &c
, 4, 1) == 0)
737 bu16 emuexcpt
= 0x25;
738 sim_do_commandf (sd
, "memory-size 0x%x", BFIN_DEFAULT_MEM_SIZE
);
739 sim_write (sd
, 0, (void *)&emuexcpt
, 2);
742 /* Check for/establish the a reference program image. */
743 if (sim_analyze_program (sd
, STATE_PROG_FILE (sd
), abfd
) != SIM_RC_OK
)
749 /* Establish any remaining configuration options. */
750 if (sim_config (sd
) != SIM_RC_OK
)
756 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
762 /* CPU specific initialization. */
763 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
765 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
766 bfin_initialize_cpu (sd
, cpu
);
772 /* Some utils don't like having a NULL environ. */
773 static char * const simple_env
[] = { "HOME=/", "PATH=/bin", NULL
};
775 static bu32 fdpic_load_offset
;
778 bfin_fdpic_load (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
, bu32
*sp
,
779 bu32
*elf_addrs
, char **ldso_path
)
784 Elf_Internal_Ehdr
*iehdr
;
785 Elf32_External_Ehdr ehdr
;
786 Elf_Internal_Phdr
*phdrs
;
794 unsigned char null
[4] = { 0, 0, 0, 0 };
799 /* See if this an FDPIC ELF. */
802 goto skip_fdpic_init
;
803 if (bfd_seek (abfd
, 0, SEEK_SET
) != 0)
804 goto skip_fdpic_init
;
805 if (bfd_bread (&ehdr
, sizeof (ehdr
), abfd
) != sizeof (ehdr
))
806 goto skip_fdpic_init
;
807 iehdr
= elf_elfheader (abfd
);
808 if (!(iehdr
->e_flags
& EF_BFIN_FDPIC
))
809 goto skip_fdpic_init
;
811 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
812 sim_io_printf (sd
, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
813 bfd_get_filename (abfd
), fdpic_load_offset
, elf_addrs
[0]);
815 /* Grab the Program Headers to set up the loadsegs on the stack. */
816 phdr_size
= bfd_get_elf_phdr_upper_bound (abfd
);
818 goto skip_fdpic_init
;
819 phdrs
= xmalloc (phdr_size
);
820 phdrc
= bfd_get_elf_phdrs (abfd
, phdrs
);
822 goto skip_fdpic_init
;
824 /* Push the Ehdr onto the stack. */
825 *sp
-= sizeof (ehdr
);
827 sim_write (sd
, *sp
, (void *)&ehdr
, sizeof (ehdr
));
828 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
829 sim_io_printf (sd
, " Elf_Ehdr: %#x\n", *sp
);
831 /* Since we're relocating things ourselves, we need to relocate
832 the start address as well. */
833 elf_addrs
[0] = bfd_get_start_address (abfd
) + fdpic_load_offset
;
835 /* And the Exec's Phdrs onto the stack. */
836 if (STATE_PROG_BFD (sd
) == abfd
)
838 elf_addrs
[4] = elf_addrs
[0];
840 phdr_size
= iehdr
->e_phentsize
* iehdr
->e_phnum
;
841 if (bfd_seek (abfd
, iehdr
->e_phoff
, SEEK_SET
) != 0)
842 goto skip_fdpic_init
;
843 data
= xmalloc (phdr_size
);
844 if (bfd_bread (data
, phdr_size
, abfd
) != phdr_size
)
845 goto skip_fdpic_init
;
848 elf_addrs
[2] = phdrc
;
849 sim_write (sd
, *sp
, data
, phdr_size
);
851 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
852 sim_io_printf (sd
, " Elf_Phdrs: %#x\n", *sp
);
855 /* Now push all the loadsegs. */
858 for (i
= phdrc
; i
>= 0; --i
)
859 if (phdrs
[i
].p_type
== PT_LOAD
)
861 Elf_Internal_Phdr
*p
= &phdrs
[i
];
862 bu32 paddr
, vaddr
, memsz
, filesz
;
864 paddr
= p
->p_paddr
+ fdpic_load_offset
;
867 filesz
= p
->p_filesz
;
869 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
870 sim_io_printf (sd
, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
871 i
, vaddr
, paddr
, filesz
, memsz
);
873 data
= xmalloc (memsz
);
875 memset (data
+ filesz
, 0, memsz
- filesz
);
877 if (bfd_seek (abfd
, p
->p_offset
, SEEK_SET
) == 0
878 && bfd_bread (data
, filesz
, abfd
) == filesz
)
879 sim_write (sd
, paddr
, data
, memsz
);
883 max_load_addr
= max (paddr
+ memsz
, max_load_addr
);
886 sim_write (sd
, *sp
+0, (void *)&paddr
, 4); /* loadseg.addr */
887 sim_write (sd
, *sp
+4, (void *)&vaddr
, 4); /* loadseg.p_vaddr */
888 sim_write (sd
, *sp
+8, (void *)&memsz
, 4); /* loadseg.p_memsz */
891 else if (phdrs
[i
].p_type
== PT_DYNAMIC
)
893 elf_addrs
[5] = phdrs
[i
].p_paddr
+ fdpic_load_offset
;
894 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
895 sim_io_printf (sd
, " PT_DYNAMIC: %#x\n", elf_addrs
[5]);
897 else if (phdrs
[i
].p_type
== PT_INTERP
)
899 uint32_t off
= phdrs
[i
].p_offset
;
900 uint32_t len
= phdrs
[i
].p_filesz
;
902 *ldso_path
= xmalloc (len
);
903 if (bfd_seek (abfd
, off
, SEEK_SET
) != 0
904 || bfd_bread (*ldso_path
, len
, abfd
) != len
)
909 else if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
910 sim_io_printf (sd
, " PT_INTERP: %s\n", *ldso_path
);
913 /* Update the load offset with a few extra pages. */
914 fdpic_load_offset
= align_up (max (max_load_addr
, fdpic_load_offset
),
916 fdpic_load_offset
+= 0x10000;
918 /* Push the summary loadmap info onto the stack last. */
920 sim_write (sd
, *sp
+0, null
, 2); /* loadmap.version */
921 sim_write (sd
, *sp
+2, (void *)&nsegs
, 2); /* loadmap.nsegs */
931 bfin_user_init (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
,
932 char * const *argv
, char * const *env
)
934 /* XXX: Missing host -> target endian ... */
935 /* Linux starts the user app with the stack:
937 argv[0] -- pointers to the actual strings
943 auxvt[0].type -- ELF Auxiliary Vector Table
948 argv[0..N][0..M] -- actual argv/env strings
950 FDPIC loadmaps -- for FDPIC apps
951 So set things up the same way. */
953 bu32 argv_flat
, env_flat
;
957 /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
960 bu32 exec_loadmap
, ldso_loadmap
;
963 unsigned char null
[4] = { 0, 0, 0, 0 };
965 host_callback
*cb
= STATE_CALLBACK (sd
);
967 elf_addrs
[0] = elf_addrs
[4] = bfd_get_start_address (abfd
);
968 elf_addrs
[1] = elf_addrs
[2] = elf_addrs
[3] = elf_addrs
[5] = 0;
970 /* Keep the load addresses consistent between runs. Also make sure we make
971 space for the fixed code region (part of the Blackfin Linux ABI). */
972 fdpic_load_offset
= 0x1000;
974 /* First try to load this as an FDPIC executable. */
976 if (!bfin_fdpic_load (sd
, cpu
, STATE_PROG_BFD (sd
), &sp
, elf_addrs
, &ldso_path
))
977 goto skip_fdpic_init
;
980 /* If that worked, then load the fixed code region. We only do this for
981 FDPIC ELFs atm because they are PIEs and let us relocate them without
982 manual fixups. FLAT files however require location processing which
983 we do not do ourselves, and they link with a VMA of 0. */
984 sim_write (sd
, 0x400, bfin_linux_fixed_code
, sizeof (bfin_linux_fixed_code
));
986 /* If the FDPIC needs an interpreter, then load it up too. */
989 const char *ldso_full_path
= concat (simulator_sysroot
, ldso_path
, NULL
);
990 struct bfd
*ldso_bfd
;
992 ldso_bfd
= bfd_openr (ldso_full_path
, STATE_TARGET (sd
));
995 sim_io_eprintf (sd
, "bfin-sim: bfd open failed: %s\n", ldso_full_path
);
998 if (!bfd_check_format (ldso_bfd
, bfd_object
))
999 sim_io_eprintf (sd
, "bfin-sim: bfd format not valid: %s\n", ldso_full_path
);
1000 bfd_set_arch_info (ldso_bfd
, STATE_ARCHITECTURE (sd
));
1002 if (!bfin_fdpic_load (sd
, cpu
, ldso_bfd
, &sp
, elf_addrs
, &ldso_path
))
1003 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path
);
1005 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
1006 ldso_full_path
, ldso_path
);
1014 /* Finally setup the registers required by the FDPIC ABI. */
1015 SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up. */
1016 SET_PREG (0, exec_loadmap
); /* Exec loadmap addr. */
1017 SET_PREG (1, ldso_loadmap
); /* Interp loadmap addr. */
1018 SET_PREG (2, elf_addrs
[5]); /* PT_DYNAMIC map addr. */
1023 sim_pc_set (cpu
, elf_addrs
[0]);
1025 /* Figure out how much storage the argv/env strings need. */
1026 argc
= countargv ((char **)argv
);
1029 argv_flat
= argc
; /* NUL bytes */
1030 for (i
= 0; i
< argc
; ++i
)
1031 argv_flat
+= strlen (argv
[i
]);
1035 envc
= countargv ((char **)env
);
1036 env_flat
= envc
; /* NUL bytes */
1037 for (i
= 0; i
< envc
; ++i
)
1038 env_flat
+= strlen (env
[i
]);
1040 /* Push the Auxiliary Vector Table between argv/env and actual strings. */
1041 sp_flat
= sp
= align_up (SPREG
- argv_flat
- env_flat
- 4, 4);
1044 # define AT_PUSH(at, val) \
1048 sim_write (sd, sp, (void *)&auxvt, 4); \
1051 sim_write (sd, sp, (void *)&auxvt, 4)
1052 unsigned int egid
= getegid (), gid
= getgid ();
1053 unsigned int euid
= geteuid (), uid
= getuid ();
1054 bu32 auxvt_size
= 0;
1055 AT_PUSH (AT_NULL
, 0);
1056 AT_PUSH (AT_SECURE
, egid
!= gid
|| euid
!= uid
);
1057 AT_PUSH (AT_EGID
, egid
);
1058 AT_PUSH (AT_GID
, gid
);
1059 AT_PUSH (AT_EUID
, euid
);
1060 AT_PUSH (AT_UID
, uid
);
1061 AT_PUSH (AT_ENTRY
, elf_addrs
[4]);
1062 AT_PUSH (AT_FLAGS
, 0);
1063 AT_PUSH (AT_BASE
, elf_addrs
[3]);
1064 AT_PUSH (AT_PHNUM
, elf_addrs
[2]);
1065 AT_PUSH (AT_PHENT
, sizeof (Elf32_External_Phdr
));
1066 AT_PUSH (AT_PHDR
, elf_addrs
[1]);
1067 AT_PUSH (AT_CLKTCK
, 100); /* XXX: This ever not 100 ? */
1068 AT_PUSH (AT_PAGESZ
, 4096);
1069 AT_PUSH (AT_HWCAP
, 0);
1074 /* Push the argc/argv/env after the auxvt. */
1075 sp
-= ((1 + argc
+ 1 + envc
+ 1) * 4);
1078 /* First push the argc value. */
1079 sim_write (sd
, sp
, (void *)&argc
, 4);
1082 /* Then the actual argv strings so we know where to point argv[]. */
1083 for (i
= 0; i
< argc
; ++i
)
1085 unsigned len
= strlen (argv
[i
]) + 1;
1086 sim_write (sd
, sp_flat
, (void *)argv
[i
], len
);
1087 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1091 sim_write (sd
, sp
, null
, 4);
1094 /* Then the actual env strings so we know where to point env[]. */
1095 for (i
= 0; i
< envc
; ++i
)
1097 unsigned len
= strlen (env
[i
]) + 1;
1098 sim_write (sd
, sp_flat
, (void *)env
[i
], len
);
1099 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1104 /* Set some callbacks. */
1105 cb
->syscall_map
= cb_linux_syscall_map
;
1106 cb
->errno_map
= cb_linux_errno_map
;
1107 cb
->open_map
= cb_linux_open_map
;
1108 cb
->signal_map
= cb_linux_signal_map
;
1109 cb
->stat_map
= stat_map_32
= cb_linux_stat_map_32
;
1110 stat_map_64
= cb_linux_stat_map_64
;
1114 bfin_os_init (SIM_DESC sd
, SIM_CPU
*cpu
, char * const *argv
)
1116 /* Pass the command line via a string in R0 like Linux expects. */
1119 bu32 cmdline
= BFIN_L1_SRAM_SCRATCH
;
1121 SET_DREG (0, cmdline
);
1122 if (argv
&& argv
[0])
1128 bu32 len
= strlen (argv
[i
]);
1129 sim_write (sd
, cmdline
, (void *)argv
[i
], len
);
1131 sim_write (sd
, cmdline
, &byte
, 1);
1137 sim_write (sd
, cmdline
, &byte
, 1);
1141 bfin_virtual_init (SIM_DESC sd
, SIM_CPU
*cpu
)
1143 host_callback
*cb
= STATE_CALLBACK (sd
);
1145 cb
->stat_map
= stat_map_32
= cb_libgloss_stat_map_32
;
1150 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
1151 char * const *argv
, char * const *env
)
1153 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
1158 addr
= bfd_get_start_address (abfd
);
1161 sim_pc_set (cpu
, addr
);
1163 /* Standalone mode (i.e. `run`) will take care of the argv for us in
1164 sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim'
1165 with `gdb`), we need to handle it because the user can change the
1166 argv on the fly via gdb's 'run'. */
1167 if (STATE_PROG_ARGV (sd
) != argv
)
1169 freeargv (STATE_PROG_ARGV (sd
));
1170 STATE_PROG_ARGV (sd
) = dupargv (argv
);
1173 switch (STATE_ENVIRONMENT (sd
))
1175 case USER_ENVIRONMENT
:
1176 bfin_user_init (sd
, cpu
, abfd
, argv
, env
);
1178 case OPERATING_ENVIRONMENT
:
1179 bfin_os_init (sd
, cpu
, argv
);
1182 bfin_virtual_init (sd
, cpu
);