1 /* Simulator for Analog Devices Blackfin processors.
3 Copyright (C) 2005-2011 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. */
40 #define CB_SYS_ioctl 201
41 #define CB_SYS_mmap2 202
42 #define CB_SYS_munmap 203
43 #define CB_SYS_dup2 204
44 #define CB_SYS_getuid 205
45 #define CB_SYS_getuid32 206
46 #define CB_SYS_getgid 207
47 #define CB_SYS_getgid32 208
48 #define CB_SYS_setuid 209
49 #define CB_SYS_setuid32 210
50 #define CB_SYS_setgid 211
51 #define CB_SYS_setgid32 212
52 #define CB_SYS_pread 213
53 #define CB_SYS__llseek 214
54 #define CB_SYS_getcwd 215
55 #define CB_SYS_stat64 216
56 #define CB_SYS_lstat64 217
57 #define CB_SYS_fstat64 218
58 #define CB_SYS_ftruncate64 219
59 #define CB_SYS_gettimeofday 220
60 #define CB_SYS_access 221
61 #include "linux-targ-map.h"
62 #include "linux-fixed-code.h"
64 #include "elf/common.h"
65 #include "elf/external.h"
66 #include "elf/internal.h"
70 #include "dv-bfin_cec.h"
71 #include "dv-bfin_mmu.h"
86 # define setuid(uid) -1
89 # define setgid(gid) -1
92 static const char stat_map_32
[] =
93 /* Linux kernel 32bit layout: */
94 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
95 "space,2:st_size,4:st_blksize,4:st_blocks,4:st_atime,4:st_atimensec,4:"
96 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:space,4";
97 /* uClibc public ABI 32bit layout:
98 "st_dev,8:space,2:space,2:st_ino,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:"
99 "st_rdev,8:space,2:space,2:st_size,4:st_blksiez,4:st_blocks,4:st_atime,4:"
100 "st_atimensec,4:st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:"
102 static const char stat_map_64
[] =
103 "st_dev,8:space,4:space,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:st_rdev,8:"
104 "space,4:st_size,8:st_blksize,4:st_blocks,8:st_atime,4:st_atimensec,4:"
105 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:st_ino,8";
107 /* Count the number of arguments in an argv. */
109 count_argc (const char * const *argv
)
116 for (i
= 0; argv
[i
] != NULL
; ++i
)
121 /* Read/write functions for system call interface. */
124 syscall_read_mem (host_callback
*cb
, struct cb_syscall
*sc
,
125 unsigned long taddr
, char *buf
, int bytes
)
127 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
128 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
130 MAYBE_TRACE (CORE
, cpu
, "DBUS FETCH (syscall) %i bytes @ 0x%08lx", bytes
, taddr
);
132 return sim_core_read_buffer (sd
, cpu
, read_map
, buf
, taddr
, bytes
);
136 syscall_write_mem (host_callback
*cb
, struct cb_syscall
*sc
,
137 unsigned long taddr
, const char *buf
, int bytes
)
139 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
140 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
142 MAYBE_TRACE (CORE
, cpu
, "DBUS STORE (syscall) %i bytes @ 0x%08lx", bytes
, taddr
);
144 return sim_core_write_buffer (sd
, cpu
, write_map
, buf
, taddr
, bytes
);
147 /* Simulate a monitor trap, put the result into r0 and errno into r1
148 return offset by which to adjust pc. */
151 bfin_syscall (SIM_CPU
*cpu
)
153 SIM_DESC sd
= CPU_STATE (cpu
);
154 const char * const *argv
= (void *)STATE_PROG_ARGV (sd
);
155 host_callback
*cb
= STATE_CALLBACK (sd
);
159 char _tbuf
[512], *tbuf
= _tbuf
;
162 CB_SYSCALL_INIT (&sc
);
164 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
168 sc
.arg1
= args
[0] = DREG (0);
169 sc
.arg2
= args
[1] = DREG (1);
170 sc
.arg3
= args
[2] = DREG (2);
171 sc
.arg4
= args
[3] = DREG (3);
172 /*sc.arg5 =*/ args
[4] = DREG (4);
173 /*sc.arg6 =*/ args
[5] = DREG (5);
177 /* libgloss syscall. */
179 sc
.arg1
= args
[0] = GET_LONG (DREG (0));
180 sc
.arg2
= args
[1] = GET_LONG (DREG (0) + 4);
181 sc
.arg3
= args
[2] = GET_LONG (DREG (0) + 8);
182 sc
.arg4
= args
[3] = GET_LONG (DREG (0) + 12);
183 /*sc.arg5 =*/ args
[4] = GET_LONG (DREG (0) + 16);
184 /*sc.arg6 =*/ args
[5] = GET_LONG (DREG (0) + 20);
188 sc
.read_mem
= syscall_read_mem
;
189 sc
.write_mem
= syscall_write_mem
;
191 /* Common cb_syscall() handles most functions. */
192 switch (cb_target_to_host_syscall (cb
, sc
.func
))
195 tbuf
+= sprintf (tbuf
, "exit(%i)", args
[0]);
196 sim_engine_halt (sd
, cpu
, NULL
, PCREG
, sim_exited
, sc
.arg1
);
200 tbuf
+= sprintf (tbuf
, "argc()");
201 sc
.result
= count_argc (argv
);
205 tbuf
+= sprintf (tbuf
, "argnlen(%u)", args
[0]);
206 if (sc
.arg1
< count_argc (argv
))
207 sc
.result
= strlen (argv
[sc
.arg1
]);
214 tbuf
+= sprintf (tbuf
, "argn(%u)", args
[0]);
215 if (sc
.arg1
< count_argc (argv
))
217 const char *argn
= argv
[sc
.arg1
];
218 int len
= strlen (argn
);
219 int written
= sc
.write_mem (cb
, &sc
, sc
.arg2
, argn
, len
+ 1);
220 if (written
== len
+ 1)
231 case CB_SYS_gettimeofday
:
233 struct timeval _tv
, *tv
= &_tv
;
234 struct timezone _tz
, *tz
= &_tz
;
236 tbuf
+= sprintf (tbuf
, "gettimeofday(%#x, %#x)", args
[0], args
[1]);
242 sc
.result
= gettimeofday (tv
, tz
);
251 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
253 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
258 t
= tz
->tz_minuteswest
;
259 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
261 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
270 /* XXX: hack just enough to get basic stdio w/uClibc ... */
271 tbuf
+= sprintf (tbuf
, "ioctl(%i, %#x, %u)", args
[0], args
[1], args
[2]);
272 if (sc
.arg2
== 0x5401)
274 sc
.result
= !isatty (sc
.arg1
);
280 sc
.errcode
= TARGET_EINVAL
;
286 static bu32 heap
= BFIN_DEFAULT_MEM_SIZE
/ 2;
289 tbuf
+= sprintf (tbuf
, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
290 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
294 if (sc
.arg4
& 0x20 /*MAP_ANONYMOUS*/)
295 /* XXX: We don't handle zeroing, but default is all zeros. */;
296 else if (args
[4] >= MAX_CALLBACK_FDS
)
297 sc
.errcode
= TARGET_ENOSYS
;
301 char *data
= xmalloc (sc
.arg2
);
303 /* XXX: Should add a cb->pread. */
304 if (pread (cb
->fdmap
[args
[4]], data
, sc
.arg2
, args
[5] << 12) == sc
.arg2
)
305 sc
.write_mem (cb
, &sc
, heap
, data
, sc
.arg2
);
307 sc
.errcode
= TARGET_EINVAL
;
311 sc
.errcode
= TARGET_ENOSYS
;
323 /* Keep it page aligned. */
324 heap
= ALIGN (heap
, 4096);
330 /* XXX: meh, just lie for mmap(). */
331 tbuf
+= sprintf (tbuf
, "munmap(%#x, %u)", args
[0], args
[1]);
336 tbuf
+= sprintf (tbuf
, "dup2(%i, %i)", args
[0], args
[1]);
337 if (sc
.arg1
>= MAX_CALLBACK_FDS
|| sc
.arg2
>= MAX_CALLBACK_FDS
)
340 sc
.errcode
= TARGET_EINVAL
;
344 sc
.result
= dup2 (cb
->fdmap
[sc
.arg1
], cb
->fdmap
[sc
.arg2
]);
350 tbuf
+= sprintf (tbuf
, "llseek(%i, %u, %u, %#x, %u)",
351 args
[0], args
[1], args
[2], args
[3], args
[4]);
352 sc
.func
= TARGET_LINUX_SYS_lseek
;
356 sc
.errcode
= TARGET_EINVAL
;
362 cb_syscall (cb
, &sc
);
366 sc
.write_mem (cb
, &sc
, args
[3], (void *)&sc
.result
, 4);
367 sc
.write_mem (cb
, &sc
, args
[3] + 4, (void *)&z
, 4);
372 /* XXX: Should add a cb->pread. */
374 tbuf
+= sprintf (tbuf
, "pread(%i, %#x, %u, %i)",
375 args
[0], args
[1], args
[2], args
[3]);
376 if (sc
.arg1
>= MAX_CALLBACK_FDS
)
379 sc
.errcode
= TARGET_EINVAL
;
383 long old_pos
, read_result
, read_errcode
;
385 /* Get current filepos. */
386 sc
.func
= TARGET_LINUX_SYS_lseek
;
389 cb_syscall (cb
, &sc
);
394 /* Move to the new pos. */
395 sc
.func
= TARGET_LINUX_SYS_lseek
;
398 cb_syscall (cb
, &sc
);
403 sc
.func
= TARGET_LINUX_SYS_read
;
406 cb_syscall (cb
, &sc
);
407 read_result
= sc
.result
;
408 read_errcode
= sc
.errcode
;
410 /* Move back to the old pos. */
411 sc
.func
= TARGET_LINUX_SYS_lseek
;
414 cb_syscall (cb
, &sc
);
416 sc
.result
= read_result
;
417 sc
.errcode
= read_errcode
;
422 tbuf
+= sprintf (tbuf
, "getcwd(%#x, %u)", args
[0], args
[1]);
424 p
= alloca (sc
.arg2
);
425 if (getcwd (p
, sc
.arg2
) == NULL
)
428 sc
.errcode
= TARGET_EINVAL
;
432 sc
.write_mem (cb
, &sc
, sc
.arg1
, p
, sc
.arg2
);
438 tbuf
+= sprintf (tbuf
, "stat64(%#x, %u)", args
[0], args
[1]);
439 cb
->stat_map
= stat_map_64
;
440 sc
.func
= TARGET_LINUX_SYS_stat
;
441 cb_syscall (cb
, &sc
);
442 cb
->stat_map
= stat_map_32
;
445 tbuf
+= sprintf (tbuf
, "lstat64(%#x, %u)", args
[0], args
[1]);
446 cb
->stat_map
= stat_map_64
;
447 sc
.func
= TARGET_LINUX_SYS_lstat
;
448 cb_syscall (cb
, &sc
);
449 cb
->stat_map
= stat_map_32
;
452 tbuf
+= sprintf (tbuf
, "fstat64(%#x, %u)", args
[0], args
[1]);
453 cb
->stat_map
= stat_map_64
;
454 sc
.func
= TARGET_LINUX_SYS_fstat
;
455 cb_syscall (cb
, &sc
);
456 cb
->stat_map
= stat_map_32
;
459 case CB_SYS_ftruncate64
:
460 tbuf
+= sprintf (tbuf
, "ftruncate64(%u, %u)", args
[0], args
[1]);
461 sc
.func
= TARGET_LINUX_SYS_ftruncate
;
462 cb_syscall (cb
, &sc
);
466 case CB_SYS_getuid32
:
467 tbuf
+= sprintf (tbuf
, "getuid()");
468 sc
.result
= getuid ();
471 case CB_SYS_getgid32
:
472 tbuf
+= sprintf (tbuf
, "getgid()");
473 sc
.result
= getgid ();
477 case CB_SYS_setuid32
:
478 tbuf
+= sprintf (tbuf
, "setuid(%u)", args
[0]);
479 sc
.result
= setuid (sc
.arg1
);
483 case CB_SYS_setgid32
:
484 tbuf
+= sprintf (tbuf
, "setgid(%u)", args
[0]);
485 sc
.result
= setgid (sc
.arg1
);
489 tbuf
+= sprintf (tbuf
, "getpid()");
490 sc
.result
= getpid ();
493 tbuf
+= sprintf (tbuf
, "kill(%u, %i)", args
[0], args
[1]);
494 /* Only let the app kill itself. */
495 if (sc
.arg1
!= getpid ())
498 sc
.errcode
= TARGET_EPERM
;
503 sc
.result
= kill (sc
.arg1
, sc
.arg2
);
507 sc
.errcode
= TARGET_ENOSYS
;
513 tbuf
+= sprintf (tbuf
, "open(%#x, %#x, %o)", args
[0], args
[1], args
[2]);
516 tbuf
+= sprintf (tbuf
, "close(%i)", args
[0]);
519 tbuf
+= sprintf (tbuf
, "read(%i, %#x, %u)", args
[0], args
[1], args
[2]);
522 tbuf
+= sprintf (tbuf
, "write(%i, %#x, %u)", args
[0], args
[1], args
[2]);
525 tbuf
+= sprintf (tbuf
, "lseek(%i, %i, %i)", args
[0], args
[1], args
[2]);
528 tbuf
+= sprintf (tbuf
, "unlink(%#x)", args
[0]);
530 case CB_SYS_truncate
:
531 tbuf
+= sprintf (tbuf
, "truncate(%#x, %i)", args
[0], args
[1]);
533 case CB_SYS_ftruncate
:
534 tbuf
+= sprintf (tbuf
, "ftruncate(%i, %i)", args
[0], args
[1]);
537 tbuf
+= sprintf (tbuf
, "rename(%#x, %#x)", args
[0], args
[1]);
540 tbuf
+= sprintf (tbuf
, "stat(%#x, %#x)", args
[0], args
[1]);
543 tbuf
+= sprintf (tbuf
, "fstat(%i, %#x)", args
[0], args
[1]);
546 tbuf
+= sprintf (tbuf
, "lstat(%i, %#x)", args
[0], args
[1]);
549 tbuf
+= sprintf (tbuf
, "pipe(%#x, %#x)", args
[0], args
[1]);
553 tbuf
+= sprintf (tbuf
, "???_%i(%#x, %#x, %#x, %#x, %#x, %#x)", sc
.func
,
554 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
556 cb_syscall (cb
, &sc
);
562 cb
->last_errno
= errno
;
563 sc
.errcode
= cb
->get_errno (cb
);
567 TRACE_EVENTS (cpu
, "syscall_%i(%#x, %#x, %#x, %#x, %#x, %#x) = %li (error = %i)",
568 sc
.func
, args
[0], args
[1], args
[2], args
[3], args
[4], args
[5],
569 sc
.result
, sc
.errcode
);
571 tbuf
+= sprintf (tbuf
, " = ");
572 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
576 tbuf
+= sprintf (tbuf
, "-1 (error = %i)", sc
.errcode
);
577 if (sc
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
579 sim_io_eprintf (sd
, "bfin-sim: %#x: unimplemented syscall %i\n",
582 SET_DREG (0, -sc
.errcode
);
587 tbuf
+= sprintf (tbuf
, "%#lx", sc
.result
);
589 tbuf
+= sprintf (tbuf
, "%lu", sc
.result
);
590 SET_DREG (0, sc
.result
);
595 tbuf
+= sprintf (tbuf
, "%lu (error = %i)", sc
.result
, sc
.errcode
);
596 SET_DREG (0, sc
.result
);
597 /* Blackfin libgloss only expects R0 to be updated, not R1. */
598 /*SET_DREG (1, sc.errcode);*/
601 TRACE_SYSCALL (cpu
, "%s", _tbuf
);
605 trace_register (SIM_DESC sd
,
611 trace_printf (sd
, cpu
, "%s %s",
613 TRACE_PREFIX (CPU_TRACE_DATA (cpu
)));
615 trace_vprintf (sd
, cpu
, fmt
, ap
);
617 trace_printf (sd
, cpu
, "\n");
620 /* Execute a single instruction. */
623 step_once (SIM_CPU
*cpu
)
625 SIM_DESC sd
= CPU_STATE (cpu
);
626 bu32 insn_len
, oldpc
= PCREG
;
630 if (TRACE_ANY_P (cpu
))
631 trace_prefix (sd
, cpu
, NULL_CIA
, oldpc
, TRACE_LINENUM_P (cpu
),
632 NULL
, 0, " "); /* Use a space for gcc warnings. */
634 /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
635 has already had the SSSTEP bit enabled. */
637 if (STATE_ENVIRONMENT (sd
) == OPERATING_ENVIRONMENT
638 && (SYSCFGREG
& SYSCFG_SSSTEP
))
640 int ivg
= cec_get_ivg (cpu
);
641 if (ivg
== -1 || ivg
> 3)
646 /* XXX: Is this what happens on the hardware ? */
647 if (cec_get_ivg (cpu
) == EVT_EMU
)
648 cec_return (cpu
, EVT_EMU
);
651 BFIN_CPU_STATE
.did_jump
= false;
653 insn_len
= interp_insn_bfin (cpu
, oldpc
);
655 /* If we executed this insn successfully, then we always decrement
656 the loop counter. We don't want to update the PC though if the
657 last insn happened to be a change in code flow (jump/etc...). */
658 if (!BFIN_CPU_STATE
.did_jump
)
659 SET_PCREG (hwloop_get_next_pc (cpu
, oldpc
, insn_len
));
660 for (i
= 1; i
>= 0; --i
)
661 if (LCREG (i
) && oldpc
== LBREG (i
))
663 SET_LCREG (i
, LCREG (i
) - 1);
668 ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
));
670 /* Handle hardware single stepping only if we're still lower than EVT3.
671 XXX: May not be entirely correct wrt EXCPT insns. */
674 int ivg
= cec_get_ivg (cpu
);
675 if (ivg
== -1 || ivg
> 3)
678 cec_exception (cpu
, VEC_STEP
);
686 sim_engine_run (SIM_DESC sd
,
687 int next_cpu_nr
, /* ignore */
688 int nr_cpus
, /* ignore */
689 int siggnal
) /* ignore */
694 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
696 cpu
= STATE_CPU (sd
, 0);
701 /* Process any events -- can't use tickn because it may
702 advance right over the next event. */
703 for (ticks
= 0; ticks
< CYCLE_DELAY
; ++ticks
)
704 if (sim_events_tick (sd
))
705 sim_events_process (sd
);
709 /* Cover function of sim_state_free to free the cpu buffers as well. */
712 free_state (SIM_DESC sd
)
714 if (STATE_MODULES (sd
) != NULL
)
715 sim_module_uninstall (sd
);
716 sim_cpu_free_all (sd
);
720 /* Create an instance of the simulator. */
723 bfin_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
725 memset (&cpu
->state
, 0, sizeof (cpu
->state
));
727 PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
)) = 0;
729 bfin_model_cpu_init (sd
, cpu
);
731 /* Set default stack to top of scratch pad. */
732 SET_SPREG (BFIN_DEFAULT_MEM_SIZE
);
733 SET_KSPREG (BFIN_DEFAULT_MEM_SIZE
);
734 SET_USPREG (BFIN_DEFAULT_MEM_SIZE
);
736 /* This is what the hardware likes. */
737 SET_SYSCFGREG (0x30);
741 sim_open (SIM_OPEN_KIND kind
, host_callback
*callback
,
742 struct bfd
*abfd
, char **argv
)
746 SIM_DESC sd
= sim_state_alloc (kind
, callback
);
748 /* The cpu data is kept in a separately allocated chunk of memory. */
749 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
756 /* XXX: Only first core gets profiled ? */
757 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
758 STATE_WATCHPOINTS (sd
)->pc
= &PCREG
;
759 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (PCREG
);
762 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
768 /* XXX: Default to the Virtual environment. */
769 if (STATE_ENVIRONMENT (sd
) == ALL_ENVIRONMENT
)
770 STATE_ENVIRONMENT (sd
) = VIRTUAL_ENVIRONMENT
;
772 /* These options override any module options.
773 Obviously ambiguity should be avoided, however the caller may wish to
774 augment the meaning of an option. */
775 #define e_sim_add_option_table(sd, options) \
777 extern const OPTION options[]; \
778 sim_add_option_table (sd, NULL, options); \
780 e_sim_add_option_table (sd
, bfin_mmu_options
);
781 e_sim_add_option_table (sd
, bfin_mach_options
);
783 /* getopt will print the error message so we just have to exit if this fails.
784 FIXME: Hmmm... in the case of gdb we need getopt to call
786 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
792 /* Allocate external memory if none specified by user.
793 Use address 4 here in case the user wanted address 0 unmapped. */
794 if (sim_core_read_buffer (sd
, NULL
, read_map
, &c
, 4, 1) == 0)
796 bu16 emuexcpt
= 0x25;
797 sim_do_commandf (sd
, "memory-size 0x%lx", BFIN_DEFAULT_MEM_SIZE
);
798 sim_write (sd
, 0, (void *)&emuexcpt
, 2);
801 /* Check for/establish the a reference program image. */
802 if (sim_analyze_program (sd
,
803 (STATE_PROG_ARGV (sd
) != NULL
804 ? *STATE_PROG_ARGV (sd
)
805 : NULL
), abfd
) != SIM_RC_OK
)
811 /* Establish any remaining configuration options. */
812 if (sim_config (sd
) != SIM_RC_OK
)
818 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
824 /* CPU specific initialization. */
825 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
827 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
828 bfin_initialize_cpu (sd
, cpu
);
835 sim_close (SIM_DESC sd
, int quitting
)
837 sim_module_uninstall (sd
);
840 /* Some utils don't like having a NULL environ. */
841 static const char * const simple_env
[] = { "HOME=/", "PATH=/bin", NULL
};
843 static bu32 fdpic_load_offset
;
846 bfin_fdpic_load (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
, bu32
*sp
,
847 bu32
*elf_addrs
, char **ldso_path
)
852 Elf_Internal_Ehdr
*iehdr
;
853 Elf32_External_Ehdr ehdr
;
854 Elf_Internal_Phdr
*phdrs
;
862 unsigned char null
[4] = { 0, 0, 0, 0 };
867 /* See if this an FDPIC ELF. */
870 goto skip_fdpic_init
;
871 if (bfd_seek (abfd
, 0, SEEK_SET
) != 0)
872 goto skip_fdpic_init
;
873 if (bfd_bread (&ehdr
, sizeof (ehdr
), abfd
) != sizeof (ehdr
))
874 goto skip_fdpic_init
;
875 iehdr
= elf_elfheader (abfd
);
876 if (!(iehdr
->e_flags
& EF_BFIN_FDPIC
))
877 goto skip_fdpic_init
;
879 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
880 sim_io_printf (sd
, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
881 bfd_get_filename (abfd
), fdpic_load_offset
, elf_addrs
[0]);
883 /* Grab the Program Headers to set up the loadsegs on the stack. */
884 phdr_size
= bfd_get_elf_phdr_upper_bound (abfd
);
886 goto skip_fdpic_init
;
887 phdrs
= xmalloc (phdr_size
);
888 phdrc
= bfd_get_elf_phdrs (abfd
, phdrs
);
890 goto skip_fdpic_init
;
892 /* Push the Ehdr onto the stack. */
893 *sp
-= sizeof (ehdr
);
895 sim_write (sd
, *sp
, (void *)&ehdr
, sizeof (ehdr
));
896 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
897 sim_io_printf (sd
, " Elf_Ehdr: %#x\n", *sp
);
899 /* Since we're relocating things ourselves, we need to relocate
900 the start address as well. */
901 elf_addrs
[0] = bfd_get_start_address (abfd
) + fdpic_load_offset
;
903 /* And the Exec's Phdrs onto the stack. */
904 if (STATE_PROG_BFD (sd
) == abfd
)
906 elf_addrs
[4] = elf_addrs
[0];
908 phdr_size
= iehdr
->e_phentsize
* iehdr
->e_phnum
;
909 if (bfd_seek (abfd
, iehdr
->e_phoff
, SEEK_SET
) != 0)
910 goto skip_fdpic_init
;
911 data
= xmalloc (phdr_size
);
912 if (bfd_bread (data
, phdr_size
, abfd
) != phdr_size
)
913 goto skip_fdpic_init
;
916 elf_addrs
[2] = phdrc
;
917 sim_write (sd
, *sp
, data
, phdr_size
);
919 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
920 sim_io_printf (sd
, " Elf_Phdrs: %#x\n", *sp
);
923 /* Now push all the loadsegs. */
926 for (i
= phdrc
; i
>= 0; --i
)
927 if (phdrs
[i
].p_type
== PT_LOAD
)
929 Elf_Internal_Phdr
*p
= &phdrs
[i
];
930 bu32 paddr
, vaddr
, memsz
, filesz
;
932 paddr
= p
->p_paddr
+ fdpic_load_offset
;
935 filesz
= p
->p_filesz
;
937 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
938 sim_io_printf (sd
, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
939 i
, vaddr
, paddr
, filesz
, memsz
);
941 data
= xmalloc (memsz
);
943 memset (data
+ filesz
, 0, memsz
- filesz
);
945 if (bfd_seek (abfd
, p
->p_offset
, SEEK_SET
) == 0
946 && bfd_bread (data
, filesz
, abfd
) == filesz
)
947 sim_write (sd
, paddr
, data
, memsz
);
951 max_load_addr
= MAX (paddr
+ memsz
, max_load_addr
);
954 sim_write (sd
, *sp
+0, (void *)&paddr
, 4); /* loadseg.addr */
955 sim_write (sd
, *sp
+4, (void *)&vaddr
, 4); /* loadseg.p_vaddr */
956 sim_write (sd
, *sp
+8, (void *)&memsz
, 4); /* loadseg.p_memsz */
959 else if (phdrs
[i
].p_type
== PT_DYNAMIC
)
961 elf_addrs
[5] = phdrs
[i
].p_paddr
+ fdpic_load_offset
;
962 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
963 sim_io_printf (sd
, " PT_DYNAMIC: %#x\n", elf_addrs
[5]);
965 else if (phdrs
[i
].p_type
== PT_INTERP
)
967 uint32_t off
= phdrs
[i
].p_offset
;
968 uint32_t len
= phdrs
[i
].p_filesz
;
970 *ldso_path
= xmalloc (len
);
971 if (bfd_seek (abfd
, off
, SEEK_SET
) != 0
972 || bfd_bread (*ldso_path
, len
, abfd
) != len
)
977 else if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
978 sim_io_printf (sd
, " PT_INTERP: %s\n", *ldso_path
);
981 /* Update the load offset with a few extra pages. */
982 fdpic_load_offset
= ALIGN (MAX (max_load_addr
, fdpic_load_offset
), 0x10000);
983 fdpic_load_offset
+= 0x10000;
985 /* Push the summary loadmap info onto the stack last. */
987 sim_write (sd
, *sp
+0, null
, 2); /* loadmap.version */
988 sim_write (sd
, *sp
+2, (void *)&nsegs
, 2); /* loadmap.nsegs */
998 bfin_user_init (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
,
999 const char * const *argv
, const char * const *env
)
1001 /* XXX: Missing host -> target endian ... */
1002 /* Linux starts the user app with the stack:
1004 argv[0] -- pointers to the actual strings
1010 auxvt[0].type -- ELF Auxiliary Vector Table
1015 argv[0..N][0..M] -- actual argv/env strings
1017 FDPIC loadmaps -- for FDPIC apps
1018 So set things up the same way. */
1020 bu32 argv_flat
, env_flat
;
1024 /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
1026 bu32 auxvt
, auxvt_size
;
1027 bu32 exec_loadmap
, ldso_loadmap
;
1030 unsigned char null
[4] = { 0, 0, 0, 0 };
1032 host_callback
*cb
= STATE_CALLBACK (sd
);
1034 elf_addrs
[0] = elf_addrs
[4] = bfd_get_start_address (abfd
);
1035 elf_addrs
[1] = elf_addrs
[2] = elf_addrs
[3] = elf_addrs
[5] = 0;
1037 /* Keep the load addresses consistent between runs. Also make sure we make
1038 space for the fixed code region (part of the Blackfin Linux ABI). */
1039 fdpic_load_offset
= 0x1000;
1041 /* First try to load this as an FDPIC executable. */
1043 if (!bfin_fdpic_load (sd
, cpu
, STATE_PROG_BFD (sd
), &sp
, elf_addrs
, &ldso_path
))
1044 goto skip_fdpic_init
;
1047 /* If that worked, then load the fixed code region. We only do this for
1048 FDPIC ELFs atm because they are PIEs and let us relocate them without
1049 manual fixups. FLAT files however require location processing which
1050 we do not do ourselves, and they link with a VMA of 0. */
1051 sim_write (sd
, 0x400, bfin_linux_fixed_code
, sizeof (bfin_linux_fixed_code
));
1053 /* If the FDPIC needs an interpreter, then load it up too. */
1056 const char *ldso_full_path
= concat (simulator_sysroot
, ldso_path
, NULL
);
1057 struct bfd
*ldso_bfd
;
1059 ldso_bfd
= bfd_openr (ldso_full_path
, STATE_TARGET (sd
));
1062 sim_io_eprintf (sd
, "bfin-sim: bfd open failed: %s\n", ldso_full_path
);
1065 if (!bfd_check_format (ldso_bfd
, bfd_object
))
1066 sim_io_eprintf (sd
, "bfin-sim: bfd format not valid: %s\n", ldso_full_path
);
1067 bfd_set_arch_info (ldso_bfd
, STATE_ARCHITECTURE (sd
));
1069 if (!bfin_fdpic_load (sd
, cpu
, ldso_bfd
, &sp
, elf_addrs
, &ldso_path
))
1070 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path
);
1072 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
1073 ldso_full_path
, ldso_path
);
1081 /* Finally setup the registers required by the FDPIC ABI. */
1082 SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up. */
1083 SET_PREG (0, exec_loadmap
); /* Exec loadmap addr. */
1084 SET_PREG (1, ldso_loadmap
); /* Interp loadmap addr. */
1085 SET_PREG (2, elf_addrs
[5]); /* PT_DYNAMIC map addr. */
1090 sim_pc_set (cpu
, elf_addrs
[0]);
1092 /* Figure out how much storage the argv/env strings need. */
1093 argc
= count_argc (argv
);
1096 argv_flat
= argc
; /* NUL bytes */
1097 for (i
= 0; i
< argc
; ++i
)
1098 argv_flat
+= strlen (argv
[i
]);
1102 envc
= count_argc (env
);
1103 env_flat
= envc
; /* NUL bytes */
1104 for (i
= 0; i
< envc
; ++i
)
1105 env_flat
+= strlen (env
[i
]);
1107 /* Push the Auxiliary Vector Table between argv/env and actual strings. */
1108 sp_flat
= sp
= ALIGN (SPREG
- argv_flat
- env_flat
- 4, 4);
1111 # define AT_PUSH(at, val) \
1115 sim_write (sd, sp, (void *)&auxvt, 4); \
1118 sim_write (sd, sp, (void *)&auxvt, 4)
1120 unsigned int egid
= getegid (), gid
= getgid ();
1121 unsigned int euid
= geteuid (), uid
= getuid ();
1122 AT_PUSH (AT_NULL
, 0);
1123 AT_PUSH (AT_SECURE
, egid
!= gid
|| euid
!= uid
);
1124 AT_PUSH (AT_EGID
, egid
);
1125 AT_PUSH (AT_GID
, gid
);
1126 AT_PUSH (AT_EUID
, euid
);
1127 AT_PUSH (AT_UID
, uid
);
1128 AT_PUSH (AT_ENTRY
, elf_addrs
[4]);
1129 AT_PUSH (AT_FLAGS
, 0);
1130 AT_PUSH (AT_BASE
, elf_addrs
[3]);
1131 AT_PUSH (AT_PHNUM
, elf_addrs
[2]);
1132 AT_PUSH (AT_PHENT
, sizeof (Elf32_External_Phdr
));
1133 AT_PUSH (AT_PHDR
, elf_addrs
[1]);
1134 AT_PUSH (AT_CLKTCK
, 100); /* XXX: This ever not 100 ? */
1135 AT_PUSH (AT_PAGESZ
, 4096);
1136 AT_PUSH (AT_HWCAP
, 0);
1141 /* Push the argc/argv/env after the auxvt. */
1142 sp
-= ((1 + argc
+ 1 + envc
+ 1) * 4);
1145 /* First push the argc value. */
1146 sim_write (sd
, sp
, (void *)&argc
, 4);
1149 /* Then the actual argv strings so we know where to point argv[]. */
1150 for (i
= 0; i
< argc
; ++i
)
1152 unsigned len
= strlen (argv
[i
]) + 1;
1153 sim_write (sd
, sp_flat
, (void *)argv
[i
], len
);
1154 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1158 sim_write (sd
, sp
, null
, 4);
1161 /* Then the actual env strings so we know where to point env[]. */
1162 for (i
= 0; i
< envc
; ++i
)
1164 unsigned len
= strlen (env
[i
]) + 1;
1165 sim_write (sd
, sp_flat
, (void *)env
[i
], len
);
1166 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1171 /* Set some callbacks. */
1172 cb
->syscall_map
= cb_linux_syscall_map
;
1173 cb
->errno_map
= cb_linux_errno_map
;
1174 cb
->open_map
= cb_linux_open_map
;
1175 cb
->signal_map
= cb_linux_signal_map
;
1176 cb
->stat_map
= stat_map_32
;
1180 bfin_os_init (SIM_DESC sd
, SIM_CPU
*cpu
, const char * const *argv
)
1182 /* Pass the command line via a string in R0 like Linux expects. */
1185 bu32 cmdline
= BFIN_L1_SRAM_SCRATCH
;
1187 SET_DREG (0, cmdline
);
1188 if (argv
&& argv
[0])
1194 bu32 len
= strlen (argv
[i
]);
1195 sim_write (sd
, cmdline
, (void *)argv
[i
], len
);
1197 sim_write (sd
, cmdline
, &byte
, 1);
1203 sim_write (sd
, cmdline
, &byte
, 1);
1207 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
1208 char **argv
, char **env
)
1210 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
1215 addr
= bfd_get_start_address (abfd
);
1218 sim_pc_set (cpu
, addr
);
1220 /* Standalone mode (i.e. `bfin-...-run`) will take care of the argv
1221 for us in sim_open() -> sim_parse_args(). But in debug mode (i.e.
1222 'target sim' with `bfin-...-gdb`), we need to handle it. */
1223 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
1225 free (STATE_PROG_ARGV (sd
));
1226 STATE_PROG_ARGV (sd
) = dupargv (argv
);
1229 switch (STATE_ENVIRONMENT (sd
))
1231 case USER_ENVIRONMENT
:
1232 bfin_user_init (sd
, cpu
, abfd
, (void *)argv
, (void *)env
);
1234 case OPERATING_ENVIRONMENT
:
1235 bfin_os_init (sd
, cpu
, (void *)argv
);
1238 /* Nothing to do for virtual/all envs. */
1246 sim_do_command (SIM_DESC sd
, char *cmd
)
1248 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
1249 sim_io_eprintf (sd
, "Unknown command `%s'\n", cmd
);