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"
35 #include "sim-syscall.h"
38 #include "targ-vals.h"
40 /* The numbers here do not matter. They just need to be unique. They also
41 need not be static across releases -- they're used internally only. The
42 mapping from the Linux ABI to the CB values is in linux-targ-map.h. */
43 #define CB_SYS_ioctl 201
44 #define CB_SYS_mmap2 202
45 #define CB_SYS_munmap 203
46 #define CB_SYS_dup2 204
47 #define CB_SYS_getuid 205
48 #define CB_SYS_getuid32 206
49 #define CB_SYS_getgid 207
50 #define CB_SYS_getgid32 208
51 #define CB_SYS_setuid 209
52 #define CB_SYS_setuid32 210
53 #define CB_SYS_setgid 211
54 #define CB_SYS_setgid32 212
55 #define CB_SYS_pread 213
56 #define CB_SYS__llseek 214
57 #define CB_SYS_getcwd 215
58 #define CB_SYS_stat64 216
59 #define CB_SYS_lstat64 217
60 #define CB_SYS_fstat64 218
61 #define CB_SYS_ftruncate64 219
62 #define CB_SYS_gettimeofday 220
63 #define CB_SYS_access 221
64 #include "linux-targ-map.h"
65 #include "linux-fixed-code.h"
67 #include "elf/common.h"
68 #include "elf/external.h"
69 #include "elf/internal.h"
73 #include "dv-bfin_cec.h"
74 #include "dv-bfin_mmu.h"
89 # define setuid(uid) -1
92 # define setgid(gid) -1
95 static const char cb_linux_stat_map_32
[] =
96 /* Linux kernel 32bit layout: */
97 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
98 "space,2:st_size,4:st_blksize,4:st_blocks,4:st_atime,4:st_atimensec,4:"
99 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:space,4";
100 /* uClibc public ABI 32bit layout:
101 "st_dev,8:space,2:space,2:st_ino,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:"
102 "st_rdev,8:space,2:space,2:st_size,4:st_blksiez,4:st_blocks,4:st_atime,4:"
103 "st_atimensec,4:st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:"
105 static const char cb_linux_stat_map_64
[] =
106 "st_dev,8:space,4:space,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:st_rdev,8:"
107 "space,4:st_size,8:st_blksize,4:st_blocks,8:st_atime,4:st_atimensec,4:"
108 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:st_ino,8";
109 static const char cb_libgloss_stat_map_32
[] =
110 "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
111 "st_size,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:"
112 "space,4:st_blksize,4:st_blocks,4:space,8";
113 static const char *stat_map_32
, *stat_map_64
;
115 /* Count the number of arguments in an argv. */
117 count_argc (const char * const *argv
)
124 for (i
= 0; argv
[i
] != NULL
; ++i
)
129 /* Simulate a monitor trap, put the result into r0 and errno into r1
130 return offset by which to adjust pc. */
133 bfin_syscall (SIM_CPU
*cpu
)
135 SIM_DESC sd
= CPU_STATE (cpu
);
136 const char * const *argv
= (void *)STATE_PROG_ARGV (sd
);
137 host_callback
*cb
= STATE_CALLBACK (sd
);
141 char _tbuf
[1024 * 3], *tbuf
= _tbuf
, tstr
[1024];
144 CB_SYSCALL_INIT (&sc
);
146 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
150 sc
.arg1
= args
[0] = DREG (0);
151 sc
.arg2
= args
[1] = DREG (1);
152 sc
.arg3
= args
[2] = DREG (2);
153 sc
.arg4
= args
[3] = DREG (3);
154 /*sc.arg5 =*/ args
[4] = DREG (4);
155 /*sc.arg6 =*/ args
[5] = DREG (5);
159 /* libgloss syscall. */
161 sc
.arg1
= args
[0] = GET_LONG (DREG (0));
162 sc
.arg2
= args
[1] = GET_LONG (DREG (0) + 4);
163 sc
.arg3
= args
[2] = GET_LONG (DREG (0) + 8);
164 sc
.arg4
= args
[3] = GET_LONG (DREG (0) + 12);
165 /*sc.arg5 =*/ args
[4] = GET_LONG (DREG (0) + 16);
166 /*sc.arg6 =*/ args
[5] = GET_LONG (DREG (0) + 20);
170 sc
.read_mem
= sim_syscall_read_mem
;
171 sc
.write_mem
= sim_syscall_write_mem
;
173 /* Common cb_syscall() handles most functions. */
174 switch (cb_target_to_host_syscall (cb
, sc
.func
))
177 tbuf
+= sprintf (tbuf
, "exit(%i)", args
[0]);
178 sim_engine_halt (sd
, cpu
, NULL
, PCREG
, sim_exited
, sc
.arg1
);
182 tbuf
+= sprintf (tbuf
, "argc()");
183 sc
.result
= count_argc (argv
);
187 tbuf
+= sprintf (tbuf
, "argnlen(%u)", args
[0]);
188 if (sc
.arg1
< count_argc (argv
))
189 sc
.result
= strlen (argv
[sc
.arg1
]);
196 tbuf
+= sprintf (tbuf
, "argn(%u)", args
[0]);
197 if (sc
.arg1
< count_argc (argv
))
199 const char *argn
= argv
[sc
.arg1
];
200 int len
= strlen (argn
);
201 int written
= sc
.write_mem (cb
, &sc
, sc
.arg2
, argn
, len
+ 1);
202 if (written
== len
+ 1)
213 case CB_SYS_gettimeofday
:
215 struct timeval _tv
, *tv
= &_tv
;
216 struct timezone _tz
, *tz
= &_tz
;
218 tbuf
+= sprintf (tbuf
, "gettimeofday(%#x, %#x)", args
[0], args
[1]);
224 sc
.result
= gettimeofday (tv
, tz
);
233 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
235 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
240 t
= tz
->tz_minuteswest
;
241 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
243 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
252 /* XXX: hack just enough to get basic stdio w/uClibc ... */
253 tbuf
+= sprintf (tbuf
, "ioctl(%i, %#x, %u)", args
[0], args
[1], args
[2]);
254 if (sc
.arg2
== 0x5401)
256 sc
.result
= !isatty (sc
.arg1
);
262 sc
.errcode
= TARGET_EINVAL
;
268 static bu32 heap
= BFIN_DEFAULT_MEM_SIZE
/ 2;
271 tbuf
+= sprintf (tbuf
, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
272 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
276 if (sc
.arg4
& 0x20 /*MAP_ANONYMOUS*/)
277 /* XXX: We don't handle zeroing, but default is all zeros. */;
278 else if (args
[4] >= MAX_CALLBACK_FDS
)
279 sc
.errcode
= TARGET_ENOSYS
;
283 char *data
= xmalloc (sc
.arg2
);
285 /* XXX: Should add a cb->pread. */
286 if (pread (cb
->fdmap
[args
[4]], data
, sc
.arg2
, args
[5] << 12) == sc
.arg2
)
287 sc
.write_mem (cb
, &sc
, heap
, data
, sc
.arg2
);
289 sc
.errcode
= TARGET_EINVAL
;
293 sc
.errcode
= TARGET_ENOSYS
;
305 /* Keep it page aligned. */
306 heap
= ALIGN (heap
, 4096);
312 /* XXX: meh, just lie for mmap(). */
313 tbuf
+= sprintf (tbuf
, "munmap(%#x, %u)", args
[0], args
[1]);
318 tbuf
+= sprintf (tbuf
, "dup2(%i, %i)", args
[0], args
[1]);
319 if (sc
.arg1
>= MAX_CALLBACK_FDS
|| sc
.arg2
>= MAX_CALLBACK_FDS
)
322 sc
.errcode
= TARGET_EINVAL
;
326 sc
.result
= dup2 (cb
->fdmap
[sc
.arg1
], cb
->fdmap
[sc
.arg2
]);
332 tbuf
+= sprintf (tbuf
, "llseek(%i, %u, %u, %#x, %u)",
333 args
[0], args
[1], args
[2], args
[3], args
[4]);
334 sc
.func
= TARGET_LINUX_SYS_lseek
;
338 sc
.errcode
= TARGET_EINVAL
;
344 cb_syscall (cb
, &sc
);
348 sc
.write_mem (cb
, &sc
, args
[3], (void *)&sc
.result
, 4);
349 sc
.write_mem (cb
, &sc
, args
[3] + 4, (void *)&z
, 4);
354 /* XXX: Should add a cb->pread. */
356 tbuf
+= sprintf (tbuf
, "pread(%i, %#x, %u, %i)",
357 args
[0], args
[1], args
[2], args
[3]);
358 if (sc
.arg1
>= MAX_CALLBACK_FDS
)
361 sc
.errcode
= TARGET_EINVAL
;
365 long old_pos
, read_result
, read_errcode
;
367 /* Get current filepos. */
368 sc
.func
= TARGET_LINUX_SYS_lseek
;
371 cb_syscall (cb
, &sc
);
376 /* Move to the new pos. */
377 sc
.func
= TARGET_LINUX_SYS_lseek
;
380 cb_syscall (cb
, &sc
);
385 sc
.func
= TARGET_LINUX_SYS_read
;
388 cb_syscall (cb
, &sc
);
389 read_result
= sc
.result
;
390 read_errcode
= sc
.errcode
;
392 /* Move back to the old pos. */
393 sc
.func
= TARGET_LINUX_SYS_lseek
;
396 cb_syscall (cb
, &sc
);
398 sc
.result
= read_result
;
399 sc
.errcode
= read_errcode
;
404 tbuf
+= sprintf (tbuf
, "getcwd(%#x, %u)", args
[0], args
[1]);
406 p
= alloca (sc
.arg2
);
407 if (getcwd (p
, sc
.arg2
) == NULL
)
410 sc
.errcode
= TARGET_EINVAL
;
414 sc
.write_mem (cb
, &sc
, sc
.arg1
, p
, sc
.arg2
);
420 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
421 strcpy (tstr
, "???");
422 tbuf
+= sprintf (tbuf
, "stat64(%#x:\"%s\", %u)", args
[0], tstr
, args
[1]);
423 cb
->stat_map
= stat_map_64
;
424 sc
.func
= TARGET_LINUX_SYS_stat
;
425 cb_syscall (cb
, &sc
);
426 cb
->stat_map
= stat_map_32
;
429 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
430 strcpy (tstr
, "???");
431 tbuf
+= sprintf (tbuf
, "lstat64(%#x:\"%s\", %u)", args
[0], tstr
, args
[1]);
432 cb
->stat_map
= stat_map_64
;
433 sc
.func
= TARGET_LINUX_SYS_lstat
;
434 cb_syscall (cb
, &sc
);
435 cb
->stat_map
= stat_map_32
;
438 tbuf
+= sprintf (tbuf
, "fstat64(%#x, %u)", args
[0], args
[1]);
439 cb
->stat_map
= stat_map_64
;
440 sc
.func
= TARGET_LINUX_SYS_fstat
;
441 cb_syscall (cb
, &sc
);
442 cb
->stat_map
= stat_map_32
;
445 case CB_SYS_ftruncate64
:
446 tbuf
+= sprintf (tbuf
, "ftruncate64(%u, %u)", args
[0], args
[1]);
447 sc
.func
= TARGET_LINUX_SYS_ftruncate
;
448 cb_syscall (cb
, &sc
);
452 case CB_SYS_getuid32
:
453 tbuf
+= sprintf (tbuf
, "getuid()");
454 sc
.result
= getuid ();
457 case CB_SYS_getgid32
:
458 tbuf
+= sprintf (tbuf
, "getgid()");
459 sc
.result
= getgid ();
463 case CB_SYS_setuid32
:
464 tbuf
+= sprintf (tbuf
, "setuid(%u)", args
[0]);
465 sc
.result
= setuid (sc
.arg1
);
469 case CB_SYS_setgid32
:
470 tbuf
+= sprintf (tbuf
, "setgid(%u)", args
[0]);
471 sc
.result
= setgid (sc
.arg1
);
475 tbuf
+= sprintf (tbuf
, "getpid()");
476 sc
.result
= getpid ();
479 tbuf
+= sprintf (tbuf
, "kill(%u, %i)", args
[0], args
[1]);
480 /* Only let the app kill itself. */
481 if (sc
.arg1
!= getpid ())
484 sc
.errcode
= TARGET_EPERM
;
489 sc
.result
= kill (sc
.arg1
, sc
.arg2
);
493 sc
.errcode
= TARGET_ENOSYS
;
499 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
500 strcpy (tstr
, "???");
501 tbuf
+= sprintf (tbuf
, "open(%#x:\"%s\", %#x, %o)",
502 args
[0], tstr
, args
[1], args
[2]);
505 tbuf
+= sprintf (tbuf
, "close(%i)", args
[0]);
508 tbuf
+= sprintf (tbuf
, "read(%i, %#x, %u)", args
[0], args
[1], args
[2]);
511 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[1]))
512 strcpy (tstr
, "???");
513 tbuf
+= sprintf (tbuf
, "write(%i, %#x:\"%s\", %u)",
514 args
[0], args
[1], tstr
, args
[2]);
517 tbuf
+= sprintf (tbuf
, "lseek(%i, %i, %i)", args
[0], args
[1], args
[2]);
520 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
521 strcpy (tstr
, "???");
522 tbuf
+= sprintf (tbuf
, "unlink(%#x:\"%s\")", args
[0], tstr
);
524 case CB_SYS_truncate
:
525 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
526 strcpy (tstr
, "???");
527 tbuf
+= sprintf (tbuf
, "truncate(%#x:\"%s\", %i)", args
[0], tstr
, args
[1]);
529 case CB_SYS_ftruncate
:
530 tbuf
+= sprintf (tbuf
, "ftruncate(%i, %i)", args
[0], args
[1]);
533 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
534 strcpy (tstr
, "???");
535 tbuf
+= sprintf (tbuf
, "rename(%#x:\"%s\", ", args
[0], tstr
);
536 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[1]))
537 strcpy (tstr
, "???");
538 tbuf
+= sprintf (tbuf
, "%#x:\"%s\")", args
[1], tstr
);
541 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
542 strcpy (tstr
, "???");
543 tbuf
+= sprintf (tbuf
, "stat(%#x:\"%s\", %#x)", args
[0], tstr
, args
[1]);
546 tbuf
+= sprintf (tbuf
, "fstat(%i, %#x)", args
[0], args
[1]);
549 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
550 strcpy (tstr
, "???");
551 tbuf
+= sprintf (tbuf
, "lstat(%#x:\"%s\", %#x)", args
[0], tstr
, 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
);
609 /* Execute a single instruction. */
612 step_once (SIM_CPU
*cpu
)
614 SIM_DESC sd
= CPU_STATE (cpu
);
615 bu32 insn_len
, oldpc
= PCREG
;
619 if (TRACE_ANY_P (cpu
))
620 trace_prefix (sd
, cpu
, NULL_CIA
, oldpc
, TRACE_LINENUM_P (cpu
),
621 NULL
, 0, " "); /* Use a space for gcc warnings. */
623 /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
624 has already had the SSSTEP bit enabled. */
626 if (STATE_ENVIRONMENT (sd
) == OPERATING_ENVIRONMENT
627 && (SYSCFGREG
& SYSCFG_SSSTEP
))
629 int ivg
= cec_get_ivg (cpu
);
630 if (ivg
== -1 || ivg
> 3)
635 /* XXX: Is this what happens on the hardware ? */
636 if (cec_get_ivg (cpu
) == EVT_EMU
)
637 cec_return (cpu
, EVT_EMU
);
640 BFIN_CPU_STATE
.did_jump
= false;
642 insn_len
= interp_insn_bfin (cpu
, oldpc
);
644 /* If we executed this insn successfully, then we always decrement
645 the loop counter. We don't want to update the PC though if the
646 last insn happened to be a change in code flow (jump/etc...). */
647 if (!BFIN_CPU_STATE
.did_jump
)
648 SET_PCREG (hwloop_get_next_pc (cpu
, oldpc
, insn_len
));
649 for (i
= 1; i
>= 0; --i
)
650 if (LCREG (i
) && oldpc
== LBREG (i
))
652 SET_LCREG (i
, LCREG (i
) - 1);
657 ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
));
659 /* Handle hardware single stepping only if we're still lower than EVT3.
660 XXX: May not be entirely correct wrt EXCPT insns. */
663 int ivg
= cec_get_ivg (cpu
);
664 if (ivg
== -1 || ivg
> 3)
667 cec_exception (cpu
, VEC_STEP
);
675 sim_engine_run (SIM_DESC sd
,
676 int next_cpu_nr
, /* ignore */
677 int nr_cpus
, /* ignore */
678 int siggnal
) /* ignore */
683 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
685 cpu
= STATE_CPU (sd
, 0);
690 /* Process any events -- can't use tickn because it may
691 advance right over the next event. */
692 for (ticks
= 0; ticks
< CYCLE_DELAY
; ++ticks
)
693 if (sim_events_tick (sd
))
694 sim_events_process (sd
);
698 /* Cover function of sim_state_free to free the cpu buffers as well. */
701 free_state (SIM_DESC sd
)
703 if (STATE_MODULES (sd
) != NULL
)
704 sim_module_uninstall (sd
);
705 sim_cpu_free_all (sd
);
709 /* Create an instance of the simulator. */
712 bfin_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
714 memset (&cpu
->state
, 0, sizeof (cpu
->state
));
716 PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
)) = 0;
718 bfin_model_cpu_init (sd
, cpu
);
720 /* Set default stack to top of scratch pad. */
721 SET_SPREG (BFIN_DEFAULT_MEM_SIZE
);
722 SET_KSPREG (BFIN_DEFAULT_MEM_SIZE
);
723 SET_USPREG (BFIN_DEFAULT_MEM_SIZE
);
725 /* This is what the hardware likes. */
726 SET_SYSCFGREG (0x30);
730 sim_open (SIM_OPEN_KIND kind
, host_callback
*callback
,
731 struct bfd
*abfd
, char **argv
)
735 SIM_DESC sd
= sim_state_alloc (kind
, callback
);
737 /* The cpu data is kept in a separately allocated chunk of memory. */
738 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
745 /* XXX: Only first core gets profiled ? */
746 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
747 STATE_WATCHPOINTS (sd
)->pc
= &PCREG
;
748 STATE_WATCHPOINTS (sd
)->sizeof_pc
= sizeof (PCREG
);
751 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
757 /* XXX: Default to the Virtual environment. */
758 if (STATE_ENVIRONMENT (sd
) == ALL_ENVIRONMENT
)
759 STATE_ENVIRONMENT (sd
) = VIRTUAL_ENVIRONMENT
;
761 /* These options override any module options.
762 Obviously ambiguity should be avoided, however the caller may wish to
763 augment the meaning of an option. */
764 #define e_sim_add_option_table(sd, options) \
766 extern const OPTION options[]; \
767 sim_add_option_table (sd, NULL, options); \
769 e_sim_add_option_table (sd
, bfin_mmu_options
);
770 e_sim_add_option_table (sd
, bfin_mach_options
);
772 /* getopt will print the error message so we just have to exit if this fails.
773 FIXME: Hmmm... in the case of gdb we need getopt to call
775 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
781 /* Allocate external memory if none specified by user.
782 Use address 4 here in case the user wanted address 0 unmapped. */
783 if (sim_core_read_buffer (sd
, NULL
, read_map
, &c
, 4, 1) == 0)
785 bu16 emuexcpt
= 0x25;
786 sim_do_commandf (sd
, "memory-size 0x%lx", BFIN_DEFAULT_MEM_SIZE
);
787 sim_write (sd
, 0, (void *)&emuexcpt
, 2);
790 /* Check for/establish the a reference program image. */
791 if (sim_analyze_program (sd
,
792 (STATE_PROG_ARGV (sd
) != NULL
793 ? *STATE_PROG_ARGV (sd
)
794 : NULL
), abfd
) != SIM_RC_OK
)
800 /* Establish any remaining configuration options. */
801 if (sim_config (sd
) != SIM_RC_OK
)
807 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
813 /* CPU specific initialization. */
814 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
816 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
817 bfin_initialize_cpu (sd
, cpu
);
823 /* Some utils don't like having a NULL environ. */
824 static const char * const simple_env
[] = { "HOME=/", "PATH=/bin", NULL
};
826 static bu32 fdpic_load_offset
;
829 bfin_fdpic_load (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
, bu32
*sp
,
830 bu32
*elf_addrs
, char **ldso_path
)
835 Elf_Internal_Ehdr
*iehdr
;
836 Elf32_External_Ehdr ehdr
;
837 Elf_Internal_Phdr
*phdrs
;
845 unsigned char null
[4] = { 0, 0, 0, 0 };
850 /* See if this an FDPIC ELF. */
853 goto skip_fdpic_init
;
854 if (bfd_seek (abfd
, 0, SEEK_SET
) != 0)
855 goto skip_fdpic_init
;
856 if (bfd_bread (&ehdr
, sizeof (ehdr
), abfd
) != sizeof (ehdr
))
857 goto skip_fdpic_init
;
858 iehdr
= elf_elfheader (abfd
);
859 if (!(iehdr
->e_flags
& EF_BFIN_FDPIC
))
860 goto skip_fdpic_init
;
862 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
863 sim_io_printf (sd
, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
864 bfd_get_filename (abfd
), fdpic_load_offset
, elf_addrs
[0]);
866 /* Grab the Program Headers to set up the loadsegs on the stack. */
867 phdr_size
= bfd_get_elf_phdr_upper_bound (abfd
);
869 goto skip_fdpic_init
;
870 phdrs
= xmalloc (phdr_size
);
871 phdrc
= bfd_get_elf_phdrs (abfd
, phdrs
);
873 goto skip_fdpic_init
;
875 /* Push the Ehdr onto the stack. */
876 *sp
-= sizeof (ehdr
);
878 sim_write (sd
, *sp
, (void *)&ehdr
, sizeof (ehdr
));
879 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
880 sim_io_printf (sd
, " Elf_Ehdr: %#x\n", *sp
);
882 /* Since we're relocating things ourselves, we need to relocate
883 the start address as well. */
884 elf_addrs
[0] = bfd_get_start_address (abfd
) + fdpic_load_offset
;
886 /* And the Exec's Phdrs onto the stack. */
887 if (STATE_PROG_BFD (sd
) == abfd
)
889 elf_addrs
[4] = elf_addrs
[0];
891 phdr_size
= iehdr
->e_phentsize
* iehdr
->e_phnum
;
892 if (bfd_seek (abfd
, iehdr
->e_phoff
, SEEK_SET
) != 0)
893 goto skip_fdpic_init
;
894 data
= xmalloc (phdr_size
);
895 if (bfd_bread (data
, phdr_size
, abfd
) != phdr_size
)
896 goto skip_fdpic_init
;
899 elf_addrs
[2] = phdrc
;
900 sim_write (sd
, *sp
, data
, phdr_size
);
902 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
903 sim_io_printf (sd
, " Elf_Phdrs: %#x\n", *sp
);
906 /* Now push all the loadsegs. */
909 for (i
= phdrc
; i
>= 0; --i
)
910 if (phdrs
[i
].p_type
== PT_LOAD
)
912 Elf_Internal_Phdr
*p
= &phdrs
[i
];
913 bu32 paddr
, vaddr
, memsz
, filesz
;
915 paddr
= p
->p_paddr
+ fdpic_load_offset
;
918 filesz
= p
->p_filesz
;
920 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
921 sim_io_printf (sd
, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
922 i
, vaddr
, paddr
, filesz
, memsz
);
924 data
= xmalloc (memsz
);
926 memset (data
+ filesz
, 0, memsz
- filesz
);
928 if (bfd_seek (abfd
, p
->p_offset
, SEEK_SET
) == 0
929 && bfd_bread (data
, filesz
, abfd
) == filesz
)
930 sim_write (sd
, paddr
, data
, memsz
);
934 max_load_addr
= MAX (paddr
+ memsz
, max_load_addr
);
937 sim_write (sd
, *sp
+0, (void *)&paddr
, 4); /* loadseg.addr */
938 sim_write (sd
, *sp
+4, (void *)&vaddr
, 4); /* loadseg.p_vaddr */
939 sim_write (sd
, *sp
+8, (void *)&memsz
, 4); /* loadseg.p_memsz */
942 else if (phdrs
[i
].p_type
== PT_DYNAMIC
)
944 elf_addrs
[5] = phdrs
[i
].p_paddr
+ fdpic_load_offset
;
945 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
946 sim_io_printf (sd
, " PT_DYNAMIC: %#x\n", elf_addrs
[5]);
948 else if (phdrs
[i
].p_type
== PT_INTERP
)
950 uint32_t off
= phdrs
[i
].p_offset
;
951 uint32_t len
= phdrs
[i
].p_filesz
;
953 *ldso_path
= xmalloc (len
);
954 if (bfd_seek (abfd
, off
, SEEK_SET
) != 0
955 || bfd_bread (*ldso_path
, len
, abfd
) != len
)
960 else if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
961 sim_io_printf (sd
, " PT_INTERP: %s\n", *ldso_path
);
964 /* Update the load offset with a few extra pages. */
965 fdpic_load_offset
= ALIGN (MAX (max_load_addr
, fdpic_load_offset
), 0x10000);
966 fdpic_load_offset
+= 0x10000;
968 /* Push the summary loadmap info onto the stack last. */
970 sim_write (sd
, *sp
+0, null
, 2); /* loadmap.version */
971 sim_write (sd
, *sp
+2, (void *)&nsegs
, 2); /* loadmap.nsegs */
981 bfin_user_init (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
,
982 const char * const *argv
, const char * const *env
)
984 /* XXX: Missing host -> target endian ... */
985 /* Linux starts the user app with the stack:
987 argv[0] -- pointers to the actual strings
993 auxvt[0].type -- ELF Auxiliary Vector Table
998 argv[0..N][0..M] -- actual argv/env strings
1000 FDPIC loadmaps -- for FDPIC apps
1001 So set things up the same way. */
1003 bu32 argv_flat
, env_flat
;
1007 /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
1010 bu32 exec_loadmap
, ldso_loadmap
;
1013 unsigned char null
[4] = { 0, 0, 0, 0 };
1015 host_callback
*cb
= STATE_CALLBACK (sd
);
1017 elf_addrs
[0] = elf_addrs
[4] = bfd_get_start_address (abfd
);
1018 elf_addrs
[1] = elf_addrs
[2] = elf_addrs
[3] = elf_addrs
[5] = 0;
1020 /* Keep the load addresses consistent between runs. Also make sure we make
1021 space for the fixed code region (part of the Blackfin Linux ABI). */
1022 fdpic_load_offset
= 0x1000;
1024 /* First try to load this as an FDPIC executable. */
1026 if (!bfin_fdpic_load (sd
, cpu
, STATE_PROG_BFD (sd
), &sp
, elf_addrs
, &ldso_path
))
1027 goto skip_fdpic_init
;
1030 /* If that worked, then load the fixed code region. We only do this for
1031 FDPIC ELFs atm because they are PIEs and let us relocate them without
1032 manual fixups. FLAT files however require location processing which
1033 we do not do ourselves, and they link with a VMA of 0. */
1034 sim_write (sd
, 0x400, bfin_linux_fixed_code
, sizeof (bfin_linux_fixed_code
));
1036 /* If the FDPIC needs an interpreter, then load it up too. */
1039 const char *ldso_full_path
= concat (simulator_sysroot
, ldso_path
, NULL
);
1040 struct bfd
*ldso_bfd
;
1042 ldso_bfd
= bfd_openr (ldso_full_path
, STATE_TARGET (sd
));
1045 sim_io_eprintf (sd
, "bfin-sim: bfd open failed: %s\n", ldso_full_path
);
1048 if (!bfd_check_format (ldso_bfd
, bfd_object
))
1049 sim_io_eprintf (sd
, "bfin-sim: bfd format not valid: %s\n", ldso_full_path
);
1050 bfd_set_arch_info (ldso_bfd
, STATE_ARCHITECTURE (sd
));
1052 if (!bfin_fdpic_load (sd
, cpu
, ldso_bfd
, &sp
, elf_addrs
, &ldso_path
))
1053 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path
);
1055 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
1056 ldso_full_path
, ldso_path
);
1064 /* Finally setup the registers required by the FDPIC ABI. */
1065 SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up. */
1066 SET_PREG (0, exec_loadmap
); /* Exec loadmap addr. */
1067 SET_PREG (1, ldso_loadmap
); /* Interp loadmap addr. */
1068 SET_PREG (2, elf_addrs
[5]); /* PT_DYNAMIC map addr. */
1073 sim_pc_set (cpu
, elf_addrs
[0]);
1075 /* Figure out how much storage the argv/env strings need. */
1076 argc
= count_argc (argv
);
1079 argv_flat
= argc
; /* NUL bytes */
1080 for (i
= 0; i
< argc
; ++i
)
1081 argv_flat
+= strlen (argv
[i
]);
1085 envc
= count_argc (env
);
1086 env_flat
= envc
; /* NUL bytes */
1087 for (i
= 0; i
< envc
; ++i
)
1088 env_flat
+= strlen (env
[i
]);
1090 /* Push the Auxiliary Vector Table between argv/env and actual strings. */
1091 sp_flat
= sp
= ALIGN (SPREG
- argv_flat
- env_flat
- 4, 4);
1094 # define AT_PUSH(at, val) \
1098 sim_write (sd, sp, (void *)&auxvt, 4); \
1101 sim_write (sd, sp, (void *)&auxvt, 4)
1102 unsigned int egid
= getegid (), gid
= getgid ();
1103 unsigned int euid
= geteuid (), uid
= getuid ();
1104 bu32 auxvt_size
= 0;
1105 AT_PUSH (AT_NULL
, 0);
1106 AT_PUSH (AT_SECURE
, egid
!= gid
|| euid
!= uid
);
1107 AT_PUSH (AT_EGID
, egid
);
1108 AT_PUSH (AT_GID
, gid
);
1109 AT_PUSH (AT_EUID
, euid
);
1110 AT_PUSH (AT_UID
, uid
);
1111 AT_PUSH (AT_ENTRY
, elf_addrs
[4]);
1112 AT_PUSH (AT_FLAGS
, 0);
1113 AT_PUSH (AT_BASE
, elf_addrs
[3]);
1114 AT_PUSH (AT_PHNUM
, elf_addrs
[2]);
1115 AT_PUSH (AT_PHENT
, sizeof (Elf32_External_Phdr
));
1116 AT_PUSH (AT_PHDR
, elf_addrs
[1]);
1117 AT_PUSH (AT_CLKTCK
, 100); /* XXX: This ever not 100 ? */
1118 AT_PUSH (AT_PAGESZ
, 4096);
1119 AT_PUSH (AT_HWCAP
, 0);
1124 /* Push the argc/argv/env after the auxvt. */
1125 sp
-= ((1 + argc
+ 1 + envc
+ 1) * 4);
1128 /* First push the argc value. */
1129 sim_write (sd
, sp
, (void *)&argc
, 4);
1132 /* Then the actual argv strings so we know where to point argv[]. */
1133 for (i
= 0; i
< argc
; ++i
)
1135 unsigned len
= strlen (argv
[i
]) + 1;
1136 sim_write (sd
, sp_flat
, (void *)argv
[i
], len
);
1137 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1141 sim_write (sd
, sp
, null
, 4);
1144 /* Then the actual env strings so we know where to point env[]. */
1145 for (i
= 0; i
< envc
; ++i
)
1147 unsigned len
= strlen (env
[i
]) + 1;
1148 sim_write (sd
, sp_flat
, (void *)env
[i
], len
);
1149 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1154 /* Set some callbacks. */
1155 cb
->syscall_map
= cb_linux_syscall_map
;
1156 cb
->errno_map
= cb_linux_errno_map
;
1157 cb
->open_map
= cb_linux_open_map
;
1158 cb
->signal_map
= cb_linux_signal_map
;
1159 cb
->stat_map
= stat_map_32
= cb_linux_stat_map_32
;
1160 stat_map_64
= cb_linux_stat_map_64
;
1164 bfin_os_init (SIM_DESC sd
, SIM_CPU
*cpu
, const char * const *argv
)
1166 /* Pass the command line via a string in R0 like Linux expects. */
1169 bu32 cmdline
= BFIN_L1_SRAM_SCRATCH
;
1171 SET_DREG (0, cmdline
);
1172 if (argv
&& argv
[0])
1178 bu32 len
= strlen (argv
[i
]);
1179 sim_write (sd
, cmdline
, (void *)argv
[i
], len
);
1181 sim_write (sd
, cmdline
, &byte
, 1);
1187 sim_write (sd
, cmdline
, &byte
, 1);
1191 bfin_virtual_init (SIM_DESC sd
, SIM_CPU
*cpu
)
1193 host_callback
*cb
= STATE_CALLBACK (sd
);
1195 cb
->stat_map
= stat_map_32
= cb_libgloss_stat_map_32
;
1200 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
1201 char **argv
, char **env
)
1203 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
1208 addr
= bfd_get_start_address (abfd
);
1211 sim_pc_set (cpu
, addr
);
1213 /* Standalone mode (i.e. `bfin-...-run`) will take care of the argv
1214 for us in sim_open() -> sim_parse_args(). But in debug mode (i.e.
1215 'target sim' with `bfin-...-gdb`), we need to handle it. */
1216 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
1218 freeargv (STATE_PROG_ARGV (sd
));
1219 STATE_PROG_ARGV (sd
) = dupargv (argv
);
1222 switch (STATE_ENVIRONMENT (sd
))
1224 case USER_ENVIRONMENT
:
1225 bfin_user_init (sd
, cpu
, abfd
, (void *)argv
, (void *)env
);
1227 case OPERATING_ENVIRONMENT
:
1228 bfin_os_init (sd
, cpu
, (void *)argv
);
1231 bfin_virtual_init (sd
, cpu
);