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
;
300 char *data
= xmalloc (sc
.arg2
);
302 /* XXX: Should add a cb->pread. */
303 if (pread (cb
->fdmap
[args
[4]], data
, sc
.arg2
, args
[5] << 12) == sc
.arg2
)
304 sc
.write_mem (cb
, &sc
, heap
, data
, sc
.arg2
);
306 sc
.errcode
= TARGET_EINVAL
;
319 /* Keep it page aligned. */
320 heap
= ALIGN (heap
, 4096);
326 /* XXX: meh, just lie for mmap(). */
327 tbuf
+= sprintf (tbuf
, "munmap(%#x, %u)", args
[0], args
[1]);
332 tbuf
+= sprintf (tbuf
, "dup2(%i, %i)", args
[0], args
[1]);
333 if (sc
.arg1
>= MAX_CALLBACK_FDS
|| sc
.arg2
>= MAX_CALLBACK_FDS
)
336 sc
.errcode
= TARGET_EINVAL
;
340 sc
.result
= dup2 (cb
->fdmap
[sc
.arg1
], cb
->fdmap
[sc
.arg2
]);
346 tbuf
+= sprintf (tbuf
, "llseek(%i, %u, %u, %#x, %u)",
347 args
[0], args
[1], args
[2], args
[3], args
[4]);
348 sc
.func
= TARGET_LINUX_SYS_lseek
;
352 sc
.errcode
= TARGET_EINVAL
;
358 cb_syscall (cb
, &sc
);
362 sc
.write_mem (cb
, &sc
, args
[3], (void *)&sc
.result
, 4);
363 sc
.write_mem (cb
, &sc
, args
[3] + 4, (void *)&z
, 4);
368 /* XXX: Should add a cb->pread. */
370 tbuf
+= sprintf (tbuf
, "pread(%i, %#x, %u, %i)",
371 args
[0], args
[1], args
[2], args
[3]);
372 if (sc
.arg1
>= MAX_CALLBACK_FDS
)
375 sc
.errcode
= TARGET_EINVAL
;
379 long old_pos
, read_result
, read_errcode
;
381 /* Get current filepos. */
382 sc
.func
= TARGET_LINUX_SYS_lseek
;
385 cb_syscall (cb
, &sc
);
390 /* Move to the new pos. */
391 sc
.func
= TARGET_LINUX_SYS_lseek
;
394 cb_syscall (cb
, &sc
);
399 sc
.func
= TARGET_LINUX_SYS_read
;
402 cb_syscall (cb
, &sc
);
403 read_result
= sc
.result
;
404 read_errcode
= sc
.errcode
;
406 /* Move back to the old pos. */
407 sc
.func
= TARGET_LINUX_SYS_lseek
;
410 cb_syscall (cb
, &sc
);
412 sc
.result
= read_result
;
413 sc
.errcode
= read_errcode
;
418 tbuf
+= sprintf (tbuf
, "getcwd(%#x, %u)", args
[0], args
[1]);
420 p
= alloca (sc
.arg2
);
421 if (getcwd (p
, sc
.arg2
) == NULL
)
424 sc
.errcode
= TARGET_EINVAL
;
428 sc
.write_mem (cb
, &sc
, sc
.arg1
, p
, sc
.arg2
);
434 tbuf
+= sprintf (tbuf
, "stat64(%#x, %u)", args
[0], args
[1]);
435 cb
->stat_map
= stat_map_64
;
436 sc
.func
= TARGET_LINUX_SYS_stat
;
437 cb_syscall (cb
, &sc
);
438 cb
->stat_map
= stat_map_32
;
441 tbuf
+= sprintf (tbuf
, "lstat64(%#x, %u)", args
[0], args
[1]);
442 cb
->stat_map
= stat_map_64
;
443 sc
.func
= TARGET_LINUX_SYS_lstat
;
444 cb_syscall (cb
, &sc
);
445 cb
->stat_map
= stat_map_32
;
448 tbuf
+= sprintf (tbuf
, "fstat64(%#x, %u)", args
[0], args
[1]);
449 cb
->stat_map
= stat_map_64
;
450 sc
.func
= TARGET_LINUX_SYS_fstat
;
451 cb_syscall (cb
, &sc
);
452 cb
->stat_map
= stat_map_32
;
455 case CB_SYS_ftruncate64
:
456 tbuf
+= sprintf (tbuf
, "ftruncate64(%u, %u)", args
[0], args
[1]);
457 sc
.func
= TARGET_LINUX_SYS_ftruncate
;
458 cb_syscall (cb
, &sc
);
462 case CB_SYS_getuid32
:
463 tbuf
+= sprintf (tbuf
, "getuid()");
464 sc
.result
= getuid ();
467 case CB_SYS_getgid32
:
468 tbuf
+= sprintf (tbuf
, "getgid()");
469 sc
.result
= getgid ();
473 case CB_SYS_setuid32
:
474 tbuf
+= sprintf (tbuf
, "setuid(%u)", args
[0]);
475 sc
.result
= setuid (sc
.arg1
);
479 case CB_SYS_setgid32
:
480 tbuf
+= sprintf (tbuf
, "setgid(%u)", args
[0]);
481 sc
.result
= setgid (sc
.arg1
);
485 tbuf
+= sprintf (tbuf
, "getpid()");
486 sc
.result
= getpid ();
489 tbuf
+= sprintf (tbuf
, "kill(%u, %i)", args
[0], args
[1]);
490 /* Only let the app kill itself. */
491 if (sc
.arg1
!= getpid ())
494 sc
.errcode
= TARGET_EPERM
;
498 sc
.result
= kill (sc
.arg1
, sc
.arg2
);
504 tbuf
+= sprintf (tbuf
, "open(%#x, %#x, %o)", args
[0], args
[1], args
[2]);
507 tbuf
+= sprintf (tbuf
, "close(%i)", args
[0]);
510 tbuf
+= sprintf (tbuf
, "read(%i, %#x, %u)", args
[0], args
[1], args
[2]);
513 tbuf
+= sprintf (tbuf
, "write(%i, %#x, %u)", args
[0], args
[1], args
[2]);
516 tbuf
+= sprintf (tbuf
, "lseek(%i, %i, %i)", args
[0], args
[1], args
[2]);
519 tbuf
+= sprintf (tbuf
, "unlink(%#x)", args
[0]);
521 case CB_SYS_truncate
:
522 tbuf
+= sprintf (tbuf
, "truncate(%#x, %i)", args
[0], args
[1]);
524 case CB_SYS_ftruncate
:
525 tbuf
+= sprintf (tbuf
, "ftruncate(%i, %i)", args
[0], args
[1]);
528 tbuf
+= sprintf (tbuf
, "rename(%#x, %#x)", args
[0], args
[1]);
531 tbuf
+= sprintf (tbuf
, "stat(%#x, %#x)", args
[0], args
[1]);
534 tbuf
+= sprintf (tbuf
, "fstat(%i, %#x)", args
[0], args
[1]);
537 tbuf
+= sprintf (tbuf
, "lstat(%i, %#x)", args
[0], args
[1]);
540 tbuf
+= sprintf (tbuf
, "pipe(%#x, %#x)", args
[0], args
[1]);
544 tbuf
+= sprintf (tbuf
, "???_%i(%#x, %#x, %#x, %#x, %#x, %#x)", sc
.func
,
545 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
547 cb_syscall (cb
, &sc
);
553 cb
->last_errno
= errno
;
554 sc
.errcode
= cb
->get_errno (cb
);
558 TRACE_EVENTS (cpu
, "syscall_%i(%#x, %#x, %#x, %#x, %#x, %#x) = %li (error = %i)",
559 sc
.func
, args
[0], args
[1], args
[2], args
[3], args
[4], args
[5],
560 sc
.result
, sc
.errcode
);
562 tbuf
+= sprintf (tbuf
, " = ");
563 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
567 tbuf
+= sprintf (tbuf
, "-1 (error = %i)", sc
.errcode
);
568 if (sc
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
570 sim_io_eprintf (sd
, "bfin-sim: %#x: unimplemented syscall %i\n",
573 SET_DREG (0, -sc
.errcode
);
578 tbuf
+= sprintf (tbuf
, "%#lx", sc
.result
);
580 tbuf
+= sprintf (tbuf
, "%lu", sc
.result
);
581 SET_DREG (0, sc
.result
);
586 tbuf
+= sprintf (tbuf
, "%lu (error = %i)", sc
.result
, sc
.errcode
);
587 SET_DREG (0, sc
.result
);
588 /* Blackfin libgloss only expects R0 to be updated, not R1. */
589 /*SET_DREG (1, sc.errcode);*/
592 TRACE_SYSCALL (cpu
, "%s", _tbuf
);
596 trace_register (SIM_DESC sd
,
602 trace_printf (sd
, cpu
, "%s %s",
604 TRACE_PREFIX (CPU_TRACE_DATA (cpu
)));
606 trace_vprintf (sd
, cpu
, fmt
, ap
);
608 trace_printf (sd
, cpu
, "\n");
611 /* Execute a single instruction. */
614 step_once (SIM_CPU
*cpu
)
616 SIM_DESC sd
= CPU_STATE (cpu
);
617 bu32 insn_len
, oldpc
= PCREG
;
621 if (TRACE_ANY_P (cpu
))
622 trace_prefix (sd
, cpu
, NULL_CIA
, oldpc
, TRACE_LINENUM_P (cpu
),
623 NULL
, 0, " "); /* Use a space for gcc warnings. */
625 /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
626 has already had the SSSTEP bit enabled. */
628 if (STATE_ENVIRONMENT (sd
) == OPERATING_ENVIRONMENT
629 && (SYSCFGREG
& SYSCFG_SSSTEP
))
631 int ivg
= cec_get_ivg (cpu
);
632 if (ivg
== -1 || ivg
> 3)
637 /* XXX: Is this what happens on the hardware ? */
638 if (cec_get_ivg (cpu
) == EVT_EMU
)
639 cec_return (cpu
, EVT_EMU
);
642 BFIN_CPU_STATE
.did_jump
= false;
644 insn_len
= interp_insn_bfin (cpu
, oldpc
);
646 /* If we executed this insn successfully, then we always decrement
647 the loop counter. We don't want to update the PC though if the
648 last insn happened to be a change in code flow (jump/etc...). */
649 if (!BFIN_CPU_STATE
.did_jump
)
650 SET_PCREG (hwloop_get_next_pc (cpu
, oldpc
, insn_len
));
651 for (i
= 1; i
>= 0; --i
)
652 if (LCREG (i
) && oldpc
== LBREG (i
))
654 SET_LCREG (i
, LCREG (i
) - 1);
659 ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
));
661 /* Handle hardware single stepping only if we're still lower than EVT3.
662 XXX: May not be entirely correct wrt EXCPT insns. */
665 int ivg
= cec_get_ivg (cpu
);
666 if (ivg
== -1 || ivg
> 3)
669 cec_exception (cpu
, VEC_STEP
);
677 sim_engine_run (SIM_DESC sd
,
678 int next_cpu_nr
, /* ignore */
679 int nr_cpus
, /* ignore */
680 int siggnal
) /* ignore */
685 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
687 cpu
= STATE_CPU (sd
, 0);
692 /* Process any events -- can't use tickn because it may
693 advance right over the next event. */
694 for (ticks
= 0; ticks
< CYCLE_DELAY
; ++ticks
)
695 if (sim_events_tick (sd
))
696 sim_events_process (sd
);
700 /* Cover function of sim_state_free to free the cpu buffers as well. */
703 free_state (SIM_DESC sd
)
705 if (STATE_MODULES (sd
) != NULL
)
706 sim_module_uninstall (sd
);
707 sim_cpu_free_all (sd
);
711 /* Create an instance of the simulator. */
714 bfin_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
716 memset (&cpu
->state
, 0, sizeof (cpu
->state
));
718 PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
)) = 0;
720 bfin_model_cpu_init (sd
, cpu
);
722 /* Set default stack to top of scratch pad. */
723 SET_SPREG (BFIN_DEFAULT_MEM_SIZE
);
724 SET_KSPREG (BFIN_DEFAULT_MEM_SIZE
);
725 SET_USPREG (BFIN_DEFAULT_MEM_SIZE
);
727 /* This is what the hardware likes. */
728 SET_SYSCFGREG (0x30);
732 sim_open (SIM_OPEN_KIND kind
, host_callback
*callback
,
733 struct bfd
*abfd
, char **argv
)
737 SIM_DESC sd
= sim_state_alloc (kind
, callback
);
739 /* The cpu data is kept in a separately allocated chunk of memory. */
740 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
747 /* XXX: Only first core gets profiled ? */
748 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
749 STATE_WATCHPOINTS (sd
)->pc
= &PCREG
;
750 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (PCREG
);
753 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
759 /* XXX: Default to the Virtual environment. */
760 if (STATE_ENVIRONMENT (sd
) == ALL_ENVIRONMENT
)
761 STATE_ENVIRONMENT (sd
) = VIRTUAL_ENVIRONMENT
;
763 /* These options override any module options.
764 Obviously ambiguity should be avoided, however the caller may wish to
765 augment the meaning of an option. */
766 #define e_sim_add_option_table(sd, options) \
768 extern const OPTION options[]; \
769 sim_add_option_table (sd, NULL, options); \
771 e_sim_add_option_table (sd
, bfin_mmu_options
);
772 e_sim_add_option_table (sd
, bfin_mach_options
);
774 /* getopt will print the error message so we just have to exit if this fails.
775 FIXME: Hmmm... in the case of gdb we need getopt to call
777 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
783 /* Allocate external memory if none specified by user.
784 Use address 4 here in case the user wanted address 0 unmapped. */
785 if (sim_core_read_buffer (sd
, NULL
, read_map
, &c
, 4, 1) == 0)
787 bu16 emuexcpt
= 0x25;
788 sim_do_commandf (sd
, "memory-size 0x%lx", BFIN_DEFAULT_MEM_SIZE
);
789 sim_write (sd
, 0, (void *)&emuexcpt
, 2);
792 /* Check for/establish the a reference program image. */
793 if (sim_analyze_program (sd
,
794 (STATE_PROG_ARGV (sd
) != NULL
795 ? *STATE_PROG_ARGV (sd
)
796 : NULL
), abfd
) != SIM_RC_OK
)
802 /* Establish any remaining configuration options. */
803 if (sim_config (sd
) != SIM_RC_OK
)
809 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
815 /* CPU specific initialization. */
816 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
818 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
819 bfin_initialize_cpu (sd
, cpu
);
826 sim_close (SIM_DESC sd
, int quitting
)
828 sim_module_uninstall (sd
);
831 /* Some utils don't like having a NULL environ. */
832 static const char * const simple_env
[] = { "HOME=/", "PATH=/bin", NULL
};
834 static bu32 fdpic_load_offset
;
837 bfin_fdpic_load (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
, bu32
*sp
,
838 bu32
*elf_addrs
, char **ldso_path
)
843 Elf_Internal_Ehdr
*iehdr
;
844 Elf32_External_Ehdr ehdr
;
845 Elf_Internal_Phdr
*phdrs
;
853 unsigned char null
[4] = { 0, 0, 0, 0 };
858 /* See if this an FDPIC ELF. */
861 goto skip_fdpic_init
;
862 if (bfd_seek (abfd
, 0, SEEK_SET
) != 0)
863 goto skip_fdpic_init
;
864 if (bfd_bread (&ehdr
, sizeof (ehdr
), abfd
) != sizeof (ehdr
))
865 goto skip_fdpic_init
;
866 iehdr
= elf_elfheader (abfd
);
867 if (!(iehdr
->e_flags
& EF_BFIN_FDPIC
))
868 goto skip_fdpic_init
;
870 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
871 sim_io_printf (sd
, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
872 bfd_get_filename (abfd
), fdpic_load_offset
, elf_addrs
[0]);
874 /* Grab the Program Headers to set up the loadsegs on the stack. */
875 phdr_size
= bfd_get_elf_phdr_upper_bound (abfd
);
877 goto skip_fdpic_init
;
878 phdrs
= xmalloc (phdr_size
);
879 phdrc
= bfd_get_elf_phdrs (abfd
, phdrs
);
881 goto skip_fdpic_init
;
883 /* Push the Ehdr onto the stack. */
884 *sp
-= sizeof (ehdr
);
886 sim_write (sd
, *sp
, (void *)&ehdr
, sizeof (ehdr
));
887 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
888 sim_io_printf (sd
, " Elf_Ehdr: %#x\n", *sp
);
890 /* Since we're relocating things ourselves, we need to relocate
891 the start address as well. */
892 elf_addrs
[0] = bfd_get_start_address (abfd
) + fdpic_load_offset
;
894 /* And the Exec's Phdrs onto the stack. */
895 if (STATE_PROG_BFD (sd
) == abfd
)
897 elf_addrs
[4] = elf_addrs
[0];
899 phdr_size
= iehdr
->e_phentsize
* iehdr
->e_phnum
;
900 if (bfd_seek (abfd
, iehdr
->e_phoff
, SEEK_SET
) != 0)
901 goto skip_fdpic_init
;
902 data
= xmalloc (phdr_size
);
903 if (bfd_bread (data
, phdr_size
, abfd
) != phdr_size
)
904 goto skip_fdpic_init
;
907 elf_addrs
[2] = phdrc
;
908 sim_write (sd
, *sp
, data
, phdr_size
);
910 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
911 sim_io_printf (sd
, " Elf_Phdrs: %#x\n", *sp
);
914 /* Now push all the loadsegs. */
917 for (i
= phdrc
; i
>= 0; --i
)
918 if (phdrs
[i
].p_type
== PT_LOAD
)
920 Elf_Internal_Phdr
*p
= &phdrs
[i
];
921 bu32 paddr
, vaddr
, memsz
, filesz
;
923 paddr
= p
->p_paddr
+ fdpic_load_offset
;
926 filesz
= p
->p_filesz
;
928 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
929 sim_io_printf (sd
, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
930 i
, vaddr
, paddr
, filesz
, memsz
);
932 data
= xmalloc (memsz
);
934 memset (data
+ filesz
, 0, memsz
- filesz
);
936 if (bfd_seek (abfd
, p
->p_offset
, SEEK_SET
) == 0
937 && bfd_bread (data
, filesz
, abfd
) == filesz
)
938 sim_write (sd
, paddr
, data
, memsz
);
942 max_load_addr
= MAX (paddr
+ memsz
, max_load_addr
);
945 sim_write (sd
, *sp
+0, (void *)&paddr
, 4); /* loadseg.addr */
946 sim_write (sd
, *sp
+4, (void *)&vaddr
, 4); /* loadseg.p_vaddr */
947 sim_write (sd
, *sp
+8, (void *)&memsz
, 4); /* loadseg.p_memsz */
950 else if (phdrs
[i
].p_type
== PT_DYNAMIC
)
952 elf_addrs
[5] = phdrs
[i
].p_paddr
+ fdpic_load_offset
;
953 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
954 sim_io_printf (sd
, " PT_DYNAMIC: %#x\n", elf_addrs
[5]);
956 else if (phdrs
[i
].p_type
== PT_INTERP
)
958 uint32_t off
= phdrs
[i
].p_offset
;
959 uint32_t len
= phdrs
[i
].p_filesz
;
961 *ldso_path
= xmalloc (len
);
962 if (bfd_seek (abfd
, off
, SEEK_SET
) != 0
963 || bfd_bread (*ldso_path
, len
, abfd
) != len
)
968 else if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
969 sim_io_printf (sd
, " PT_INTERP: %s\n", *ldso_path
);
972 /* Update the load offset with a few extra pages. */
973 fdpic_load_offset
= ALIGN (MAX (max_load_addr
, fdpic_load_offset
), 0x10000);
974 fdpic_load_offset
+= 0x10000;
976 /* Push the summary loadmap info onto the stack last. */
978 sim_write (sd
, *sp
+0, null
, 2); /* loadmap.version */
979 sim_write (sd
, *sp
+2, (void *)&nsegs
, 2); /* loadmap.nsegs */
989 bfin_user_init (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
,
990 const char * const *argv
, const char * const *env
)
992 /* XXX: Missing host -> target endian ... */
993 /* Linux starts the user app with the stack:
995 argv[0] -- pointers to the actual strings
1001 auxvt[0].type -- ELF Auxiliary Vector Table
1006 argv[0..N][0..M] -- actual argv/env strings
1008 FDPIC loadmaps -- for FDPIC apps
1009 So set things up the same way. */
1011 bu32 argv_flat
, env_flat
;
1015 /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
1017 bu32 auxvt
, auxvt_size
;
1018 bu32 exec_loadmap
, ldso_loadmap
;
1021 unsigned char null
[4] = { 0, 0, 0, 0 };
1023 host_callback
*cb
= STATE_CALLBACK (sd
);
1025 elf_addrs
[0] = elf_addrs
[4] = bfd_get_start_address (abfd
);
1026 elf_addrs
[1] = elf_addrs
[2] = elf_addrs
[3] = elf_addrs
[5] = 0;
1028 /* Keep the load addresses consistent between runs. Also make sure we make
1029 space for the fixed code region (part of the Blackfin Linux ABI). */
1030 fdpic_load_offset
= 0x1000;
1032 /* First try to load this as an FDPIC executable. */
1034 if (!bfin_fdpic_load (sd
, cpu
, STATE_PROG_BFD (sd
), &sp
, elf_addrs
, &ldso_path
))
1035 goto skip_fdpic_init
;
1038 /* If that worked, then load the fixed code region. We only do this for
1039 FDPIC ELFs atm because they are PIEs and let us relocate them without
1040 manual fixups. FLAT files however require location processing which
1041 we do not do ourselves, and they link with a VMA of 0. */
1042 sim_write (sd
, 0x400, bfin_linux_fixed_code
, sizeof (bfin_linux_fixed_code
));
1044 /* If the FDPIC needs an interpreter, then load it up too. */
1047 const char *ldso_full_path
= concat (simulator_sysroot
, ldso_path
, NULL
);
1048 struct bfd
*ldso_bfd
;
1050 ldso_bfd
= bfd_openr (ldso_full_path
, STATE_TARGET (sd
));
1053 sim_io_eprintf (sd
, "bfin-sim: bfd open failed: %s\n", ldso_full_path
);
1056 if (!bfd_check_format (ldso_bfd
, bfd_object
))
1057 sim_io_eprintf (sd
, "bfin-sim: bfd format not valid: %s\n", ldso_full_path
);
1058 bfd_set_arch_info (ldso_bfd
, STATE_ARCHITECTURE (sd
));
1060 if (!bfin_fdpic_load (sd
, cpu
, ldso_bfd
, &sp
, elf_addrs
, &ldso_path
))
1061 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path
);
1063 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
1064 ldso_full_path
, ldso_path
);
1072 /* Finally setup the registers required by the FDPIC ABI. */
1073 SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up. */
1074 SET_PREG (0, exec_loadmap
); /* Exec loadmap addr. */
1075 SET_PREG (1, ldso_loadmap
); /* Interp loadmap addr. */
1076 SET_PREG (2, elf_addrs
[5]); /* PT_DYNAMIC map addr. */
1081 sim_pc_set (cpu
, elf_addrs
[0]);
1083 /* Figure out how much storage the argv/env strings need. */
1084 argc
= count_argc (argv
);
1087 argv_flat
= argc
; /* NUL bytes */
1088 for (i
= 0; i
< argc
; ++i
)
1089 argv_flat
+= strlen (argv
[i
]);
1093 envc
= count_argc (env
);
1094 env_flat
= envc
; /* NUL bytes */
1095 for (i
= 0; i
< envc
; ++i
)
1096 env_flat
+= strlen (env
[i
]);
1098 /* Push the Auxiliary Vector Table between argv/env and actual strings. */
1099 sp_flat
= sp
= ALIGN (SPREG
- argv_flat
- env_flat
- 4, 4);
1102 # define AT_PUSH(at, val) \
1106 sim_write (sd, sp, (void *)&auxvt, 4); \
1109 sim_write (sd, sp, (void *)&auxvt, 4)
1111 unsigned int egid
= getegid (), gid
= getgid ();
1112 unsigned int euid
= geteuid (), uid
= getuid ();
1113 AT_PUSH (AT_NULL
, 0);
1114 AT_PUSH (AT_SECURE
, egid
!= gid
|| euid
!= uid
);
1115 AT_PUSH (AT_EGID
, egid
);
1116 AT_PUSH (AT_GID
, gid
);
1117 AT_PUSH (AT_EUID
, euid
);
1118 AT_PUSH (AT_UID
, uid
);
1119 AT_PUSH (AT_ENTRY
, elf_addrs
[4]);
1120 AT_PUSH (AT_FLAGS
, 0);
1121 AT_PUSH (AT_BASE
, elf_addrs
[3]);
1122 AT_PUSH (AT_PHNUM
, elf_addrs
[2]);
1123 AT_PUSH (AT_PHENT
, sizeof (Elf32_External_Phdr
));
1124 AT_PUSH (AT_PHDR
, elf_addrs
[1]);
1125 AT_PUSH (AT_CLKTCK
, 100); /* XXX: This ever not 100 ? */
1126 AT_PUSH (AT_PAGESZ
, 4096);
1127 AT_PUSH (AT_HWCAP
, 0);
1132 /* Push the argc/argv/env after the auxvt. */
1133 sp
-= ((1 + argc
+ 1 + envc
+ 1) * 4);
1136 /* First push the argc value. */
1137 sim_write (sd
, sp
, (void *)&argc
, 4);
1140 /* Then the actual argv strings so we know where to point argv[]. */
1141 for (i
= 0; i
< argc
; ++i
)
1143 unsigned len
= strlen (argv
[i
]) + 1;
1144 sim_write (sd
, sp_flat
, (void *)argv
[i
], len
);
1145 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1149 sim_write (sd
, sp
, null
, 4);
1152 /* Then the actual env strings so we know where to point env[]. */
1153 for (i
= 0; i
< envc
; ++i
)
1155 unsigned len
= strlen (env
[i
]) + 1;
1156 sim_write (sd
, sp_flat
, (void *)env
[i
], len
);
1157 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1162 /* Set some callbacks. */
1163 cb
->syscall_map
= cb_linux_syscall_map
;
1164 cb
->errno_map
= cb_linux_errno_map
;
1165 cb
->open_map
= cb_linux_open_map
;
1166 cb
->signal_map
= cb_linux_signal_map
;
1167 cb
->stat_map
= stat_map_32
;
1171 bfin_os_init (SIM_DESC sd
, SIM_CPU
*cpu
, const char * const *argv
)
1173 /* Pass the command line via a string in R0 like Linux expects. */
1176 bu32 cmdline
= BFIN_L1_SRAM_SCRATCH
;
1178 SET_DREG (0, cmdline
);
1179 if (argv
&& argv
[0])
1185 bu32 len
= strlen (argv
[i
]);
1186 sim_write (sd
, cmdline
, (void *)argv
[i
], len
);
1188 sim_write (sd
, cmdline
, &byte
, 1);
1194 sim_write (sd
, cmdline
, &byte
, 1);
1198 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
1199 char **argv
, char **env
)
1201 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
1206 addr
= bfd_get_start_address (abfd
);
1209 sim_pc_set (cpu
, addr
);
1211 /* Standalone mode (i.e. `bfin-...-run`) will take care of the argv
1212 for us in sim_open() -> sim_parse_args(). But in debug mode (i.e.
1213 'target sim' with `bfin-...-gdb`), we need to handle it. */
1214 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
1216 free (STATE_PROG_ARGV (sd
));
1217 STATE_PROG_ARGV (sd
) = dupargv (argv
);
1220 switch (STATE_ENVIRONMENT (sd
))
1222 case USER_ENVIRONMENT
:
1223 bfin_user_init (sd
, cpu
, abfd
, (void *)argv
, (void *)env
);
1225 case OPERATING_ENVIRONMENT
:
1226 bfin_os_init (sd
, cpu
, (void *)argv
);
1229 /* Nothing to do for virtual/all envs. */
1237 sim_do_command (SIM_DESC sd
, char *cmd
)
1239 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
1240 sim_io_eprintf (sd
, "Unknown command `%s'\n", cmd
);