1 /* Simulator for Analog Devices Blackfin processors.
3 Copyright (C) 2005-2021 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 /* Simulate a monitor trap, put the result into r0 and errno into r1
116 return offset by which to adjust pc. */
119 bfin_syscall (SIM_CPU
*cpu
)
121 SIM_DESC sd
= CPU_STATE (cpu
);
122 char * const *argv
= (void *)STATE_PROG_ARGV (sd
);
123 host_callback
*cb
= STATE_CALLBACK (sd
);
127 char _tbuf
[1024 * 3], *tbuf
= _tbuf
, tstr
[1024];
130 CB_SYSCALL_INIT (&sc
);
132 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
136 sc
.arg1
= args
[0] = DREG (0);
137 sc
.arg2
= args
[1] = DREG (1);
138 sc
.arg3
= args
[2] = DREG (2);
139 sc
.arg4
= args
[3] = DREG (3);
140 /*sc.arg5 =*/ args
[4] = DREG (4);
141 /*sc.arg6 =*/ args
[5] = DREG (5);
145 /* libgloss syscall. */
147 sc
.arg1
= args
[0] = GET_LONG (DREG (0));
148 sc
.arg2
= args
[1] = GET_LONG (DREG (0) + 4);
149 sc
.arg3
= args
[2] = GET_LONG (DREG (0) + 8);
150 sc
.arg4
= args
[3] = GET_LONG (DREG (0) + 12);
151 /*sc.arg5 =*/ args
[4] = GET_LONG (DREG (0) + 16);
152 /*sc.arg6 =*/ args
[5] = GET_LONG (DREG (0) + 20);
156 sc
.read_mem
= sim_syscall_read_mem
;
157 sc
.write_mem
= sim_syscall_write_mem
;
159 /* Common cb_syscall() handles most functions. */
160 switch (cb_target_to_host_syscall (cb
, sc
.func
))
163 tbuf
+= sprintf (tbuf
, "exit(%i)", args
[0]);
164 sim_engine_halt (sd
, cpu
, NULL
, PCREG
, sim_exited
, sc
.arg1
);
168 tbuf
+= sprintf (tbuf
, "argc()");
169 sc
.result
= countargv ((char **)argv
);
173 tbuf
+= sprintf (tbuf
, "argnlen(%u)", args
[0]);
174 if (sc
.arg1
< countargv ((char **)argv
))
175 sc
.result
= strlen (argv
[sc
.arg1
]);
182 tbuf
+= sprintf (tbuf
, "argn(%u)", args
[0]);
183 if (sc
.arg1
< countargv ((char **)argv
))
185 const char *argn
= argv
[sc
.arg1
];
186 int len
= strlen (argn
);
187 int written
= sc
.write_mem (cb
, &sc
, sc
.arg2
, argn
, len
+ 1);
188 if (written
== len
+ 1)
199 case CB_SYS_gettimeofday
:
201 struct timeval _tv
, *tv
= &_tv
;
202 struct timezone _tz
, *tz
= &_tz
;
204 tbuf
+= sprintf (tbuf
, "gettimeofday(%#x, %#x)", args
[0], args
[1]);
210 sc
.result
= gettimeofday (tv
, tz
);
219 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
221 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
226 t
= tz
->tz_minuteswest
;
227 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
229 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
238 /* XXX: hack just enough to get basic stdio w/uClibc ... */
239 tbuf
+= sprintf (tbuf
, "ioctl(%i, %#x, %u)", args
[0], args
[1], args
[2]);
240 if (sc
.arg2
== 0x5401)
242 sc
.result
= !isatty (sc
.arg1
);
248 sc
.errcode
= TARGET_EINVAL
;
254 static bu32 heap
= BFIN_DEFAULT_MEM_SIZE
/ 2;
257 tbuf
+= sprintf (tbuf
, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
258 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
262 if (sc
.arg4
& 0x20 /*MAP_ANONYMOUS*/)
263 /* XXX: We don't handle zeroing, but default is all zeros. */;
264 else if (args
[4] >= MAX_CALLBACK_FDS
)
265 sc
.errcode
= TARGET_ENOSYS
;
269 char *data
= xmalloc (sc
.arg2
);
271 /* XXX: Should add a cb->pread. */
272 if (pread (cb
->fdmap
[args
[4]], data
, sc
.arg2
, args
[5] << 12) == sc
.arg2
)
273 sc
.write_mem (cb
, &sc
, heap
, data
, sc
.arg2
);
275 sc
.errcode
= TARGET_EINVAL
;
279 sc
.errcode
= TARGET_ENOSYS
;
291 /* Keep it page aligned. */
292 heap
= align_up (heap
, 4096);
298 /* XXX: meh, just lie for mmap(). */
299 tbuf
+= sprintf (tbuf
, "munmap(%#x, %u)", args
[0], args
[1]);
304 tbuf
+= sprintf (tbuf
, "dup2(%i, %i)", args
[0], args
[1]);
305 if (sc
.arg1
>= MAX_CALLBACK_FDS
|| sc
.arg2
>= MAX_CALLBACK_FDS
)
308 sc
.errcode
= TARGET_EINVAL
;
312 sc
.result
= dup2 (cb
->fdmap
[sc
.arg1
], cb
->fdmap
[sc
.arg2
]);
318 tbuf
+= sprintf (tbuf
, "llseek(%i, %u, %u, %#x, %u)",
319 args
[0], args
[1], args
[2], args
[3], args
[4]);
320 sc
.func
= TARGET_LINUX_SYS_lseek
;
324 sc
.errcode
= TARGET_EINVAL
;
330 cb_syscall (cb
, &sc
);
334 sc
.write_mem (cb
, &sc
, args
[3], (void *)&sc
.result
, 4);
335 sc
.write_mem (cb
, &sc
, args
[3] + 4, (void *)&z
, 4);
340 /* XXX: Should add a cb->pread. */
342 tbuf
+= sprintf (tbuf
, "pread(%i, %#x, %u, %i)",
343 args
[0], args
[1], args
[2], args
[3]);
344 if (sc
.arg1
>= MAX_CALLBACK_FDS
)
347 sc
.errcode
= TARGET_EINVAL
;
351 long old_pos
, read_result
, read_errcode
;
353 /* Get current filepos. */
354 sc
.func
= TARGET_LINUX_SYS_lseek
;
357 cb_syscall (cb
, &sc
);
362 /* Move to the new pos. */
363 sc
.func
= TARGET_LINUX_SYS_lseek
;
366 cb_syscall (cb
, &sc
);
371 sc
.func
= TARGET_LINUX_SYS_read
;
374 cb_syscall (cb
, &sc
);
375 read_result
= sc
.result
;
376 read_errcode
= sc
.errcode
;
378 /* Move back to the old pos. */
379 sc
.func
= TARGET_LINUX_SYS_lseek
;
382 cb_syscall (cb
, &sc
);
384 sc
.result
= read_result
;
385 sc
.errcode
= read_errcode
;
390 tbuf
+= sprintf (tbuf
, "getcwd(%#x, %u)", args
[0], args
[1]);
392 p
= alloca (sc
.arg2
);
393 if (getcwd (p
, sc
.arg2
) == NULL
)
396 sc
.errcode
= TARGET_EINVAL
;
400 sc
.write_mem (cb
, &sc
, sc
.arg1
, p
, sc
.arg2
);
406 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
407 strcpy (tstr
, "???");
408 tbuf
+= sprintf (tbuf
, "stat64(%#x:\"%s\", %u)", args
[0], tstr
, args
[1]);
409 cb
->stat_map
= stat_map_64
;
410 sc
.func
= TARGET_LINUX_SYS_stat
;
411 cb_syscall (cb
, &sc
);
412 cb
->stat_map
= stat_map_32
;
415 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
416 strcpy (tstr
, "???");
417 tbuf
+= sprintf (tbuf
, "lstat64(%#x:\"%s\", %u)", args
[0], tstr
, args
[1]);
418 cb
->stat_map
= stat_map_64
;
419 sc
.func
= TARGET_LINUX_SYS_lstat
;
420 cb_syscall (cb
, &sc
);
421 cb
->stat_map
= stat_map_32
;
424 tbuf
+= sprintf (tbuf
, "fstat64(%#x, %u)", args
[0], args
[1]);
425 cb
->stat_map
= stat_map_64
;
426 sc
.func
= TARGET_LINUX_SYS_fstat
;
427 cb_syscall (cb
, &sc
);
428 cb
->stat_map
= stat_map_32
;
431 case CB_SYS_ftruncate64
:
432 tbuf
+= sprintf (tbuf
, "ftruncate64(%u, %u)", args
[0], args
[1]);
433 sc
.func
= TARGET_LINUX_SYS_ftruncate
;
434 cb_syscall (cb
, &sc
);
438 case CB_SYS_getuid32
:
439 tbuf
+= sprintf (tbuf
, "getuid()");
440 sc
.result
= getuid ();
443 case CB_SYS_getgid32
:
444 tbuf
+= sprintf (tbuf
, "getgid()");
445 sc
.result
= getgid ();
449 case CB_SYS_setuid32
:
450 tbuf
+= sprintf (tbuf
, "setuid(%u)", args
[0]);
451 sc
.result
= setuid (sc
.arg1
);
455 case CB_SYS_setgid32
:
456 tbuf
+= sprintf (tbuf
, "setgid(%u)", args
[0]);
457 sc
.result
= setgid (sc
.arg1
);
461 tbuf
+= sprintf (tbuf
, "getpid()");
462 sc
.result
= getpid ();
465 tbuf
+= sprintf (tbuf
, "kill(%u, %i)", args
[0], args
[1]);
466 /* Only let the app kill itself. */
467 if (sc
.arg1
!= getpid ())
470 sc
.errcode
= TARGET_EPERM
;
475 sc
.result
= kill (sc
.arg1
, sc
.arg2
);
479 sc
.errcode
= TARGET_ENOSYS
;
485 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
486 strcpy (tstr
, "???");
487 tbuf
+= sprintf (tbuf
, "open(%#x:\"%s\", %#x, %o)",
488 args
[0], tstr
, args
[1], args
[2]);
491 tbuf
+= sprintf (tbuf
, "close(%i)", args
[0]);
494 tbuf
+= sprintf (tbuf
, "read(%i, %#x, %u)", args
[0], args
[1], args
[2]);
497 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[1]))
498 strcpy (tstr
, "???");
499 tbuf
+= sprintf (tbuf
, "write(%i, %#x:\"%s\", %u)",
500 args
[0], args
[1], tstr
, args
[2]);
503 tbuf
+= sprintf (tbuf
, "lseek(%i, %i, %i)", args
[0], args
[1], args
[2]);
506 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
507 strcpy (tstr
, "???");
508 tbuf
+= sprintf (tbuf
, "unlink(%#x:\"%s\")", args
[0], tstr
);
510 case CB_SYS_truncate
:
511 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
512 strcpy (tstr
, "???");
513 tbuf
+= sprintf (tbuf
, "truncate(%#x:\"%s\", %i)", args
[0], tstr
, args
[1]);
515 case CB_SYS_ftruncate
:
516 tbuf
+= sprintf (tbuf
, "ftruncate(%i, %i)", args
[0], args
[1]);
519 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
520 strcpy (tstr
, "???");
521 tbuf
+= sprintf (tbuf
, "rename(%#x:\"%s\", ", args
[0], tstr
);
522 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[1]))
523 strcpy (tstr
, "???");
524 tbuf
+= sprintf (tbuf
, "%#x:\"%s\")", args
[1], tstr
);
527 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
528 strcpy (tstr
, "???");
529 tbuf
+= sprintf (tbuf
, "stat(%#x:\"%s\", %#x)", args
[0], tstr
, args
[1]);
532 tbuf
+= sprintf (tbuf
, "fstat(%i, %#x)", args
[0], args
[1]);
535 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
536 strcpy (tstr
, "???");
537 tbuf
+= sprintf (tbuf
, "lstat(%#x:\"%s\", %#x)", args
[0], tstr
, 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 SET_DREG (1, sc
.result2
);
589 SET_DREG (2, sc
.errcode
);
592 TRACE_SYSCALL (cpu
, "%s", _tbuf
);
595 /* Execute a single instruction. */
598 step_once (SIM_CPU
*cpu
)
600 SIM_DESC sd
= CPU_STATE (cpu
);
601 bu32 insn_len
, oldpc
= PCREG
;
605 if (TRACE_ANY_P (cpu
))
606 trace_prefix (sd
, cpu
, NULL_CIA
, oldpc
, TRACE_LINENUM_P (cpu
),
607 NULL
, 0, " "); /* Use a space for gcc warnings. */
609 TRACE_DISASM (cpu
, oldpc
);
611 /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
612 has already had the SSSTEP bit enabled. */
614 if (STATE_ENVIRONMENT (sd
) == OPERATING_ENVIRONMENT
615 && (SYSCFGREG
& SYSCFG_SSSTEP
))
617 int ivg
= cec_get_ivg (cpu
);
618 if (ivg
== -1 || ivg
> 3)
623 /* XXX: Is this what happens on the hardware ? */
624 if (cec_get_ivg (cpu
) == EVT_EMU
)
625 cec_return (cpu
, EVT_EMU
);
628 BFIN_CPU_STATE
.did_jump
= false;
630 insn_len
= interp_insn_bfin (cpu
, oldpc
);
632 /* If we executed this insn successfully, then we always decrement
633 the loop counter. We don't want to update the PC though if the
634 last insn happened to be a change in code flow (jump/etc...). */
635 if (!BFIN_CPU_STATE
.did_jump
)
636 SET_PCREG (hwloop_get_next_pc (cpu
, oldpc
, insn_len
));
637 for (i
= 1; i
>= 0; --i
)
638 if (LCREG (i
) && oldpc
== LBREG (i
))
640 SET_LCREG (i
, LCREG (i
) - 1);
645 ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
));
647 /* Handle hardware single stepping only if we're still lower than EVT3.
648 XXX: May not be entirely correct wrt EXCPT insns. */
651 int ivg
= cec_get_ivg (cpu
);
652 if (ivg
== -1 || ivg
> 3)
655 cec_exception (cpu
, VEC_STEP
);
663 sim_engine_run (SIM_DESC sd
,
664 int next_cpu_nr
, /* ignore */
665 int nr_cpus
, /* ignore */
666 int siggnal
) /* ignore */
671 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
673 cpu
= STATE_CPU (sd
, 0);
678 /* Process any events -- can't use tickn because it may
679 advance right over the next event. */
680 for (ticks
= 0; ticks
< CYCLE_DELAY
; ++ticks
)
681 if (sim_events_tick (sd
))
682 sim_events_process (sd
);
686 /* Cover function of sim_state_free to free the cpu buffers as well. */
689 free_state (SIM_DESC sd
)
691 if (STATE_MODULES (sd
) != NULL
)
692 sim_module_uninstall (sd
);
693 sim_cpu_free_all (sd
);
697 /* Create an instance of the simulator. */
700 bfin_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
702 memset (&cpu
->state
, 0, sizeof (cpu
->state
));
704 PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
)) = 0;
706 bfin_model_cpu_init (sd
, cpu
);
708 /* Set default stack to top of scratch pad. */
709 SET_SPREG (BFIN_DEFAULT_MEM_SIZE
);
710 SET_KSPREG (BFIN_DEFAULT_MEM_SIZE
);
711 SET_USPREG (BFIN_DEFAULT_MEM_SIZE
);
713 /* This is what the hardware likes. */
714 SET_SYSCFGREG (0x30);
718 sim_open (SIM_OPEN_KIND kind
, host_callback
*callback
,
719 struct bfd
*abfd
, char * const *argv
)
723 SIM_DESC sd
= sim_state_alloc (kind
, callback
);
725 /* The cpu data is kept in a separately allocated chunk of memory. */
726 if (sim_cpu_alloc_all (sd
, 1, /*cgen_cpu_max_extra_bytes ()*/0) != SIM_RC_OK
)
733 /* XXX: Only first core gets profiled ? */
734 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
735 STATE_WATCHPOINTS (sd
)->pc
= &PCREG
;
738 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
744 /* XXX: Default to the Virtual environment. */
745 if (STATE_ENVIRONMENT (sd
) == ALL_ENVIRONMENT
)
746 STATE_ENVIRONMENT (sd
) = VIRTUAL_ENVIRONMENT
;
748 /* These options override any module options.
749 Obviously ambiguity should be avoided, however the caller may wish to
750 augment the meaning of an option. */
751 #define e_sim_add_option_table(sd, options) \
753 extern const OPTION options[]; \
754 sim_add_option_table (sd, NULL, options); \
756 e_sim_add_option_table (sd
, bfin_mmu_options
);
757 e_sim_add_option_table (sd
, bfin_mach_options
);
759 /* The parser will print an error message for us, so we silently return. */
760 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
766 /* Allocate external memory if none specified by user.
767 Use address 4 here in case the user wanted address 0 unmapped. */
768 if (sim_core_read_buffer (sd
, NULL
, read_map
, &c
, 4, 1) == 0)
770 bu16 emuexcpt
= 0x25;
771 sim_do_commandf (sd
, "memory-size 0x%lx", BFIN_DEFAULT_MEM_SIZE
);
772 sim_write (sd
, 0, (void *)&emuexcpt
, 2);
775 /* Check for/establish the a reference program image. */
776 if (sim_analyze_program (sd
,
777 (STATE_PROG_ARGV (sd
) != NULL
778 ? *STATE_PROG_ARGV (sd
)
779 : NULL
), abfd
) != SIM_RC_OK
)
785 /* Establish any remaining configuration options. */
786 if (sim_config (sd
) != SIM_RC_OK
)
792 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
798 /* CPU specific initialization. */
799 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
801 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
802 bfin_initialize_cpu (sd
, cpu
);
808 /* Some utils don't like having a NULL environ. */
809 static char * const simple_env
[] = { "HOME=/", "PATH=/bin", NULL
};
811 static bu32 fdpic_load_offset
;
814 bfin_fdpic_load (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
, bu32
*sp
,
815 bu32
*elf_addrs
, char **ldso_path
)
820 Elf_Internal_Ehdr
*iehdr
;
821 Elf32_External_Ehdr ehdr
;
822 Elf_Internal_Phdr
*phdrs
;
830 unsigned char null
[4] = { 0, 0, 0, 0 };
835 /* See if this an FDPIC ELF. */
838 goto skip_fdpic_init
;
839 if (bfd_seek (abfd
, 0, SEEK_SET
) != 0)
840 goto skip_fdpic_init
;
841 if (bfd_bread (&ehdr
, sizeof (ehdr
), abfd
) != sizeof (ehdr
))
842 goto skip_fdpic_init
;
843 iehdr
= elf_elfheader (abfd
);
844 if (!(iehdr
->e_flags
& EF_BFIN_FDPIC
))
845 goto skip_fdpic_init
;
847 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
848 sim_io_printf (sd
, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
849 bfd_get_filename (abfd
), fdpic_load_offset
, elf_addrs
[0]);
851 /* Grab the Program Headers to set up the loadsegs on the stack. */
852 phdr_size
= bfd_get_elf_phdr_upper_bound (abfd
);
854 goto skip_fdpic_init
;
855 phdrs
= xmalloc (phdr_size
);
856 phdrc
= bfd_get_elf_phdrs (abfd
, phdrs
);
858 goto skip_fdpic_init
;
860 /* Push the Ehdr onto the stack. */
861 *sp
-= sizeof (ehdr
);
863 sim_write (sd
, *sp
, (void *)&ehdr
, sizeof (ehdr
));
864 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
865 sim_io_printf (sd
, " Elf_Ehdr: %#x\n", *sp
);
867 /* Since we're relocating things ourselves, we need to relocate
868 the start address as well. */
869 elf_addrs
[0] = bfd_get_start_address (abfd
) + fdpic_load_offset
;
871 /* And the Exec's Phdrs onto the stack. */
872 if (STATE_PROG_BFD (sd
) == abfd
)
874 elf_addrs
[4] = elf_addrs
[0];
876 phdr_size
= iehdr
->e_phentsize
* iehdr
->e_phnum
;
877 if (bfd_seek (abfd
, iehdr
->e_phoff
, SEEK_SET
) != 0)
878 goto skip_fdpic_init
;
879 data
= xmalloc (phdr_size
);
880 if (bfd_bread (data
, phdr_size
, abfd
) != phdr_size
)
881 goto skip_fdpic_init
;
884 elf_addrs
[2] = phdrc
;
885 sim_write (sd
, *sp
, data
, phdr_size
);
887 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
888 sim_io_printf (sd
, " Elf_Phdrs: %#x\n", *sp
);
891 /* Now push all the loadsegs. */
894 for (i
= phdrc
; i
>= 0; --i
)
895 if (phdrs
[i
].p_type
== PT_LOAD
)
897 Elf_Internal_Phdr
*p
= &phdrs
[i
];
898 bu32 paddr
, vaddr
, memsz
, filesz
;
900 paddr
= p
->p_paddr
+ fdpic_load_offset
;
903 filesz
= p
->p_filesz
;
905 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
906 sim_io_printf (sd
, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
907 i
, vaddr
, paddr
, filesz
, memsz
);
909 data
= xmalloc (memsz
);
911 memset (data
+ filesz
, 0, memsz
- filesz
);
913 if (bfd_seek (abfd
, p
->p_offset
, SEEK_SET
) == 0
914 && bfd_bread (data
, filesz
, abfd
) == filesz
)
915 sim_write (sd
, paddr
, data
, memsz
);
919 max_load_addr
= max (paddr
+ memsz
, max_load_addr
);
922 sim_write (sd
, *sp
+0, (void *)&paddr
, 4); /* loadseg.addr */
923 sim_write (sd
, *sp
+4, (void *)&vaddr
, 4); /* loadseg.p_vaddr */
924 sim_write (sd
, *sp
+8, (void *)&memsz
, 4); /* loadseg.p_memsz */
927 else if (phdrs
[i
].p_type
== PT_DYNAMIC
)
929 elf_addrs
[5] = phdrs
[i
].p_paddr
+ fdpic_load_offset
;
930 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
931 sim_io_printf (sd
, " PT_DYNAMIC: %#x\n", elf_addrs
[5]);
933 else if (phdrs
[i
].p_type
== PT_INTERP
)
935 uint32_t off
= phdrs
[i
].p_offset
;
936 uint32_t len
= phdrs
[i
].p_filesz
;
938 *ldso_path
= xmalloc (len
);
939 if (bfd_seek (abfd
, off
, SEEK_SET
) != 0
940 || bfd_bread (*ldso_path
, len
, abfd
) != len
)
945 else if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
946 sim_io_printf (sd
, " PT_INTERP: %s\n", *ldso_path
);
949 /* Update the load offset with a few extra pages. */
950 fdpic_load_offset
= align_up (max (max_load_addr
, fdpic_load_offset
),
952 fdpic_load_offset
+= 0x10000;
954 /* Push the summary loadmap info onto the stack last. */
956 sim_write (sd
, *sp
+0, null
, 2); /* loadmap.version */
957 sim_write (sd
, *sp
+2, (void *)&nsegs
, 2); /* loadmap.nsegs */
967 bfin_user_init (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
,
968 char * const *argv
, char * const *env
)
970 /* XXX: Missing host -> target endian ... */
971 /* Linux starts the user app with the stack:
973 argv[0] -- pointers to the actual strings
979 auxvt[0].type -- ELF Auxiliary Vector Table
984 argv[0..N][0..M] -- actual argv/env strings
986 FDPIC loadmaps -- for FDPIC apps
987 So set things up the same way. */
989 bu32 argv_flat
, env_flat
;
993 /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
996 bu32 exec_loadmap
, ldso_loadmap
;
999 unsigned char null
[4] = { 0, 0, 0, 0 };
1001 host_callback
*cb
= STATE_CALLBACK (sd
);
1003 elf_addrs
[0] = elf_addrs
[4] = bfd_get_start_address (abfd
);
1004 elf_addrs
[1] = elf_addrs
[2] = elf_addrs
[3] = elf_addrs
[5] = 0;
1006 /* Keep the load addresses consistent between runs. Also make sure we make
1007 space for the fixed code region (part of the Blackfin Linux ABI). */
1008 fdpic_load_offset
= 0x1000;
1010 /* First try to load this as an FDPIC executable. */
1012 if (!bfin_fdpic_load (sd
, cpu
, STATE_PROG_BFD (sd
), &sp
, elf_addrs
, &ldso_path
))
1013 goto skip_fdpic_init
;
1016 /* If that worked, then load the fixed code region. We only do this for
1017 FDPIC ELFs atm because they are PIEs and let us relocate them without
1018 manual fixups. FLAT files however require location processing which
1019 we do not do ourselves, and they link with a VMA of 0. */
1020 sim_write (sd
, 0x400, bfin_linux_fixed_code
, sizeof (bfin_linux_fixed_code
));
1022 /* If the FDPIC needs an interpreter, then load it up too. */
1025 const char *ldso_full_path
= concat (simulator_sysroot
, ldso_path
, NULL
);
1026 struct bfd
*ldso_bfd
;
1028 ldso_bfd
= bfd_openr (ldso_full_path
, STATE_TARGET (sd
));
1031 sim_io_eprintf (sd
, "bfin-sim: bfd open failed: %s\n", ldso_full_path
);
1034 if (!bfd_check_format (ldso_bfd
, bfd_object
))
1035 sim_io_eprintf (sd
, "bfin-sim: bfd format not valid: %s\n", ldso_full_path
);
1036 bfd_set_arch_info (ldso_bfd
, STATE_ARCHITECTURE (sd
));
1038 if (!bfin_fdpic_load (sd
, cpu
, ldso_bfd
, &sp
, elf_addrs
, &ldso_path
))
1039 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path
);
1041 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
1042 ldso_full_path
, ldso_path
);
1050 /* Finally setup the registers required by the FDPIC ABI. */
1051 SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up. */
1052 SET_PREG (0, exec_loadmap
); /* Exec loadmap addr. */
1053 SET_PREG (1, ldso_loadmap
); /* Interp loadmap addr. */
1054 SET_PREG (2, elf_addrs
[5]); /* PT_DYNAMIC map addr. */
1059 sim_pc_set (cpu
, elf_addrs
[0]);
1061 /* Figure out how much storage the argv/env strings need. */
1062 argc
= countargv ((char **)argv
);
1065 argv_flat
= argc
; /* NUL bytes */
1066 for (i
= 0; i
< argc
; ++i
)
1067 argv_flat
+= strlen (argv
[i
]);
1071 envc
= countargv ((char **)env
);
1072 env_flat
= envc
; /* NUL bytes */
1073 for (i
= 0; i
< envc
; ++i
)
1074 env_flat
+= strlen (env
[i
]);
1076 /* Push the Auxiliary Vector Table between argv/env and actual strings. */
1077 sp_flat
= sp
= align_up (SPREG
- argv_flat
- env_flat
- 4, 4);
1080 # define AT_PUSH(at, val) \
1084 sim_write (sd, sp, (void *)&auxvt, 4); \
1087 sim_write (sd, sp, (void *)&auxvt, 4)
1088 unsigned int egid
= getegid (), gid
= getgid ();
1089 unsigned int euid
= geteuid (), uid
= getuid ();
1090 bu32 auxvt_size
= 0;
1091 AT_PUSH (AT_NULL
, 0);
1092 AT_PUSH (AT_SECURE
, egid
!= gid
|| euid
!= uid
);
1093 AT_PUSH (AT_EGID
, egid
);
1094 AT_PUSH (AT_GID
, gid
);
1095 AT_PUSH (AT_EUID
, euid
);
1096 AT_PUSH (AT_UID
, uid
);
1097 AT_PUSH (AT_ENTRY
, elf_addrs
[4]);
1098 AT_PUSH (AT_FLAGS
, 0);
1099 AT_PUSH (AT_BASE
, elf_addrs
[3]);
1100 AT_PUSH (AT_PHNUM
, elf_addrs
[2]);
1101 AT_PUSH (AT_PHENT
, sizeof (Elf32_External_Phdr
));
1102 AT_PUSH (AT_PHDR
, elf_addrs
[1]);
1103 AT_PUSH (AT_CLKTCK
, 100); /* XXX: This ever not 100 ? */
1104 AT_PUSH (AT_PAGESZ
, 4096);
1105 AT_PUSH (AT_HWCAP
, 0);
1110 /* Push the argc/argv/env after the auxvt. */
1111 sp
-= ((1 + argc
+ 1 + envc
+ 1) * 4);
1114 /* First push the argc value. */
1115 sim_write (sd
, sp
, (void *)&argc
, 4);
1118 /* Then the actual argv strings so we know where to point argv[]. */
1119 for (i
= 0; i
< argc
; ++i
)
1121 unsigned len
= strlen (argv
[i
]) + 1;
1122 sim_write (sd
, sp_flat
, (void *)argv
[i
], len
);
1123 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1127 sim_write (sd
, sp
, null
, 4);
1130 /* Then the actual env strings so we know where to point env[]. */
1131 for (i
= 0; i
< envc
; ++i
)
1133 unsigned len
= strlen (env
[i
]) + 1;
1134 sim_write (sd
, sp_flat
, (void *)env
[i
], len
);
1135 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1140 /* Set some callbacks. */
1141 cb
->syscall_map
= cb_linux_syscall_map
;
1142 cb
->errno_map
= cb_linux_errno_map
;
1143 cb
->open_map
= cb_linux_open_map
;
1144 cb
->signal_map
= cb_linux_signal_map
;
1145 cb
->stat_map
= stat_map_32
= cb_linux_stat_map_32
;
1146 stat_map_64
= cb_linux_stat_map_64
;
1150 bfin_os_init (SIM_DESC sd
, SIM_CPU
*cpu
, char * const *argv
)
1152 /* Pass the command line via a string in R0 like Linux expects. */
1155 bu32 cmdline
= BFIN_L1_SRAM_SCRATCH
;
1157 SET_DREG (0, cmdline
);
1158 if (argv
&& argv
[0])
1164 bu32 len
= strlen (argv
[i
]);
1165 sim_write (sd
, cmdline
, (void *)argv
[i
], len
);
1167 sim_write (sd
, cmdline
, &byte
, 1);
1173 sim_write (sd
, cmdline
, &byte
, 1);
1177 bfin_virtual_init (SIM_DESC sd
, SIM_CPU
*cpu
)
1179 host_callback
*cb
= STATE_CALLBACK (sd
);
1181 cb
->stat_map
= stat_map_32
= cb_libgloss_stat_map_32
;
1186 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
1187 char * const *argv
, char * const *env
)
1189 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
1194 addr
= bfd_get_start_address (abfd
);
1197 sim_pc_set (cpu
, addr
);
1199 /* Standalone mode (i.e. `run`) will take care of the argv for us in
1200 sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim'
1201 with `gdb`), we need to handle it because the user can change the
1202 argv on the fly via gdb's 'run'. */
1203 if (STATE_PROG_ARGV (sd
) != argv
)
1205 freeargv (STATE_PROG_ARGV (sd
));
1206 STATE_PROG_ARGV (sd
) = dupargv (argv
);
1209 switch (STATE_ENVIRONMENT (sd
))
1211 case USER_ENVIRONMENT
:
1212 bfin_user_init (sd
, cpu
, abfd
, argv
, env
);
1214 case OPERATING_ENVIRONMENT
:
1215 bfin_os_init (sd
, cpu
, argv
);
1218 bfin_virtual_init (sd
, cpu
);