1 /* Simulator for Analog Devices Blackfin processors.
3 Copyright (C) 2005-2015 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/>. */
32 #include "gdb/callback.h"
33 #include "gdb/signals.h"
37 #include "targ-vals.h"
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"
66 #include "elf/common.h"
67 #include "elf/external.h"
68 #include "elf/internal.h"
72 #include "dv-bfin_cec.h"
73 #include "dv-bfin_mmu.h"
88 # define setuid(uid) -1
91 # define setgid(gid) -1
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:"
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
;
114 /* Count the number of arguments in an argv. */
116 count_argc (const char * const *argv
)
123 for (i
= 0; argv
[i
] != NULL
; ++i
)
128 /* Read/write functions for system call interface. */
131 syscall_read_mem (host_callback
*cb
, struct cb_syscall
*sc
,
132 unsigned long taddr
, char *buf
, int bytes
)
134 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
135 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
137 TRACE_CORE (cpu
, "DBUS FETCH (syscall) %i bytes @ 0x%08lx", bytes
, taddr
);
139 return sim_core_read_buffer (sd
, cpu
, read_map
, buf
, taddr
, bytes
);
143 syscall_write_mem (host_callback
*cb
, struct cb_syscall
*sc
,
144 unsigned long taddr
, const char *buf
, int bytes
)
146 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
147 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
149 TRACE_CORE (cpu
, "DBUS STORE (syscall) %i bytes @ 0x%08lx", bytes
, taddr
);
151 return sim_core_write_buffer (sd
, cpu
, write_map
, buf
, taddr
, bytes
);
154 /* Simulate a monitor trap, put the result into r0 and errno into r1
155 return offset by which to adjust pc. */
158 bfin_syscall (SIM_CPU
*cpu
)
160 SIM_DESC sd
= CPU_STATE (cpu
);
161 const char * const *argv
= (void *)STATE_PROG_ARGV (sd
);
162 host_callback
*cb
= STATE_CALLBACK (sd
);
166 char _tbuf
[1024 * 3], *tbuf
= _tbuf
, tstr
[1024];
169 CB_SYSCALL_INIT (&sc
);
171 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
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);
184 /* libgloss syscall. */
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);
195 sc
.read_mem
= syscall_read_mem
;
196 sc
.write_mem
= syscall_write_mem
;
198 /* Common cb_syscall() handles most functions. */
199 switch (cb_target_to_host_syscall (cb
, sc
.func
))
202 tbuf
+= sprintf (tbuf
, "exit(%i)", args
[0]);
203 sim_engine_halt (sd
, cpu
, NULL
, PCREG
, sim_exited
, sc
.arg1
);
207 tbuf
+= sprintf (tbuf
, "argc()");
208 sc
.result
= count_argc (argv
);
212 tbuf
+= sprintf (tbuf
, "argnlen(%u)", args
[0]);
213 if (sc
.arg1
< count_argc (argv
))
214 sc
.result
= strlen (argv
[sc
.arg1
]);
221 tbuf
+= sprintf (tbuf
, "argn(%u)", args
[0]);
222 if (sc
.arg1
< count_argc (argv
))
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)
238 case CB_SYS_gettimeofday
:
240 struct timeval _tv
, *tv
= &_tv
;
241 struct timezone _tz
, *tz
= &_tz
;
243 tbuf
+= sprintf (tbuf
, "gettimeofday(%#x, %#x)", args
[0], args
[1]);
249 sc
.result
= gettimeofday (tv
, tz
);
258 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
260 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
265 t
= tz
->tz_minuteswest
;
266 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
268 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
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)
281 sc
.result
= !isatty (sc
.arg1
);
287 sc
.errcode
= TARGET_EINVAL
;
293 static bu32 heap
= BFIN_DEFAULT_MEM_SIZE
/ 2;
296 tbuf
+= sprintf (tbuf
, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
297 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
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
;
308 char *data
= xmalloc (sc
.arg2
);
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
);
314 sc
.errcode
= TARGET_EINVAL
;
318 sc
.errcode
= TARGET_ENOSYS
;
330 /* Keep it page aligned. */
331 heap
= ALIGN (heap
, 4096);
337 /* XXX: meh, just lie for mmap(). */
338 tbuf
+= sprintf (tbuf
, "munmap(%#x, %u)", args
[0], args
[1]);
343 tbuf
+= sprintf (tbuf
, "dup2(%i, %i)", args
[0], args
[1]);
344 if (sc
.arg1
>= MAX_CALLBACK_FDS
|| sc
.arg2
>= MAX_CALLBACK_FDS
)
347 sc
.errcode
= TARGET_EINVAL
;
351 sc
.result
= dup2 (cb
->fdmap
[sc
.arg1
], cb
->fdmap
[sc
.arg2
]);
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
;
363 sc
.errcode
= TARGET_EINVAL
;
369 cb_syscall (cb
, &sc
);
373 sc
.write_mem (cb
, &sc
, args
[3], (void *)&sc
.result
, 4);
374 sc
.write_mem (cb
, &sc
, args
[3] + 4, (void *)&z
, 4);
379 /* XXX: Should add a cb->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
)
386 sc
.errcode
= TARGET_EINVAL
;
390 long old_pos
, read_result
, read_errcode
;
392 /* Get current filepos. */
393 sc
.func
= TARGET_LINUX_SYS_lseek
;
396 cb_syscall (cb
, &sc
);
401 /* Move to the new pos. */
402 sc
.func
= TARGET_LINUX_SYS_lseek
;
405 cb_syscall (cb
, &sc
);
410 sc
.func
= TARGET_LINUX_SYS_read
;
413 cb_syscall (cb
, &sc
);
414 read_result
= sc
.result
;
415 read_errcode
= sc
.errcode
;
417 /* Move back to the old pos. */
418 sc
.func
= TARGET_LINUX_SYS_lseek
;
421 cb_syscall (cb
, &sc
);
423 sc
.result
= read_result
;
424 sc
.errcode
= read_errcode
;
429 tbuf
+= sprintf (tbuf
, "getcwd(%#x, %u)", args
[0], args
[1]);
431 p
= alloca (sc
.arg2
);
432 if (getcwd (p
, sc
.arg2
) == NULL
)
435 sc
.errcode
= TARGET_EINVAL
;
439 sc
.write_mem (cb
, &sc
, sc
.arg1
, p
, sc
.arg2
);
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
;
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
;
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
;
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
);
477 case CB_SYS_getuid32
:
478 tbuf
+= sprintf (tbuf
, "getuid()");
479 sc
.result
= getuid ();
482 case CB_SYS_getgid32
:
483 tbuf
+= sprintf (tbuf
, "getgid()");
484 sc
.result
= getgid ();
488 case CB_SYS_setuid32
:
489 tbuf
+= sprintf (tbuf
, "setuid(%u)", args
[0]);
490 sc
.result
= setuid (sc
.arg1
);
494 case CB_SYS_setgid32
:
495 tbuf
+= sprintf (tbuf
, "setgid(%u)", args
[0]);
496 sc
.result
= setgid (sc
.arg1
);
500 tbuf
+= sprintf (tbuf
, "getpid()");
501 sc
.result
= getpid ();
504 tbuf
+= sprintf (tbuf
, "kill(%u, %i)", args
[0], args
[1]);
505 /* Only let the app kill itself. */
506 if (sc
.arg1
!= getpid ())
509 sc
.errcode
= TARGET_EPERM
;
514 sc
.result
= kill (sc
.arg1
, sc
.arg2
);
518 sc
.errcode
= TARGET_ENOSYS
;
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]);
530 tbuf
+= sprintf (tbuf
, "close(%i)", args
[0]);
533 tbuf
+= sprintf (tbuf
, "read(%i, %#x, %u)", args
[0], args
[1], args
[2]);
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]);
542 tbuf
+= sprintf (tbuf
, "lseek(%i, %i, %i)", args
[0], args
[1], args
[2]);
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
);
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]);
554 case CB_SYS_ftruncate
:
555 tbuf
+= sprintf (tbuf
, "ftruncate(%i, %i)", args
[0], args
[1]);
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
);
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]);
571 tbuf
+= sprintf (tbuf
, "fstat(%i, %#x)", args
[0], args
[1]);
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]);
579 tbuf
+= sprintf (tbuf
, "pipe(%#x, %#x)", args
[0], args
[1]);
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]);
586 cb_syscall (cb
, &sc
);
592 cb
->last_errno
= errno
;
593 sc
.errcode
= cb
->get_errno (cb
);
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
);
601 tbuf
+= sprintf (tbuf
, " = ");
602 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
606 tbuf
+= sprintf (tbuf
, "-1 (error = %i)", sc
.errcode
);
607 if (sc
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
609 sim_io_eprintf (sd
, "bfin-sim: %#x: unimplemented syscall %i\n",
612 SET_DREG (0, -sc
.errcode
);
617 tbuf
+= sprintf (tbuf
, "%#lx", sc
.result
);
619 tbuf
+= sprintf (tbuf
, "%lu", sc
.result
);
620 SET_DREG (0, sc
.result
);
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
);
631 TRACE_SYSCALL (cpu
, "%s", _tbuf
);
635 trace_register (SIM_DESC sd
,
641 trace_printf (sd
, cpu
, "%s %s",
643 TRACE_PREFIX (CPU_TRACE_DATA (cpu
)));
645 trace_vprintf (sd
, cpu
, fmt
, ap
);
647 trace_printf (sd
, cpu
, "\n");
650 /* Execute a single instruction. */
653 step_once (SIM_CPU
*cpu
)
655 SIM_DESC sd
= CPU_STATE (cpu
);
656 bu32 insn_len
, oldpc
= PCREG
;
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. */
664 /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
665 has already had the SSSTEP bit enabled. */
667 if (STATE_ENVIRONMENT (sd
) == OPERATING_ENVIRONMENT
668 && (SYSCFGREG
& SYSCFG_SSSTEP
))
670 int ivg
= cec_get_ivg (cpu
);
671 if (ivg
== -1 || ivg
> 3)
676 /* XXX: Is this what happens on the hardware ? */
677 if (cec_get_ivg (cpu
) == EVT_EMU
)
678 cec_return (cpu
, EVT_EMU
);
681 BFIN_CPU_STATE
.did_jump
= false;
683 insn_len
= interp_insn_bfin (cpu
, oldpc
);
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
))
693 SET_LCREG (i
, LCREG (i
) - 1);
698 ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
));
700 /* Handle hardware single stepping only if we're still lower than EVT3.
701 XXX: May not be entirely correct wrt EXCPT insns. */
704 int ivg
= cec_get_ivg (cpu
);
705 if (ivg
== -1 || ivg
> 3)
708 cec_exception (cpu
, VEC_STEP
);
716 sim_engine_run (SIM_DESC sd
,
717 int next_cpu_nr
, /* ignore */
718 int nr_cpus
, /* ignore */
719 int siggnal
) /* ignore */
724 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
726 cpu
= STATE_CPU (sd
, 0);
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
);
739 /* Cover function of sim_state_free to free the cpu buffers as well. */
742 free_state (SIM_DESC sd
)
744 if (STATE_MODULES (sd
) != NULL
)
745 sim_module_uninstall (sd
);
746 sim_cpu_free_all (sd
);
750 /* Create an instance of the simulator. */
753 bfin_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
755 memset (&cpu
->state
, 0, sizeof (cpu
->state
));
757 PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
)) = 0;
759 bfin_model_cpu_init (sd
, cpu
);
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
);
766 /* This is what the hardware likes. */
767 SET_SYSCFGREG (0x30);
771 sim_open (SIM_OPEN_KIND kind
, host_callback
*callback
,
772 struct bfd
*abfd
, char **argv
)
776 SIM_DESC sd
= sim_state_alloc (kind
, callback
);
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
)
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
);
792 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
798 /* XXX: Default to the Virtual environment. */
799 if (STATE_ENVIRONMENT (sd
) == ALL_ENVIRONMENT
)
800 STATE_ENVIRONMENT (sd
) = VIRTUAL_ENVIRONMENT
;
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) \
807 extern const OPTION options[]; \
808 sim_add_option_table (sd, NULL, options); \
810 e_sim_add_option_table (sd
, bfin_mmu_options
);
811 e_sim_add_option_table (sd
, bfin_mach_options
);
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
816 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
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)
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);
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
)
841 /* Establish any remaining configuration options. */
842 if (sim_config (sd
) != SIM_RC_OK
)
848 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
854 /* CPU specific initialization. */
855 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
857 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
858 bfin_initialize_cpu (sd
, cpu
);
865 sim_close (SIM_DESC sd
, int quitting
)
867 sim_module_uninstall (sd
);
870 /* Some utils don't like having a NULL environ. */
871 static const char * const simple_env
[] = { "HOME=/", "PATH=/bin", NULL
};
873 static bu32 fdpic_load_offset
;
876 bfin_fdpic_load (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
, bu32
*sp
,
877 bu32
*elf_addrs
, char **ldso_path
)
882 Elf_Internal_Ehdr
*iehdr
;
883 Elf32_External_Ehdr ehdr
;
884 Elf_Internal_Phdr
*phdrs
;
892 unsigned char null
[4] = { 0, 0, 0, 0 };
897 /* See if this an FDPIC ELF. */
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
;
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]);
913 /* Grab the Program Headers to set up the loadsegs on the stack. */
914 phdr_size
= bfd_get_elf_phdr_upper_bound (abfd
);
916 goto skip_fdpic_init
;
917 phdrs
= xmalloc (phdr_size
);
918 phdrc
= bfd_get_elf_phdrs (abfd
, phdrs
);
920 goto skip_fdpic_init
;
922 /* Push the Ehdr onto the stack. */
923 *sp
-= sizeof (ehdr
);
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
);
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
;
933 /* And the Exec's Phdrs onto the stack. */
934 if (STATE_PROG_BFD (sd
) == abfd
)
936 elf_addrs
[4] = elf_addrs
[0];
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
;
946 elf_addrs
[2] = phdrc
;
947 sim_write (sd
, *sp
, data
, phdr_size
);
949 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
950 sim_io_printf (sd
, " Elf_Phdrs: %#x\n", *sp
);
953 /* Now push all the loadsegs. */
956 for (i
= phdrc
; i
>= 0; --i
)
957 if (phdrs
[i
].p_type
== PT_LOAD
)
959 Elf_Internal_Phdr
*p
= &phdrs
[i
];
960 bu32 paddr
, vaddr
, memsz
, filesz
;
962 paddr
= p
->p_paddr
+ fdpic_load_offset
;
965 filesz
= p
->p_filesz
;
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
);
971 data
= xmalloc (memsz
);
973 memset (data
+ filesz
, 0, memsz
- filesz
);
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
);
981 max_load_addr
= MAX (paddr
+ memsz
, max_load_addr
);
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 */
989 else if (phdrs
[i
].p_type
== PT_DYNAMIC
)
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]);
995 else if (phdrs
[i
].p_type
== PT_INTERP
)
997 uint32_t off
= phdrs
[i
].p_offset
;
998 uint32_t len
= phdrs
[i
].p_filesz
;
1000 *ldso_path
= xmalloc (len
);
1001 if (bfd_seek (abfd
, off
, SEEK_SET
) != 0
1002 || bfd_bread (*ldso_path
, len
, abfd
) != len
)
1007 else if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
1008 sim_io_printf (sd
, " PT_INTERP: %s\n", *ldso_path
);
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;
1015 /* Push the summary loadmap info onto the stack last. */
1017 sim_write (sd
, *sp
+0, null
, 2); /* loadmap.version */
1018 sim_write (sd
, *sp
+2, (void *)&nsegs
, 2); /* loadmap.nsegs */
1028 bfin_user_init (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
,
1029 const char * const *argv
, const char * const *env
)
1031 /* XXX: Missing host -> target endian ... */
1032 /* Linux starts the user app with the stack:
1034 argv[0] -- pointers to the actual strings
1040 auxvt[0].type -- ELF Auxiliary Vector Table
1045 argv[0..N][0..M] -- actual argv/env strings
1047 FDPIC loadmaps -- for FDPIC apps
1048 So set things up the same way. */
1050 bu32 argv_flat
, env_flat
;
1054 /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
1057 bu32 exec_loadmap
, ldso_loadmap
;
1060 unsigned char null
[4] = { 0, 0, 0, 0 };
1062 host_callback
*cb
= STATE_CALLBACK (sd
);
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;
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;
1071 /* First try to load this as an FDPIC executable. */
1073 if (!bfin_fdpic_load (sd
, cpu
, STATE_PROG_BFD (sd
), &sp
, elf_addrs
, &ldso_path
))
1074 goto skip_fdpic_init
;
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
));
1083 /* If the FDPIC needs an interpreter, then load it up too. */
1086 const char *ldso_full_path
= concat (simulator_sysroot
, ldso_path
, NULL
);
1087 struct bfd
*ldso_bfd
;
1089 ldso_bfd
= bfd_openr (ldso_full_path
, STATE_TARGET (sd
));
1092 sim_io_eprintf (sd
, "bfin-sim: bfd open failed: %s\n", ldso_full_path
);
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
));
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
);
1102 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
1103 ldso_full_path
, ldso_path
);
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. */
1120 sim_pc_set (cpu
, elf_addrs
[0]);
1122 /* Figure out how much storage the argv/env strings need. */
1123 argc
= count_argc (argv
);
1126 argv_flat
= argc
; /* NUL bytes */
1127 for (i
= 0; i
< argc
; ++i
)
1128 argv_flat
+= strlen (argv
[i
]);
1132 envc
= count_argc (env
);
1133 env_flat
= envc
; /* NUL bytes */
1134 for (i
= 0; i
< envc
; ++i
)
1135 env_flat
+= strlen (env
[i
]);
1137 /* Push the Auxiliary Vector Table between argv/env and actual strings. */
1138 sp_flat
= sp
= ALIGN (SPREG
- argv_flat
- env_flat
- 4, 4);
1141 # define AT_PUSH(at, val) \
1145 sim_write (sd, sp, (void *)&auxvt, 4); \
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);
1171 /* Push the argc/argv/env after the auxvt. */
1172 sp
-= ((1 + argc
+ 1 + envc
+ 1) * 4);
1175 /* First push the argc value. */
1176 sim_write (sd
, sp
, (void *)&argc
, 4);
1179 /* Then the actual argv strings so we know where to point argv[]. */
1180 for (i
= 0; i
< argc
; ++i
)
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);
1188 sim_write (sd
, sp
, null
, 4);
1191 /* Then the actual env strings so we know where to point env[]. */
1192 for (i
= 0; i
< envc
; ++i
)
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);
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
;
1211 bfin_os_init (SIM_DESC sd
, SIM_CPU
*cpu
, const char * const *argv
)
1213 /* Pass the command line via a string in R0 like Linux expects. */
1216 bu32 cmdline
= BFIN_L1_SRAM_SCRATCH
;
1218 SET_DREG (0, cmdline
);
1219 if (argv
&& argv
[0])
1225 bu32 len
= strlen (argv
[i
]);
1226 sim_write (sd
, cmdline
, (void *)argv
[i
], len
);
1228 sim_write (sd
, cmdline
, &byte
, 1);
1234 sim_write (sd
, cmdline
, &byte
, 1);
1238 bfin_virtual_init (SIM_DESC sd
, SIM_CPU
*cpu
)
1240 host_callback
*cb
= STATE_CALLBACK (sd
);
1242 cb
->stat_map
= stat_map_32
= cb_libgloss_stat_map_32
;
1247 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
1248 char **argv
, char **env
)
1250 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
1255 addr
= bfd_get_start_address (abfd
);
1258 sim_pc_set (cpu
, addr
);
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
)
1265 freeargv (STATE_PROG_ARGV (sd
));
1266 STATE_PROG_ARGV (sd
) = dupargv (argv
);
1269 switch (STATE_ENVIRONMENT (sd
))
1271 case USER_ENVIRONMENT
:
1272 bfin_user_init (sd
, cpu
, abfd
, (void *)argv
, (void *)env
);
1274 case OPERATING_ENVIRONMENT
:
1275 bfin_os_init (sd
, cpu
, (void *)argv
);
1278 bfin_virtual_init (sd
, cpu
);