1 /* Simulator for Analog Devices Blackfin processors.
3 Copyright (C) 2005-2024 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-options.h"
38 #include "sim-syscall.h"
43 /* The numbers here do not matter. They just need to be unique. They also
44 need not be static across releases -- they're used internally only. The
45 mapping from the Linux ABI to the CB values is in linux-targ-map.h. */
46 #define CB_SYS_ioctl 201
47 #define CB_SYS_mmap2 202
48 #define CB_SYS_munmap 203
49 #define CB_SYS_dup2 204
50 #define CB_SYS_getuid 205
51 #define CB_SYS_getuid32 206
52 #define CB_SYS_getgid 207
53 #define CB_SYS_getgid32 208
54 #define CB_SYS_setuid 209
55 #define CB_SYS_setuid32 210
56 #define CB_SYS_setgid 211
57 #define CB_SYS_setgid32 212
58 #define CB_SYS_pread 213
59 #define CB_SYS__llseek 214
60 #define CB_SYS_getcwd 215
61 #define CB_SYS_stat64 216
62 #define CB_SYS_lstat64 217
63 #define CB_SYS_fstat64 218
64 #define CB_SYS_ftruncate64 219
65 #define CB_SYS_gettimeofday 220
66 #define CB_SYS_access 221
67 #include "linux-targ-map.h"
68 #include "linux-fixed-code.h"
70 #include "elf/common.h"
71 #include "elf/external.h"
72 #include "elf/internal.h"
74 #include "bfd/elf-bfd.h"
76 #include "dv-bfin_cec.h"
77 #include "dv-bfin_mmu.h"
79 static const char cb_linux_stat_map_32
[] =
80 /* Linux kernel 32bit layout: */
81 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
82 "space,2:st_size,4:st_blksize,4:st_blocks,4:st_atime,4:st_atimensec,4:"
83 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:space,4";
84 /* uClibc public ABI 32bit layout:
85 "st_dev,8:space,2:space,2:st_ino,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:"
86 "st_rdev,8:space,2:space,2:st_size,4:st_blksiez,4:st_blocks,4:st_atime,4:"
87 "st_atimensec,4:st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:"
89 static const char cb_linux_stat_map_64
[] =
90 "st_dev,8:space,4:space,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:st_rdev,8:"
91 "space,4:st_size,8:st_blksize,4:st_blocks,8:st_atime,4:st_atimensec,4:"
92 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:st_ino,8";
93 static const char cb_libgloss_stat_map_32
[] =
94 "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
95 "st_size,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:"
96 "space,4:st_blksize,4:st_blocks,4:space,8";
97 static const char *stat_map_32
, *stat_map_64
;
99 /* Simulate a monitor trap, put the result into r0 and errno into r1
100 return offset by which to adjust pc. */
103 bfin_syscall (SIM_CPU
*cpu
)
105 SIM_DESC sd
= CPU_STATE (cpu
);
106 host_callback
*cb
= STATE_CALLBACK (sd
);
110 char _tbuf
[1024 * 3], *tbuf
= _tbuf
, tstr
[1024];
113 CB_SYSCALL_INIT (&sc
);
115 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
119 sc
.arg1
= args
[0] = DREG (0);
120 sc
.arg2
= args
[1] = DREG (1);
121 sc
.arg3
= args
[2] = DREG (2);
122 sc
.arg4
= args
[3] = DREG (3);
123 sc
.arg5
= args
[4] = DREG (4);
124 sc
.arg6
= args
[5] = DREG (5);
128 /* libgloss syscall. */
130 sc
.arg1
= args
[0] = GET_LONG (DREG (0));
131 sc
.arg2
= args
[1] = GET_LONG (DREG (0) + 4);
132 sc
.arg3
= args
[2] = GET_LONG (DREG (0) + 8);
133 sc
.arg4
= args
[3] = GET_LONG (DREG (0) + 12);
134 sc
.arg5
= args
[4] = GET_LONG (DREG (0) + 16);
135 sc
.arg6
= args
[5] = GET_LONG (DREG (0) + 20);
139 sc
.read_mem
= sim_syscall_read_mem
;
140 sc
.write_mem
= sim_syscall_write_mem
;
142 /* Common cb_syscall() handles most functions. */
143 switch (cb_target_to_host_syscall (cb
, sc
.func
))
146 tbuf
+= sprintf (tbuf
, "exit(%i)", args
[0]);
147 sim_engine_halt (sd
, cpu
, NULL
, PCREG
, sim_exited
, sc
.arg1
);
149 case CB_SYS_gettimeofday
:
151 struct timeval _tv
, *tv
= &_tv
;
152 struct timezone _tz
, *tz
= &_tz
;
154 tbuf
+= sprintf (tbuf
, "gettimeofday(%#x, %#x)", args
[0], args
[1]);
160 sc
.result
= gettimeofday (tv
, tz
);
169 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
171 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
176 t
= tz
->tz_minuteswest
;
177 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
179 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
188 /* XXX: hack just enough to get basic stdio w/uClibc ... */
189 tbuf
+= sprintf (tbuf
, "ioctl(%i, %#x, %u)", args
[0], args
[1], args
[2]);
190 if (sc
.arg2
== 0x5401)
192 sc
.result
= !isatty (sc
.arg1
);
198 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
204 static bu32 heap
= BFIN_DEFAULT_MEM_SIZE
/ 2;
207 tbuf
+= sprintf (tbuf
, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
208 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
212 if (sc
.arg4
& 0x20 /*MAP_ANONYMOUS*/)
213 /* XXX: We don't handle zeroing, but default is all zeros. */;
214 else if (args
[4] >= MAX_CALLBACK_FDS
)
215 sc
.errcode
= cb_host_to_target_errno (cb
, ENOSYS
);
219 char *data
= xmalloc (sc
.arg2
);
221 /* XXX: Should add a cb->pread. */
222 if (pread (cb
->fdmap
[args
[4]], data
, sc
.arg2
, args
[5] << 12) == sc
.arg2
)
223 sc
.write_mem (cb
, &sc
, heap
, data
, sc
.arg2
);
225 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
229 sc
.errcode
= cb_host_to_target_errno (cb
, ENOSYS
);
241 /* Keep it page aligned. */
242 heap
= align_up (heap
, 4096);
248 /* XXX: meh, just lie for mmap(). */
249 tbuf
+= sprintf (tbuf
, "munmap(%#x, %u)", args
[0], args
[1]);
254 tbuf
+= sprintf (tbuf
, "dup2(%i, %i)", args
[0], args
[1]);
255 if (sc
.arg1
>= MAX_CALLBACK_FDS
|| sc
.arg2
>= MAX_CALLBACK_FDS
)
258 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
262 sc
.result
= dup2 (cb
->fdmap
[sc
.arg1
], cb
->fdmap
[sc
.arg2
]);
268 tbuf
+= sprintf (tbuf
, "llseek(%i, %u, %u, %#x, %u)",
269 args
[0], args
[1], args
[2], args
[3], args
[4]);
270 sc
.func
= TARGET_LINUX_SYS_lseek
;
274 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
280 cb_syscall (cb
, &sc
);
284 sc
.write_mem (cb
, &sc
, args
[3], (void *)&sc
.result
, 4);
285 sc
.write_mem (cb
, &sc
, args
[3] + 4, (void *)&z
, 4);
290 /* XXX: Should add a cb->pread. */
292 tbuf
+= sprintf (tbuf
, "pread(%i, %#x, %u, %i)",
293 args
[0], args
[1], args
[2], args
[3]);
294 if (sc
.arg1
>= MAX_CALLBACK_FDS
)
297 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
301 long old_pos
, read_result
, read_errcode
;
303 /* Get current filepos. */
304 sc
.func
= TARGET_LINUX_SYS_lseek
;
307 cb_syscall (cb
, &sc
);
312 /* Move to the new pos. */
313 sc
.func
= TARGET_LINUX_SYS_lseek
;
316 cb_syscall (cb
, &sc
);
321 sc
.func
= TARGET_LINUX_SYS_read
;
324 cb_syscall (cb
, &sc
);
325 read_result
= sc
.result
;
326 read_errcode
= sc
.errcode
;
328 /* Move back to the old pos. */
329 sc
.func
= TARGET_LINUX_SYS_lseek
;
332 cb_syscall (cb
, &sc
);
334 sc
.result
= read_result
;
335 sc
.errcode
= read_errcode
;
340 tbuf
+= sprintf (tbuf
, "getcwd(%#x, %u)", args
[0], args
[1]);
342 p
= alloca (sc
.arg2
);
343 if (getcwd (p
, sc
.arg2
) == NULL
)
346 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
350 sc
.write_mem (cb
, &sc
, sc
.arg1
, p
, sc
.arg2
);
356 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
357 strcpy (tstr
, "???");
358 tbuf
+= sprintf (tbuf
, "stat64(%#x:\"%s\", %u)", args
[0], tstr
, args
[1]);
359 cb
->stat_map
= stat_map_64
;
360 sc
.func
= TARGET_LINUX_SYS_stat
;
361 cb_syscall (cb
, &sc
);
362 cb
->stat_map
= stat_map_32
;
365 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
366 strcpy (tstr
, "???");
367 tbuf
+= sprintf (tbuf
, "lstat64(%#x:\"%s\", %u)", args
[0], tstr
, args
[1]);
368 cb
->stat_map
= stat_map_64
;
369 sc
.func
= TARGET_LINUX_SYS_lstat
;
370 cb_syscall (cb
, &sc
);
371 cb
->stat_map
= stat_map_32
;
374 tbuf
+= sprintf (tbuf
, "fstat64(%#x, %u)", args
[0], args
[1]);
375 cb
->stat_map
= stat_map_64
;
376 sc
.func
= TARGET_LINUX_SYS_fstat
;
377 cb_syscall (cb
, &sc
);
378 cb
->stat_map
= stat_map_32
;
381 case CB_SYS_ftruncate64
:
382 tbuf
+= sprintf (tbuf
, "ftruncate64(%u, %u)", args
[0], args
[1]);
383 sc
.func
= TARGET_LINUX_SYS_ftruncate
;
384 cb_syscall (cb
, &sc
);
388 case CB_SYS_getuid32
:
389 tbuf
+= sprintf (tbuf
, "getuid()");
390 sc
.result
= getuid ();
393 case CB_SYS_getgid32
:
394 tbuf
+= sprintf (tbuf
, "getgid()");
395 sc
.result
= getgid ();
399 ATTRIBUTE_FALLTHROUGH
;
400 case CB_SYS_setuid32
:
401 tbuf
+= sprintf (tbuf
, "setuid(%u)", args
[0]);
402 sc
.result
= setuid (sc
.arg1
);
406 ATTRIBUTE_FALLTHROUGH
;
407 case CB_SYS_setgid32
:
408 tbuf
+= sprintf (tbuf
, "setgid(%u)", args
[0]);
409 sc
.result
= setgid (sc
.arg1
);
413 tbuf
+= sprintf (tbuf
, "kill(%u, %i)", args
[0], args
[1]);
414 /* Only let the app kill itself. */
415 if (sc
.arg1
!= getpid ())
418 sc
.errcode
= cb_host_to_target_errno (cb
, EPERM
);
423 sc
.result
= kill (sc
.arg1
, sc
.arg2
);
427 sc
.errcode
= cb_host_to_target_errno (cb
, ENOSYS
);
433 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
434 strcpy (tstr
, "???");
435 tbuf
+= sprintf (tbuf
, "open(%#x:\"%s\", %#x, %o)",
436 args
[0], tstr
, args
[1], args
[2]);
439 tbuf
+= sprintf (tbuf
, "close(%i)", args
[0]);
442 tbuf
+= sprintf (tbuf
, "read(%i, %#x, %u)", args
[0], args
[1], args
[2]);
445 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[1]))
446 strcpy (tstr
, "???");
447 tbuf
+= sprintf (tbuf
, "write(%i, %#x:\"%s\", %u)",
448 args
[0], args
[1], tstr
, args
[2]);
451 tbuf
+= sprintf (tbuf
, "lseek(%i, %i, %i)", args
[0], args
[1], args
[2]);
454 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
455 strcpy (tstr
, "???");
456 tbuf
+= sprintf (tbuf
, "unlink(%#x:\"%s\")", args
[0], tstr
);
458 case CB_SYS_truncate
:
459 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
460 strcpy (tstr
, "???");
461 tbuf
+= sprintf (tbuf
, "truncate(%#x:\"%s\", %i)", args
[0], tstr
, args
[1]);
463 case CB_SYS_ftruncate
:
464 tbuf
+= sprintf (tbuf
, "ftruncate(%i, %i)", args
[0], args
[1]);
467 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
468 strcpy (tstr
, "???");
469 tbuf
+= sprintf (tbuf
, "rename(%#x:\"%s\", ", args
[0], tstr
);
470 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[1]))
471 strcpy (tstr
, "???");
472 tbuf
+= sprintf (tbuf
, "%#x:\"%s\")", args
[1], tstr
);
475 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
476 strcpy (tstr
, "???");
477 tbuf
+= sprintf (tbuf
, "stat(%#x:\"%s\", %#x)", args
[0], tstr
, args
[1]);
480 tbuf
+= sprintf (tbuf
, "fstat(%i, %#x)", args
[0], args
[1]);
483 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
484 strcpy (tstr
, "???");
485 tbuf
+= sprintf (tbuf
, "lstat(%#x:\"%s\", %#x)", args
[0], tstr
, args
[1]);
488 tbuf
+= sprintf (tbuf
, "pipe(%#x, %#x)", args
[0], args
[1]);
492 tbuf
+= sprintf (tbuf
, "???_%i(%#x, %#x, %#x, %#x, %#x, %#x)", sc
.func
,
493 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
495 cb_syscall (cb
, &sc
);
501 cb
->last_errno
= errno
;
502 sc
.errcode
= cb
->get_errno (cb
);
506 TRACE_EVENTS (cpu
, "syscall_%i(%#x, %#x, %#x, %#x, %#x, %#x) = %li (error = %i)",
507 sc
.func
, args
[0], args
[1], args
[2], args
[3], args
[4], args
[5],
508 sc
.result
, sc
.errcode
);
510 tbuf
+= sprintf (tbuf
, " = ");
511 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
515 tbuf
+= sprintf (tbuf
, "-1 (error = %i)", sc
.errcode
);
516 if (sc
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
518 sim_io_eprintf (sd
, "bfin-sim: %#x: unimplemented syscall %i\n",
521 SET_DREG (0, -sc
.errcode
);
526 tbuf
+= sprintf (tbuf
, "%#lx", sc
.result
);
528 tbuf
+= sprintf (tbuf
, "%lu", sc
.result
);
529 SET_DREG (0, sc
.result
);
534 tbuf
+= sprintf (tbuf
, "%lu (error = %i)", sc
.result
, sc
.errcode
);
535 SET_DREG (0, sc
.result
);
536 SET_DREG (1, sc
.result2
);
537 SET_DREG (2, sc
.errcode
);
540 TRACE_SYSCALL (cpu
, "%s", _tbuf
);
543 /* Execute a single instruction. */
546 step_once (SIM_CPU
*cpu
)
548 SIM_DESC sd
= CPU_STATE (cpu
);
549 bu32 insn_len
, oldpc
= PCREG
;
553 if (TRACE_ANY_P (cpu
))
554 trace_prefix (sd
, cpu
, NULL_CIA
, oldpc
, TRACE_LINENUM_P (cpu
),
555 NULL
, 0, " "); /* Use a space for gcc warnings. */
557 TRACE_DISASM (cpu
, oldpc
);
559 /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
560 has already had the SSSTEP bit enabled. */
562 if (STATE_ENVIRONMENT (sd
) == OPERATING_ENVIRONMENT
563 && (SYSCFGREG
& SYSCFG_SSSTEP
))
565 int ivg
= cec_get_ivg (cpu
);
566 if (ivg
== -1 || ivg
> 3)
571 /* XXX: Is this what happens on the hardware ? */
572 if (cec_get_ivg (cpu
) == EVT_EMU
)
573 cec_return (cpu
, EVT_EMU
);
576 BFIN_CPU_STATE
.did_jump
= false;
578 insn_len
= interp_insn_bfin (cpu
, oldpc
);
580 /* If we executed this insn successfully, then we always decrement
581 the loop counter. We don't want to update the PC though if the
582 last insn happened to be a change in code flow (jump/etc...). */
583 if (!BFIN_CPU_STATE
.did_jump
)
584 SET_PCREG (hwloop_get_next_pc (cpu
, oldpc
, insn_len
));
585 for (i
= 1; i
>= 0; --i
)
586 if (LCREG (i
) && oldpc
== LBREG (i
))
588 SET_LCREG (i
, LCREG (i
) - 1);
593 ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
));
595 /* Handle hardware single stepping only if we're still lower than EVT3.
596 XXX: May not be entirely correct wrt EXCPT insns. */
599 int ivg
= cec_get_ivg (cpu
);
600 if (ivg
== -1 || ivg
> 3)
603 cec_exception (cpu
, VEC_STEP
);
611 sim_engine_run (SIM_DESC sd
,
612 int next_cpu_nr
, /* ignore */
613 int nr_cpus
, /* ignore */
614 int siggnal
) /* ignore */
619 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
621 cpu
= STATE_CPU (sd
, 0);
626 /* Process any events -- can't use tickn because it may
627 advance right over the next event. */
628 for (ticks
= 0; ticks
< CYCLE_DELAY
; ++ticks
)
629 if (sim_events_tick (sd
))
630 sim_events_process (sd
);
634 /* Cover function of sim_state_free to free the cpu buffers as well. */
637 free_state (SIM_DESC sd
)
639 if (STATE_MODULES (sd
) != NULL
)
640 sim_module_uninstall (sd
);
641 sim_cpu_free_all (sd
);
645 /* Create an instance of the simulator. */
648 bfin_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
650 PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
)) = 0;
652 bfin_model_cpu_init (sd
, cpu
);
654 /* Set default stack to top of scratch pad. */
655 SET_SPREG (BFIN_DEFAULT_MEM_SIZE
);
656 SET_KSPREG (BFIN_DEFAULT_MEM_SIZE
);
657 SET_USPREG (BFIN_DEFAULT_MEM_SIZE
);
659 /* This is what the hardware likes. */
660 SET_SYSCFGREG (0x30);
664 sim_open (SIM_OPEN_KIND kind
, host_callback
*callback
,
665 struct bfd
*abfd
, char * const *argv
)
669 SIM_DESC sd
= sim_state_alloc_extra (kind
, callback
,
670 sizeof (struct bfin_board_data
));
672 /* Set default options before parsing user options. */
673 STATE_MACHS (sd
) = bfin_sim_machs
;
674 STATE_MODEL_NAME (sd
) = "bf537";
675 current_alignment
= STRICT_ALIGNMENT
;
676 current_target_byte_order
= BFD_ENDIAN_LITTLE
;
678 /* The cpu data is kept in a separately allocated chunk of memory. */
679 if (sim_cpu_alloc_all_extra (sd
, 0, sizeof (struct bfin_cpu_state
))
686 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
692 /* XXX: Default to the Virtual environment. */
693 if (STATE_ENVIRONMENT (sd
) == ALL_ENVIRONMENT
)
694 STATE_ENVIRONMENT (sd
) = VIRTUAL_ENVIRONMENT
;
696 /* The parser will print an error message for us, so we silently return. */
697 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
703 /* Allocate external memory if none specified by user.
704 Use address 4 here in case the user wanted address 0 unmapped. */
705 if (sim_core_read_buffer (sd
, NULL
, read_map
, &c
, 4, 1) == 0)
707 bu16 emuexcpt
= 0x25;
708 sim_do_commandf (sd
, "memory-size 0x%x", BFIN_DEFAULT_MEM_SIZE
);
709 sim_write (sd
, 0, &emuexcpt
, 2);
712 /* Check for/establish the a reference program image. */
713 if (sim_analyze_program (sd
, STATE_PROG_FILE (sd
), abfd
) != SIM_RC_OK
)
719 /* Establish any remaining configuration options. */
720 if (sim_config (sd
) != SIM_RC_OK
)
726 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
732 /* CPU specific initialization. */
733 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
735 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
736 bfin_initialize_cpu (sd
, cpu
);
742 /* Some utils don't like having a NULL environ. */
743 static char * const simple_env
[] = { "HOME=/", "PATH=/bin", NULL
};
745 static bu32 fdpic_load_offset
;
748 bfin_fdpic_load (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
, bu32
*sp
,
749 bu32
*elf_addrs
, char **ldso_path
)
754 Elf_Internal_Ehdr
*iehdr
;
755 Elf32_External_Ehdr ehdr
;
756 Elf_Internal_Phdr
*phdrs
;
764 unsigned char null
[4] = { 0, 0, 0, 0 };
769 /* See if this an FDPIC ELF. */
772 goto skip_fdpic_init
;
773 if (bfd_seek (abfd
, 0, SEEK_SET
) != 0)
774 goto skip_fdpic_init
;
775 if (bfd_read (&ehdr
, sizeof (ehdr
), abfd
) != sizeof (ehdr
))
776 goto skip_fdpic_init
;
777 iehdr
= elf_elfheader (abfd
);
778 if (!(iehdr
->e_flags
& EF_BFIN_FDPIC
))
779 goto skip_fdpic_init
;
781 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
782 sim_io_printf (sd
, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
783 bfd_get_filename (abfd
), fdpic_load_offset
, elf_addrs
[0]);
785 /* Grab the Program Headers to set up the loadsegs on the stack. */
786 phdr_size
= bfd_get_elf_phdr_upper_bound (abfd
);
788 goto skip_fdpic_init
;
789 phdrs
= xmalloc (phdr_size
);
790 phdrc
= bfd_get_elf_phdrs (abfd
, phdrs
);
792 goto skip_fdpic_init
;
794 /* Push the Ehdr onto the stack. */
795 *sp
-= sizeof (ehdr
);
797 sim_write (sd
, *sp
, &ehdr
, sizeof (ehdr
));
798 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
799 sim_io_printf (sd
, " Elf_Ehdr: %#x\n", *sp
);
801 /* Since we're relocating things ourselves, we need to relocate
802 the start address as well. */
803 elf_addrs
[0] = bfd_get_start_address (abfd
) + fdpic_load_offset
;
805 /* And the Exec's Phdrs onto the stack. */
806 if (STATE_PROG_BFD (sd
) == abfd
)
808 elf_addrs
[4] = elf_addrs
[0];
810 phdr_size
= iehdr
->e_phentsize
* iehdr
->e_phnum
;
811 if (bfd_seek (abfd
, iehdr
->e_phoff
, SEEK_SET
) != 0)
812 goto skip_fdpic_init
;
813 data
= xmalloc (phdr_size
);
814 if (bfd_read (data
, phdr_size
, abfd
) != phdr_size
)
815 goto skip_fdpic_init
;
818 elf_addrs
[2] = phdrc
;
819 sim_write (sd
, *sp
, data
, phdr_size
);
821 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
822 sim_io_printf (sd
, " Elf_Phdrs: %#x\n", *sp
);
825 /* Now push all the loadsegs. */
828 for (i
= phdrc
; i
>= 0; --i
)
829 if (phdrs
[i
].p_type
== PT_LOAD
)
831 Elf_Internal_Phdr
*p
= &phdrs
[i
];
832 bu32 paddr
, vaddr
, memsz
, filesz
;
834 paddr
= p
->p_paddr
+ fdpic_load_offset
;
837 filesz
= p
->p_filesz
;
839 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
840 sim_io_printf (sd
, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
841 i
, vaddr
, paddr
, filesz
, memsz
);
843 data
= xmalloc (memsz
);
845 memset (data
+ filesz
, 0, memsz
- filesz
);
847 if (bfd_seek (abfd
, p
->p_offset
, SEEK_SET
) == 0
848 && bfd_read (data
, filesz
, abfd
) == filesz
)
849 sim_write (sd
, paddr
, data
, memsz
);
853 max_load_addr
= max (paddr
+ memsz
, max_load_addr
);
856 sim_write (sd
, *sp
+0, &paddr
, 4); /* loadseg.addr */
857 sim_write (sd
, *sp
+4, &vaddr
, 4); /* loadseg.p_vaddr */
858 sim_write (sd
, *sp
+8, &memsz
, 4); /* loadseg.p_memsz */
861 else if (phdrs
[i
].p_type
== PT_DYNAMIC
)
863 elf_addrs
[5] = phdrs
[i
].p_paddr
+ fdpic_load_offset
;
864 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
865 sim_io_printf (sd
, " PT_DYNAMIC: %#x\n", elf_addrs
[5]);
867 else if (phdrs
[i
].p_type
== PT_INTERP
)
869 uint32_t off
= phdrs
[i
].p_offset
;
870 uint32_t len
= phdrs
[i
].p_filesz
;
872 *ldso_path
= xmalloc (len
);
873 if (bfd_seek (abfd
, off
, SEEK_SET
) != 0
874 || bfd_read (*ldso_path
, len
, abfd
) != len
)
879 else if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
880 sim_io_printf (sd
, " PT_INTERP: %s\n", *ldso_path
);
883 /* Update the load offset with a few extra pages. */
884 fdpic_load_offset
= align_up (max (max_load_addr
, fdpic_load_offset
),
886 fdpic_load_offset
+= 0x10000;
888 /* Push the summary loadmap info onto the stack last. */
890 sim_write (sd
, *sp
+0, null
, 2); /* loadmap.version */
891 sim_write (sd
, *sp
+2, &nsegs
, 2); /* loadmap.nsegs */
901 bfin_user_init (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
,
902 char * const *argv
, char * const *env
)
904 /* XXX: Missing host -> target endian ... */
905 /* Linux starts the user app with the stack:
907 argv[0] -- pointers to the actual strings
913 auxvt[0].type -- ELF Auxiliary Vector Table
918 argv[0..N][0..M] -- actual argv/env strings
920 FDPIC loadmaps -- for FDPIC apps
921 So set things up the same way. */
923 bu32 argv_flat
, env_flat
;
927 /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
930 bu32 exec_loadmap
, ldso_loadmap
;
933 unsigned char null
[4] = { 0, 0, 0, 0 };
935 host_callback
*cb
= STATE_CALLBACK (sd
);
937 elf_addrs
[0] = elf_addrs
[4] = bfd_get_start_address (abfd
);
938 elf_addrs
[1] = elf_addrs
[2] = elf_addrs
[3] = elf_addrs
[5] = 0;
940 /* Keep the load addresses consistent between runs. Also make sure we make
941 space for the fixed code region (part of the Blackfin Linux ABI). */
942 fdpic_load_offset
= 0x1000;
944 /* First try to load this as an FDPIC executable. */
946 if (!bfin_fdpic_load (sd
, cpu
, STATE_PROG_BFD (sd
), &sp
, elf_addrs
, &ldso_path
))
947 goto skip_fdpic_init
;
950 /* If that worked, then load the fixed code region. We only do this for
951 FDPIC ELFs atm because they are PIEs and let us relocate them without
952 manual fixups. FLAT files however require location processing which
953 we do not do ourselves, and they link with a VMA of 0. */
954 sim_write (sd
, 0x400, bfin_linux_fixed_code
, sizeof (bfin_linux_fixed_code
));
956 /* If the FDPIC needs an interpreter, then load it up too. */
959 const char *ldso_full_path
= concat (simulator_sysroot
, ldso_path
, NULL
);
960 struct bfd
*ldso_bfd
;
962 ldso_bfd
= bfd_openr (ldso_full_path
, STATE_TARGET (sd
));
965 sim_io_eprintf (sd
, "bfin-sim: bfd open failed: %s\n", ldso_full_path
);
968 if (!bfd_check_format (ldso_bfd
, bfd_object
))
969 sim_io_eprintf (sd
, "bfin-sim: bfd format not valid: %s\n", ldso_full_path
);
970 bfd_set_arch_info (ldso_bfd
, STATE_ARCHITECTURE (sd
));
972 if (!bfin_fdpic_load (sd
, cpu
, ldso_bfd
, &sp
, elf_addrs
, &ldso_path
))
973 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path
);
975 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
976 ldso_full_path
, ldso_path
);
984 /* Finally setup the registers required by the FDPIC ABI. */
985 SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up. */
986 SET_PREG (0, exec_loadmap
); /* Exec loadmap addr. */
987 SET_PREG (1, ldso_loadmap
); /* Interp loadmap addr. */
988 SET_PREG (2, elf_addrs
[5]); /* PT_DYNAMIC map addr. */
993 sim_pc_set (cpu
, elf_addrs
[0]);
995 /* Figure out how much storage the argv/env strings need. */
996 argc
= countargv ((char **)argv
);
999 argv_flat
= argc
; /* NUL bytes */
1000 for (i
= 0; i
< argc
; ++i
)
1001 argv_flat
+= strlen (argv
[i
]);
1005 envc
= countargv ((char **)env
);
1006 env_flat
= envc
; /* NUL bytes */
1007 for (i
= 0; i
< envc
; ++i
)
1008 env_flat
+= strlen (env
[i
]);
1010 /* Push the Auxiliary Vector Table between argv/env and actual strings. */
1011 sp_flat
= sp
= align_up (SPREG
- argv_flat
- env_flat
- 4, 4);
1014 # define AT_PUSH(at, val) \
1017 sim_write (sd, sp, &auxvt, 4); \
1020 sim_write (sd, sp, &auxvt, 4)
1021 unsigned int egid
= getegid (), gid
= getgid ();
1022 unsigned int euid
= geteuid (), uid
= getuid ();
1023 AT_PUSH (AT_NULL
, 0);
1024 AT_PUSH (AT_SECURE
, egid
!= gid
|| euid
!= uid
);
1025 AT_PUSH (AT_EGID
, egid
);
1026 AT_PUSH (AT_GID
, gid
);
1027 AT_PUSH (AT_EUID
, euid
);
1028 AT_PUSH (AT_UID
, uid
);
1029 AT_PUSH (AT_ENTRY
, elf_addrs
[4]);
1030 AT_PUSH (AT_FLAGS
, 0);
1031 AT_PUSH (AT_BASE
, elf_addrs
[3]);
1032 AT_PUSH (AT_PHNUM
, elf_addrs
[2]);
1033 AT_PUSH (AT_PHENT
, sizeof (Elf32_External_Phdr
));
1034 AT_PUSH (AT_PHDR
, elf_addrs
[1]);
1035 AT_PUSH (AT_CLKTCK
, 100); /* XXX: This ever not 100 ? */
1036 AT_PUSH (AT_PAGESZ
, 4096);
1037 AT_PUSH (AT_HWCAP
, 0);
1042 /* Push the argc/argv/env after the auxvt. */
1043 sp
-= ((1 + argc
+ 1 + envc
+ 1) * 4);
1046 /* First push the argc value. */
1047 sim_write (sd
, sp
, &argc
, 4);
1050 /* Then the actual argv strings so we know where to point argv[]. */
1051 for (i
= 0; i
< argc
; ++i
)
1053 unsigned len
= strlen (argv
[i
]) + 1;
1054 sim_write (sd
, sp_flat
, argv
[i
], len
);
1055 sim_write (sd
, sp
, &sp_flat
, 4);
1059 sim_write (sd
, sp
, null
, 4);
1062 /* Then the actual env strings so we know where to point env[]. */
1063 for (i
= 0; i
< envc
; ++i
)
1065 unsigned len
= strlen (env
[i
]) + 1;
1066 sim_write (sd
, sp_flat
, env
[i
], len
);
1067 sim_write (sd
, sp
, &sp_flat
, 4);
1072 /* Set some callbacks. */
1073 cb
->syscall_map
= cb_linux_syscall_map
;
1074 cb
->errno_map
= cb_linux_errno_map
;
1075 cb
->open_map
= cb_linux_open_map
;
1076 cb
->signal_map
= cb_linux_signal_map
;
1077 cb
->stat_map
= stat_map_32
= cb_linux_stat_map_32
;
1078 stat_map_64
= cb_linux_stat_map_64
;
1082 bfin_os_init (SIM_DESC sd
, SIM_CPU
*cpu
, char * const *argv
)
1084 /* Pass the command line via a string in R0 like Linux expects. */
1087 bu32 cmdline
= BFIN_L1_SRAM_SCRATCH
;
1089 SET_DREG (0, cmdline
);
1090 if (argv
&& argv
[0])
1096 bu32 len
= strlen (argv
[i
]);
1097 sim_write (sd
, cmdline
, argv
[i
], len
);
1099 sim_write (sd
, cmdline
, &byte
, 1);
1105 sim_write (sd
, cmdline
, &byte
, 1);
1109 bfin_virtual_init (SIM_DESC sd
, SIM_CPU
*cpu
)
1111 host_callback
*cb
= STATE_CALLBACK (sd
);
1113 cb
->stat_map
= stat_map_32
= cb_libgloss_stat_map_32
;
1118 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
1119 char * const *argv
, char * const *env
)
1121 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
1122 host_callback
*cb
= STATE_CALLBACK (sd
);
1127 addr
= bfd_get_start_address (abfd
);
1130 sim_pc_set (cpu
, addr
);
1132 /* Standalone mode (i.e. `run`) will take care of the argv for us in
1133 sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim'
1134 with `gdb`), we need to handle it because the user can change the
1135 argv on the fly via gdb's 'run'. */
1136 if (STATE_PROG_ARGV (sd
) != argv
)
1138 freeargv (STATE_PROG_ARGV (sd
));
1139 STATE_PROG_ARGV (sd
) = dupargv (argv
);
1142 if (STATE_PROG_ENVP (sd
) != env
)
1144 freeargv (STATE_PROG_ENVP (sd
));
1145 STATE_PROG_ENVP (sd
) = dupargv (env
);
1148 cb
->argv
= STATE_PROG_ARGV (sd
);
1149 cb
->envp
= STATE_PROG_ENVP (sd
);
1151 switch (STATE_ENVIRONMENT (sd
))
1153 case USER_ENVIRONMENT
:
1154 bfin_user_init (sd
, cpu
, abfd
, argv
, env
);
1156 case OPERATING_ENVIRONMENT
:
1157 bfin_os_init (sd
, cpu
, argv
);
1160 bfin_virtual_init (sd
, cpu
);