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 cb_linux_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 cb_linux_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";
106 static const char cb_libgloss_stat_map_32
[] =
107 "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
108 "st_size,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:"
109 "space,4:st_blksize,4:st_blocks,4:space,8";
110 static const char *stat_map_32
, *stat_map_64
;
112 /* Count the number of arguments in an argv. */
114 count_argc (const char * const *argv
)
121 for (i
= 0; argv
[i
] != NULL
; ++i
)
126 /* Read/write functions for system call interface. */
129 syscall_read_mem (host_callback
*cb
, struct cb_syscall
*sc
,
130 unsigned long taddr
, char *buf
, int bytes
)
132 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
133 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
135 MAYBE_TRACE (CORE
, cpu
, "DBUS FETCH (syscall) %i bytes @ 0x%08lx", bytes
, taddr
);
137 return sim_core_read_buffer (sd
, cpu
, read_map
, buf
, taddr
, bytes
);
141 syscall_write_mem (host_callback
*cb
, struct cb_syscall
*sc
,
142 unsigned long taddr
, const char *buf
, int bytes
)
144 SIM_DESC sd
= (SIM_DESC
) sc
->p1
;
145 SIM_CPU
*cpu
= (SIM_CPU
*) sc
->p2
;
147 MAYBE_TRACE (CORE
, cpu
, "DBUS STORE (syscall) %i bytes @ 0x%08lx", bytes
, taddr
);
149 return sim_core_write_buffer (sd
, cpu
, write_map
, buf
, taddr
, bytes
);
152 /* Simulate a monitor trap, put the result into r0 and errno into r1
153 return offset by which to adjust pc. */
156 bfin_syscall (SIM_CPU
*cpu
)
158 SIM_DESC sd
= CPU_STATE (cpu
);
159 const char * const *argv
= (void *)STATE_PROG_ARGV (sd
);
160 host_callback
*cb
= STATE_CALLBACK (sd
);
164 char _tbuf
[512], *tbuf
= _tbuf
;
167 CB_SYSCALL_INIT (&sc
);
169 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
173 sc
.arg1
= args
[0] = DREG (0);
174 sc
.arg2
= args
[1] = DREG (1);
175 sc
.arg3
= args
[2] = DREG (2);
176 sc
.arg4
= args
[3] = DREG (3);
177 /*sc.arg5 =*/ args
[4] = DREG (4);
178 /*sc.arg6 =*/ args
[5] = DREG (5);
182 /* libgloss syscall. */
184 sc
.arg1
= args
[0] = GET_LONG (DREG (0));
185 sc
.arg2
= args
[1] = GET_LONG (DREG (0) + 4);
186 sc
.arg3
= args
[2] = GET_LONG (DREG (0) + 8);
187 sc
.arg4
= args
[3] = GET_LONG (DREG (0) + 12);
188 /*sc.arg5 =*/ args
[4] = GET_LONG (DREG (0) + 16);
189 /*sc.arg6 =*/ args
[5] = GET_LONG (DREG (0) + 20);
193 sc
.read_mem
= syscall_read_mem
;
194 sc
.write_mem
= syscall_write_mem
;
196 /* Common cb_syscall() handles most functions. */
197 switch (cb_target_to_host_syscall (cb
, sc
.func
))
200 tbuf
+= sprintf (tbuf
, "exit(%i)", args
[0]);
201 sim_engine_halt (sd
, cpu
, NULL
, PCREG
, sim_exited
, sc
.arg1
);
205 tbuf
+= sprintf (tbuf
, "argc()");
206 sc
.result
= count_argc (argv
);
210 tbuf
+= sprintf (tbuf
, "argnlen(%u)", args
[0]);
211 if (sc
.arg1
< count_argc (argv
))
212 sc
.result
= strlen (argv
[sc
.arg1
]);
219 tbuf
+= sprintf (tbuf
, "argn(%u)", args
[0]);
220 if (sc
.arg1
< count_argc (argv
))
222 const char *argn
= argv
[sc
.arg1
];
223 int len
= strlen (argn
);
224 int written
= sc
.write_mem (cb
, &sc
, sc
.arg2
, argn
, len
+ 1);
225 if (written
== len
+ 1)
236 case CB_SYS_gettimeofday
:
238 struct timeval _tv
, *tv
= &_tv
;
239 struct timezone _tz
, *tz
= &_tz
;
241 tbuf
+= sprintf (tbuf
, "gettimeofday(%#x, %#x)", args
[0], args
[1]);
247 sc
.result
= gettimeofday (tv
, tz
);
256 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
258 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
263 t
= tz
->tz_minuteswest
;
264 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
266 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
275 /* XXX: hack just enough to get basic stdio w/uClibc ... */
276 tbuf
+= sprintf (tbuf
, "ioctl(%i, %#x, %u)", args
[0], args
[1], args
[2]);
277 if (sc
.arg2
== 0x5401)
279 sc
.result
= !isatty (sc
.arg1
);
285 sc
.errcode
= TARGET_EINVAL
;
291 static bu32 heap
= BFIN_DEFAULT_MEM_SIZE
/ 2;
294 tbuf
+= sprintf (tbuf
, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
295 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
299 if (sc
.arg4
& 0x20 /*MAP_ANONYMOUS*/)
300 /* XXX: We don't handle zeroing, but default is all zeros. */;
301 else if (args
[4] >= MAX_CALLBACK_FDS
)
302 sc
.errcode
= TARGET_ENOSYS
;
306 char *data
= xmalloc (sc
.arg2
);
308 /* XXX: Should add a cb->pread. */
309 if (pread (cb
->fdmap
[args
[4]], data
, sc
.arg2
, args
[5] << 12) == sc
.arg2
)
310 sc
.write_mem (cb
, &sc
, heap
, data
, sc
.arg2
);
312 sc
.errcode
= TARGET_EINVAL
;
316 sc
.errcode
= TARGET_ENOSYS
;
328 /* Keep it page aligned. */
329 heap
= ALIGN (heap
, 4096);
335 /* XXX: meh, just lie for mmap(). */
336 tbuf
+= sprintf (tbuf
, "munmap(%#x, %u)", args
[0], args
[1]);
341 tbuf
+= sprintf (tbuf
, "dup2(%i, %i)", args
[0], args
[1]);
342 if (sc
.arg1
>= MAX_CALLBACK_FDS
|| sc
.arg2
>= MAX_CALLBACK_FDS
)
345 sc
.errcode
= TARGET_EINVAL
;
349 sc
.result
= dup2 (cb
->fdmap
[sc
.arg1
], cb
->fdmap
[sc
.arg2
]);
355 tbuf
+= sprintf (tbuf
, "llseek(%i, %u, %u, %#x, %u)",
356 args
[0], args
[1], args
[2], args
[3], args
[4]);
357 sc
.func
= TARGET_LINUX_SYS_lseek
;
361 sc
.errcode
= TARGET_EINVAL
;
367 cb_syscall (cb
, &sc
);
371 sc
.write_mem (cb
, &sc
, args
[3], (void *)&sc
.result
, 4);
372 sc
.write_mem (cb
, &sc
, args
[3] + 4, (void *)&z
, 4);
377 /* XXX: Should add a cb->pread. */
379 tbuf
+= sprintf (tbuf
, "pread(%i, %#x, %u, %i)",
380 args
[0], args
[1], args
[2], args
[3]);
381 if (sc
.arg1
>= MAX_CALLBACK_FDS
)
384 sc
.errcode
= TARGET_EINVAL
;
388 long old_pos
, read_result
, read_errcode
;
390 /* Get current filepos. */
391 sc
.func
= TARGET_LINUX_SYS_lseek
;
394 cb_syscall (cb
, &sc
);
399 /* Move to the new pos. */
400 sc
.func
= TARGET_LINUX_SYS_lseek
;
403 cb_syscall (cb
, &sc
);
408 sc
.func
= TARGET_LINUX_SYS_read
;
411 cb_syscall (cb
, &sc
);
412 read_result
= sc
.result
;
413 read_errcode
= sc
.errcode
;
415 /* Move back to the old pos. */
416 sc
.func
= TARGET_LINUX_SYS_lseek
;
419 cb_syscall (cb
, &sc
);
421 sc
.result
= read_result
;
422 sc
.errcode
= read_errcode
;
427 tbuf
+= sprintf (tbuf
, "getcwd(%#x, %u)", args
[0], args
[1]);
429 p
= alloca (sc
.arg2
);
430 if (getcwd (p
, sc
.arg2
) == NULL
)
433 sc
.errcode
= TARGET_EINVAL
;
437 sc
.write_mem (cb
, &sc
, sc
.arg1
, p
, sc
.arg2
);
443 tbuf
+= sprintf (tbuf
, "stat64(%#x, %u)", args
[0], args
[1]);
444 cb
->stat_map
= stat_map_64
;
445 sc
.func
= TARGET_LINUX_SYS_stat
;
446 cb_syscall (cb
, &sc
);
447 cb
->stat_map
= stat_map_32
;
450 tbuf
+= sprintf (tbuf
, "lstat64(%#x, %u)", args
[0], args
[1]);
451 cb
->stat_map
= stat_map_64
;
452 sc
.func
= TARGET_LINUX_SYS_lstat
;
453 cb_syscall (cb
, &sc
);
454 cb
->stat_map
= stat_map_32
;
457 tbuf
+= sprintf (tbuf
, "fstat64(%#x, %u)", args
[0], args
[1]);
458 cb
->stat_map
= stat_map_64
;
459 sc
.func
= TARGET_LINUX_SYS_fstat
;
460 cb_syscall (cb
, &sc
);
461 cb
->stat_map
= stat_map_32
;
464 case CB_SYS_ftruncate64
:
465 tbuf
+= sprintf (tbuf
, "ftruncate64(%u, %u)", args
[0], args
[1]);
466 sc
.func
= TARGET_LINUX_SYS_ftruncate
;
467 cb_syscall (cb
, &sc
);
471 case CB_SYS_getuid32
:
472 tbuf
+= sprintf (tbuf
, "getuid()");
473 sc
.result
= getuid ();
476 case CB_SYS_getgid32
:
477 tbuf
+= sprintf (tbuf
, "getgid()");
478 sc
.result
= getgid ();
482 case CB_SYS_setuid32
:
483 tbuf
+= sprintf (tbuf
, "setuid(%u)", args
[0]);
484 sc
.result
= setuid (sc
.arg1
);
488 case CB_SYS_setgid32
:
489 tbuf
+= sprintf (tbuf
, "setgid(%u)", args
[0]);
490 sc
.result
= setgid (sc
.arg1
);
494 tbuf
+= sprintf (tbuf
, "getpid()");
495 sc
.result
= getpid ();
498 tbuf
+= sprintf (tbuf
, "kill(%u, %i)", args
[0], args
[1]);
499 /* Only let the app kill itself. */
500 if (sc
.arg1
!= getpid ())
503 sc
.errcode
= TARGET_EPERM
;
508 sc
.result
= kill (sc
.arg1
, sc
.arg2
);
512 sc
.errcode
= TARGET_ENOSYS
;
518 tbuf
+= sprintf (tbuf
, "open(%#x, %#x, %o)", args
[0], args
[1], args
[2]);
521 tbuf
+= sprintf (tbuf
, "close(%i)", args
[0]);
524 tbuf
+= sprintf (tbuf
, "read(%i, %#x, %u)", args
[0], args
[1], args
[2]);
527 tbuf
+= sprintf (tbuf
, "write(%i, %#x, %u)", args
[0], args
[1], args
[2]);
530 tbuf
+= sprintf (tbuf
, "lseek(%i, %i, %i)", args
[0], args
[1], args
[2]);
533 tbuf
+= sprintf (tbuf
, "unlink(%#x)", args
[0]);
535 case CB_SYS_truncate
:
536 tbuf
+= sprintf (tbuf
, "truncate(%#x, %i)", args
[0], args
[1]);
538 case CB_SYS_ftruncate
:
539 tbuf
+= sprintf (tbuf
, "ftruncate(%i, %i)", args
[0], args
[1]);
542 tbuf
+= sprintf (tbuf
, "rename(%#x, %#x)", args
[0], args
[1]);
545 tbuf
+= sprintf (tbuf
, "stat(%#x, %#x)", args
[0], args
[1]);
548 tbuf
+= sprintf (tbuf
, "fstat(%i, %#x)", args
[0], args
[1]);
551 tbuf
+= sprintf (tbuf
, "lstat(%i, %#x)", args
[0], args
[1]);
554 tbuf
+= sprintf (tbuf
, "pipe(%#x, %#x)", args
[0], args
[1]);
558 tbuf
+= sprintf (tbuf
, "???_%i(%#x, %#x, %#x, %#x, %#x, %#x)", sc
.func
,
559 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
561 cb_syscall (cb
, &sc
);
567 cb
->last_errno
= errno
;
568 sc
.errcode
= cb
->get_errno (cb
);
572 TRACE_EVENTS (cpu
, "syscall_%i(%#x, %#x, %#x, %#x, %#x, %#x) = %li (error = %i)",
573 sc
.func
, args
[0], args
[1], args
[2], args
[3], args
[4], args
[5],
574 sc
.result
, sc
.errcode
);
576 tbuf
+= sprintf (tbuf
, " = ");
577 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
581 tbuf
+= sprintf (tbuf
, "-1 (error = %i)", sc
.errcode
);
582 if (sc
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
584 sim_io_eprintf (sd
, "bfin-sim: %#x: unimplemented syscall %i\n",
587 SET_DREG (0, -sc
.errcode
);
592 tbuf
+= sprintf (tbuf
, "%#lx", sc
.result
);
594 tbuf
+= sprintf (tbuf
, "%lu", sc
.result
);
595 SET_DREG (0, sc
.result
);
600 tbuf
+= sprintf (tbuf
, "%lu (error = %i)", sc
.result
, sc
.errcode
);
601 SET_DREG (0, sc
.result
);
602 SET_DREG (1, sc
.result2
);
603 SET_DREG (2, sc
.errcode
);
606 TRACE_SYSCALL (cpu
, "%s", _tbuf
);
610 trace_register (SIM_DESC sd
,
616 trace_printf (sd
, cpu
, "%s %s",
618 TRACE_PREFIX (CPU_TRACE_DATA (cpu
)));
620 trace_vprintf (sd
, cpu
, fmt
, ap
);
622 trace_printf (sd
, cpu
, "\n");
625 /* Execute a single instruction. */
628 step_once (SIM_CPU
*cpu
)
630 SIM_DESC sd
= CPU_STATE (cpu
);
631 bu32 insn_len
, oldpc
= PCREG
;
635 if (TRACE_ANY_P (cpu
))
636 trace_prefix (sd
, cpu
, NULL_CIA
, oldpc
, TRACE_LINENUM_P (cpu
),
637 NULL
, 0, " "); /* Use a space for gcc warnings. */
639 /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
640 has already had the SSSTEP bit enabled. */
642 if (STATE_ENVIRONMENT (sd
) == OPERATING_ENVIRONMENT
643 && (SYSCFGREG
& SYSCFG_SSSTEP
))
645 int ivg
= cec_get_ivg (cpu
);
646 if (ivg
== -1 || ivg
> 3)
651 /* XXX: Is this what happens on the hardware ? */
652 if (cec_get_ivg (cpu
) == EVT_EMU
)
653 cec_return (cpu
, EVT_EMU
);
656 BFIN_CPU_STATE
.did_jump
= false;
658 insn_len
= interp_insn_bfin (cpu
, oldpc
);
660 /* If we executed this insn successfully, then we always decrement
661 the loop counter. We don't want to update the PC though if the
662 last insn happened to be a change in code flow (jump/etc...). */
663 if (!BFIN_CPU_STATE
.did_jump
)
664 SET_PCREG (hwloop_get_next_pc (cpu
, oldpc
, insn_len
));
665 for (i
= 1; i
>= 0; --i
)
666 if (LCREG (i
) && oldpc
== LBREG (i
))
668 SET_LCREG (i
, LCREG (i
) - 1);
673 ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
));
675 /* Handle hardware single stepping only if we're still lower than EVT3.
676 XXX: May not be entirely correct wrt EXCPT insns. */
679 int ivg
= cec_get_ivg (cpu
);
680 if (ivg
== -1 || ivg
> 3)
683 cec_exception (cpu
, VEC_STEP
);
691 sim_engine_run (SIM_DESC sd
,
692 int next_cpu_nr
, /* ignore */
693 int nr_cpus
, /* ignore */
694 int siggnal
) /* ignore */
699 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
701 cpu
= STATE_CPU (sd
, 0);
706 /* Process any events -- can't use tickn because it may
707 advance right over the next event. */
708 for (ticks
= 0; ticks
< CYCLE_DELAY
; ++ticks
)
709 if (sim_events_tick (sd
))
710 sim_events_process (sd
);
714 /* Cover function of sim_state_free to free the cpu buffers as well. */
717 free_state (SIM_DESC sd
)
719 if (STATE_MODULES (sd
) != NULL
)
720 sim_module_uninstall (sd
);
721 sim_cpu_free_all (sd
);
725 /* Create an instance of the simulator. */
728 bfin_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
730 memset (&cpu
->state
, 0, sizeof (cpu
->state
));
732 PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
)) = 0;
734 bfin_model_cpu_init (sd
, cpu
);
736 /* Set default stack to top of scratch pad. */
737 SET_SPREG (BFIN_DEFAULT_MEM_SIZE
);
738 SET_KSPREG (BFIN_DEFAULT_MEM_SIZE
);
739 SET_USPREG (BFIN_DEFAULT_MEM_SIZE
);
741 /* This is what the hardware likes. */
742 SET_SYSCFGREG (0x30);
746 sim_open (SIM_OPEN_KIND kind
, host_callback
*callback
,
747 struct bfd
*abfd
, char **argv
)
751 SIM_DESC sd
= sim_state_alloc (kind
, callback
);
753 /* The cpu data is kept in a separately allocated chunk of memory. */
754 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
761 /* XXX: Only first core gets profiled ? */
762 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
763 STATE_WATCHPOINTS (sd
)->pc
= &PCREG
;
764 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (PCREG
);
767 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
773 /* XXX: Default to the Virtual environment. */
774 if (STATE_ENVIRONMENT (sd
) == ALL_ENVIRONMENT
)
775 STATE_ENVIRONMENT (sd
) = VIRTUAL_ENVIRONMENT
;
777 /* These options override any module options.
778 Obviously ambiguity should be avoided, however the caller may wish to
779 augment the meaning of an option. */
780 #define e_sim_add_option_table(sd, options) \
782 extern const OPTION options[]; \
783 sim_add_option_table (sd, NULL, options); \
785 e_sim_add_option_table (sd
, bfin_mmu_options
);
786 e_sim_add_option_table (sd
, bfin_mach_options
);
788 /* getopt will print the error message so we just have to exit if this fails.
789 FIXME: Hmmm... in the case of gdb we need getopt to call
791 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
797 /* Allocate external memory if none specified by user.
798 Use address 4 here in case the user wanted address 0 unmapped. */
799 if (sim_core_read_buffer (sd
, NULL
, read_map
, &c
, 4, 1) == 0)
801 bu16 emuexcpt
= 0x25;
802 sim_do_commandf (sd
, "memory-size 0x%lx", BFIN_DEFAULT_MEM_SIZE
);
803 sim_write (sd
, 0, (void *)&emuexcpt
, 2);
806 /* Check for/establish the a reference program image. */
807 if (sim_analyze_program (sd
,
808 (STATE_PROG_ARGV (sd
) != NULL
809 ? *STATE_PROG_ARGV (sd
)
810 : NULL
), abfd
) != SIM_RC_OK
)
816 /* Establish any remaining configuration options. */
817 if (sim_config (sd
) != SIM_RC_OK
)
823 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
829 /* CPU specific initialization. */
830 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
832 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
833 bfin_initialize_cpu (sd
, cpu
);
840 sim_close (SIM_DESC sd
, int quitting
)
842 sim_module_uninstall (sd
);
845 /* Some utils don't like having a NULL environ. */
846 static const char * const simple_env
[] = { "HOME=/", "PATH=/bin", NULL
};
848 static bu32 fdpic_load_offset
;
851 bfin_fdpic_load (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
, bu32
*sp
,
852 bu32
*elf_addrs
, char **ldso_path
)
857 Elf_Internal_Ehdr
*iehdr
;
858 Elf32_External_Ehdr ehdr
;
859 Elf_Internal_Phdr
*phdrs
;
867 unsigned char null
[4] = { 0, 0, 0, 0 };
872 /* See if this an FDPIC ELF. */
875 goto skip_fdpic_init
;
876 if (bfd_seek (abfd
, 0, SEEK_SET
) != 0)
877 goto skip_fdpic_init
;
878 if (bfd_bread (&ehdr
, sizeof (ehdr
), abfd
) != sizeof (ehdr
))
879 goto skip_fdpic_init
;
880 iehdr
= elf_elfheader (abfd
);
881 if (!(iehdr
->e_flags
& EF_BFIN_FDPIC
))
882 goto skip_fdpic_init
;
884 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
885 sim_io_printf (sd
, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
886 bfd_get_filename (abfd
), fdpic_load_offset
, elf_addrs
[0]);
888 /* Grab the Program Headers to set up the loadsegs on the stack. */
889 phdr_size
= bfd_get_elf_phdr_upper_bound (abfd
);
891 goto skip_fdpic_init
;
892 phdrs
= xmalloc (phdr_size
);
893 phdrc
= bfd_get_elf_phdrs (abfd
, phdrs
);
895 goto skip_fdpic_init
;
897 /* Push the Ehdr onto the stack. */
898 *sp
-= sizeof (ehdr
);
900 sim_write (sd
, *sp
, (void *)&ehdr
, sizeof (ehdr
));
901 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
902 sim_io_printf (sd
, " Elf_Ehdr: %#x\n", *sp
);
904 /* Since we're relocating things ourselves, we need to relocate
905 the start address as well. */
906 elf_addrs
[0] = bfd_get_start_address (abfd
) + fdpic_load_offset
;
908 /* And the Exec's Phdrs onto the stack. */
909 if (STATE_PROG_BFD (sd
) == abfd
)
911 elf_addrs
[4] = elf_addrs
[0];
913 phdr_size
= iehdr
->e_phentsize
* iehdr
->e_phnum
;
914 if (bfd_seek (abfd
, iehdr
->e_phoff
, SEEK_SET
) != 0)
915 goto skip_fdpic_init
;
916 data
= xmalloc (phdr_size
);
917 if (bfd_bread (data
, phdr_size
, abfd
) != phdr_size
)
918 goto skip_fdpic_init
;
921 elf_addrs
[2] = phdrc
;
922 sim_write (sd
, *sp
, data
, phdr_size
);
924 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
925 sim_io_printf (sd
, " Elf_Phdrs: %#x\n", *sp
);
928 /* Now push all the loadsegs. */
931 for (i
= phdrc
; i
>= 0; --i
)
932 if (phdrs
[i
].p_type
== PT_LOAD
)
934 Elf_Internal_Phdr
*p
= &phdrs
[i
];
935 bu32 paddr
, vaddr
, memsz
, filesz
;
937 paddr
= p
->p_paddr
+ fdpic_load_offset
;
940 filesz
= p
->p_filesz
;
942 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
943 sim_io_printf (sd
, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
944 i
, vaddr
, paddr
, filesz
, memsz
);
946 data
= xmalloc (memsz
);
948 memset (data
+ filesz
, 0, memsz
- filesz
);
950 if (bfd_seek (abfd
, p
->p_offset
, SEEK_SET
) == 0
951 && bfd_bread (data
, filesz
, abfd
) == filesz
)
952 sim_write (sd
, paddr
, data
, memsz
);
956 max_load_addr
= MAX (paddr
+ memsz
, max_load_addr
);
959 sim_write (sd
, *sp
+0, (void *)&paddr
, 4); /* loadseg.addr */
960 sim_write (sd
, *sp
+4, (void *)&vaddr
, 4); /* loadseg.p_vaddr */
961 sim_write (sd
, *sp
+8, (void *)&memsz
, 4); /* loadseg.p_memsz */
964 else if (phdrs
[i
].p_type
== PT_DYNAMIC
)
966 elf_addrs
[5] = phdrs
[i
].p_paddr
+ fdpic_load_offset
;
967 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
968 sim_io_printf (sd
, " PT_DYNAMIC: %#x\n", elf_addrs
[5]);
970 else if (phdrs
[i
].p_type
== PT_INTERP
)
972 uint32_t off
= phdrs
[i
].p_offset
;
973 uint32_t len
= phdrs
[i
].p_filesz
;
975 *ldso_path
= xmalloc (len
);
976 if (bfd_seek (abfd
, off
, SEEK_SET
) != 0
977 || bfd_bread (*ldso_path
, len
, abfd
) != len
)
982 else if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
983 sim_io_printf (sd
, " PT_INTERP: %s\n", *ldso_path
);
986 /* Update the load offset with a few extra pages. */
987 fdpic_load_offset
= ALIGN (MAX (max_load_addr
, fdpic_load_offset
), 0x10000);
988 fdpic_load_offset
+= 0x10000;
990 /* Push the summary loadmap info onto the stack last. */
992 sim_write (sd
, *sp
+0, null
, 2); /* loadmap.version */
993 sim_write (sd
, *sp
+2, (void *)&nsegs
, 2); /* loadmap.nsegs */
1003 bfin_user_init (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
,
1004 const char * const *argv
, const char * const *env
)
1006 /* XXX: Missing host -> target endian ... */
1007 /* Linux starts the user app with the stack:
1009 argv[0] -- pointers to the actual strings
1015 auxvt[0].type -- ELF Auxiliary Vector Table
1020 argv[0..N][0..M] -- actual argv/env strings
1022 FDPIC loadmaps -- for FDPIC apps
1023 So set things up the same way. */
1025 bu32 argv_flat
, env_flat
;
1029 /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
1031 bu32 auxvt
, auxvt_size
;
1032 bu32 exec_loadmap
, ldso_loadmap
;
1035 unsigned char null
[4] = { 0, 0, 0, 0 };
1037 host_callback
*cb
= STATE_CALLBACK (sd
);
1039 elf_addrs
[0] = elf_addrs
[4] = bfd_get_start_address (abfd
);
1040 elf_addrs
[1] = elf_addrs
[2] = elf_addrs
[3] = elf_addrs
[5] = 0;
1042 /* Keep the load addresses consistent between runs. Also make sure we make
1043 space for the fixed code region (part of the Blackfin Linux ABI). */
1044 fdpic_load_offset
= 0x1000;
1046 /* First try to load this as an FDPIC executable. */
1048 if (!bfin_fdpic_load (sd
, cpu
, STATE_PROG_BFD (sd
), &sp
, elf_addrs
, &ldso_path
))
1049 goto skip_fdpic_init
;
1052 /* If that worked, then load the fixed code region. We only do this for
1053 FDPIC ELFs atm because they are PIEs and let us relocate them without
1054 manual fixups. FLAT files however require location processing which
1055 we do not do ourselves, and they link with a VMA of 0. */
1056 sim_write (sd
, 0x400, bfin_linux_fixed_code
, sizeof (bfin_linux_fixed_code
));
1058 /* If the FDPIC needs an interpreter, then load it up too. */
1061 const char *ldso_full_path
= concat (simulator_sysroot
, ldso_path
, NULL
);
1062 struct bfd
*ldso_bfd
;
1064 ldso_bfd
= bfd_openr (ldso_full_path
, STATE_TARGET (sd
));
1067 sim_io_eprintf (sd
, "bfin-sim: bfd open failed: %s\n", ldso_full_path
);
1070 if (!bfd_check_format (ldso_bfd
, bfd_object
))
1071 sim_io_eprintf (sd
, "bfin-sim: bfd format not valid: %s\n", ldso_full_path
);
1072 bfd_set_arch_info (ldso_bfd
, STATE_ARCHITECTURE (sd
));
1074 if (!bfin_fdpic_load (sd
, cpu
, ldso_bfd
, &sp
, elf_addrs
, &ldso_path
))
1075 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path
);
1077 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
1078 ldso_full_path
, ldso_path
);
1086 /* Finally setup the registers required by the FDPIC ABI. */
1087 SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up. */
1088 SET_PREG (0, exec_loadmap
); /* Exec loadmap addr. */
1089 SET_PREG (1, ldso_loadmap
); /* Interp loadmap addr. */
1090 SET_PREG (2, elf_addrs
[5]); /* PT_DYNAMIC map addr. */
1095 sim_pc_set (cpu
, elf_addrs
[0]);
1097 /* Figure out how much storage the argv/env strings need. */
1098 argc
= count_argc (argv
);
1101 argv_flat
= argc
; /* NUL bytes */
1102 for (i
= 0; i
< argc
; ++i
)
1103 argv_flat
+= strlen (argv
[i
]);
1107 envc
= count_argc (env
);
1108 env_flat
= envc
; /* NUL bytes */
1109 for (i
= 0; i
< envc
; ++i
)
1110 env_flat
+= strlen (env
[i
]);
1112 /* Push the Auxiliary Vector Table between argv/env and actual strings. */
1113 sp_flat
= sp
= ALIGN (SPREG
- argv_flat
- env_flat
- 4, 4);
1116 # define AT_PUSH(at, val) \
1120 sim_write (sd, sp, (void *)&auxvt, 4); \
1123 sim_write (sd, sp, (void *)&auxvt, 4)
1125 unsigned int egid
= getegid (), gid
= getgid ();
1126 unsigned int euid
= geteuid (), uid
= getuid ();
1127 AT_PUSH (AT_NULL
, 0);
1128 AT_PUSH (AT_SECURE
, egid
!= gid
|| euid
!= uid
);
1129 AT_PUSH (AT_EGID
, egid
);
1130 AT_PUSH (AT_GID
, gid
);
1131 AT_PUSH (AT_EUID
, euid
);
1132 AT_PUSH (AT_UID
, uid
);
1133 AT_PUSH (AT_ENTRY
, elf_addrs
[4]);
1134 AT_PUSH (AT_FLAGS
, 0);
1135 AT_PUSH (AT_BASE
, elf_addrs
[3]);
1136 AT_PUSH (AT_PHNUM
, elf_addrs
[2]);
1137 AT_PUSH (AT_PHENT
, sizeof (Elf32_External_Phdr
));
1138 AT_PUSH (AT_PHDR
, elf_addrs
[1]);
1139 AT_PUSH (AT_CLKTCK
, 100); /* XXX: This ever not 100 ? */
1140 AT_PUSH (AT_PAGESZ
, 4096);
1141 AT_PUSH (AT_HWCAP
, 0);
1146 /* Push the argc/argv/env after the auxvt. */
1147 sp
-= ((1 + argc
+ 1 + envc
+ 1) * 4);
1150 /* First push the argc value. */
1151 sim_write (sd
, sp
, (void *)&argc
, 4);
1154 /* Then the actual argv strings so we know where to point argv[]. */
1155 for (i
= 0; i
< argc
; ++i
)
1157 unsigned len
= strlen (argv
[i
]) + 1;
1158 sim_write (sd
, sp_flat
, (void *)argv
[i
], len
);
1159 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1163 sim_write (sd
, sp
, null
, 4);
1166 /* Then the actual env strings so we know where to point env[]. */
1167 for (i
= 0; i
< envc
; ++i
)
1169 unsigned len
= strlen (env
[i
]) + 1;
1170 sim_write (sd
, sp_flat
, (void *)env
[i
], len
);
1171 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1176 /* Set some callbacks. */
1177 cb
->syscall_map
= cb_linux_syscall_map
;
1178 cb
->errno_map
= cb_linux_errno_map
;
1179 cb
->open_map
= cb_linux_open_map
;
1180 cb
->signal_map
= cb_linux_signal_map
;
1181 cb
->stat_map
= stat_map_32
= cb_linux_stat_map_32
;
1182 stat_map_64
= cb_linux_stat_map_64
;
1186 bfin_os_init (SIM_DESC sd
, SIM_CPU
*cpu
, const char * const *argv
)
1188 /* Pass the command line via a string in R0 like Linux expects. */
1191 bu32 cmdline
= BFIN_L1_SRAM_SCRATCH
;
1193 SET_DREG (0, cmdline
);
1194 if (argv
&& argv
[0])
1200 bu32 len
= strlen (argv
[i
]);
1201 sim_write (sd
, cmdline
, (void *)argv
[i
], len
);
1203 sim_write (sd
, cmdline
, &byte
, 1);
1209 sim_write (sd
, cmdline
, &byte
, 1);
1213 bfin_virtual_init (SIM_DESC sd
, SIM_CPU
*cpu
)
1215 host_callback
*cb
= STATE_CALLBACK (sd
);
1217 cb
->stat_map
= stat_map_32
= cb_libgloss_stat_map_32
;
1222 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
1223 char **argv
, char **env
)
1225 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
1230 addr
= bfd_get_start_address (abfd
);
1233 sim_pc_set (cpu
, addr
);
1235 /* Standalone mode (i.e. `bfin-...-run`) will take care of the argv
1236 for us in sim_open() -> sim_parse_args(). But in debug mode (i.e.
1237 'target sim' with `bfin-...-gdb`), we need to handle it. */
1238 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
1240 freeargv (STATE_PROG_ARGV (sd
));
1241 STATE_PROG_ARGV (sd
) = dupargv (argv
);
1244 switch (STATE_ENVIRONMENT (sd
))
1246 case USER_ENVIRONMENT
:
1247 bfin_user_init (sd
, cpu
, abfd
, (void *)argv
, (void *)env
);
1249 case OPERATING_ENVIRONMENT
:
1250 bfin_os_init (sd
, cpu
, (void *)argv
);
1253 bfin_virtual_init (sd
, cpu
);
1261 sim_do_command (SIM_DESC sd
, char *cmd
)
1263 if (sim_args_command (sd
, cmd
) != SIM_RC_OK
)
1264 sim_io_eprintf (sd
, "Unknown command `%s'\n", cmd
);