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/>. */
21 /* This must come before any other includes. */
33 #include "sim/callback.h"
34 #include "gdb/signals.h"
36 #include "sim-syscall.h"
39 #include "targ-vals.h"
41 /* The numbers here do not matter. They just need to be unique. They also
42 need not be static across releases -- they're used internally only. The
43 mapping from the Linux ABI to the CB values is in linux-targ-map.h. */
44 #define CB_SYS_ioctl 201
45 #define CB_SYS_mmap2 202
46 #define CB_SYS_munmap 203
47 #define CB_SYS_dup2 204
48 #define CB_SYS_getuid 205
49 #define CB_SYS_getuid32 206
50 #define CB_SYS_getgid 207
51 #define CB_SYS_getgid32 208
52 #define CB_SYS_setuid 209
53 #define CB_SYS_setuid32 210
54 #define CB_SYS_setgid 211
55 #define CB_SYS_setgid32 212
56 #define CB_SYS_pread 213
57 #define CB_SYS__llseek 214
58 #define CB_SYS_getcwd 215
59 #define CB_SYS_stat64 216
60 #define CB_SYS_lstat64 217
61 #define CB_SYS_fstat64 218
62 #define CB_SYS_ftruncate64 219
63 #define CB_SYS_gettimeofday 220
64 #define CB_SYS_access 221
65 #include "linux-targ-map.h"
66 #include "linux-fixed-code.h"
68 #include "elf/common.h"
69 #include "elf/external.h"
70 #include "elf/internal.h"
74 #include "dv-bfin_cec.h"
75 #include "dv-bfin_mmu.h"
90 # define setuid(uid) -1
93 # define setgid(gid) -1
96 static const char cb_linux_stat_map_32
[] =
97 /* Linux kernel 32bit layout: */
98 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
99 "space,2:st_size,4:st_blksize,4:st_blocks,4:st_atime,4:st_atimensec,4:"
100 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:space,4";
101 /* uClibc public ABI 32bit layout:
102 "st_dev,8:space,2:space,2:st_ino,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:"
103 "st_rdev,8:space,2:space,2:st_size,4:st_blksiez,4:st_blocks,4:st_atime,4:"
104 "st_atimensec,4:st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:"
106 static const char cb_linux_stat_map_64
[] =
107 "st_dev,8:space,4:space,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:st_rdev,8:"
108 "space,4:st_size,8:st_blksize,4:st_blocks,8:st_atime,4:st_atimensec,4:"
109 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:st_ino,8";
110 static const char cb_libgloss_stat_map_32
[] =
111 "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
112 "st_size,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:"
113 "space,4:st_blksize,4:st_blocks,4:space,8";
114 static const char *stat_map_32
, *stat_map_64
;
116 /* Simulate a monitor trap, put the result into r0 and errno into r1
117 return offset by which to adjust pc. */
120 bfin_syscall (SIM_CPU
*cpu
)
122 SIM_DESC sd
= CPU_STATE (cpu
);
123 char * const *argv
= (void *)STATE_PROG_ARGV (sd
);
124 host_callback
*cb
= STATE_CALLBACK (sd
);
128 char _tbuf
[1024 * 3], *tbuf
= _tbuf
, tstr
[1024];
131 CB_SYSCALL_INIT (&sc
);
133 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
137 sc
.arg1
= args
[0] = DREG (0);
138 sc
.arg2
= args
[1] = DREG (1);
139 sc
.arg3
= args
[2] = DREG (2);
140 sc
.arg4
= args
[3] = DREG (3);
141 /*sc.arg5 =*/ args
[4] = DREG (4);
142 /*sc.arg6 =*/ args
[5] = DREG (5);
146 /* libgloss syscall. */
148 sc
.arg1
= args
[0] = GET_LONG (DREG (0));
149 sc
.arg2
= args
[1] = GET_LONG (DREG (0) + 4);
150 sc
.arg3
= args
[2] = GET_LONG (DREG (0) + 8);
151 sc
.arg4
= args
[3] = GET_LONG (DREG (0) + 12);
152 /*sc.arg5 =*/ args
[4] = GET_LONG (DREG (0) + 16);
153 /*sc.arg6 =*/ args
[5] = GET_LONG (DREG (0) + 20);
157 sc
.read_mem
= sim_syscall_read_mem
;
158 sc
.write_mem
= sim_syscall_write_mem
;
160 /* Common cb_syscall() handles most functions. */
161 switch (cb_target_to_host_syscall (cb
, sc
.func
))
164 tbuf
+= sprintf (tbuf
, "exit(%i)", args
[0]);
165 sim_engine_halt (sd
, cpu
, NULL
, PCREG
, sim_exited
, sc
.arg1
);
169 tbuf
+= sprintf (tbuf
, "argc()");
170 sc
.result
= countargv ((char **)argv
);
174 tbuf
+= sprintf (tbuf
, "argnlen(%u)", args
[0]);
175 if (sc
.arg1
< countargv ((char **)argv
))
176 sc
.result
= strlen (argv
[sc
.arg1
]);
183 tbuf
+= sprintf (tbuf
, "argn(%u)", args
[0]);
184 if (sc
.arg1
< countargv ((char **)argv
))
186 const char *argn
= argv
[sc
.arg1
];
187 int len
= strlen (argn
);
188 int written
= sc
.write_mem (cb
, &sc
, sc
.arg2
, argn
, len
+ 1);
189 if (written
== len
+ 1)
200 case CB_SYS_gettimeofday
:
202 struct timeval _tv
, *tv
= &_tv
;
203 struct timezone _tz
, *tz
= &_tz
;
205 tbuf
+= sprintf (tbuf
, "gettimeofday(%#x, %#x)", args
[0], args
[1]);
211 sc
.result
= gettimeofday (tv
, tz
);
220 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
222 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
227 t
= tz
->tz_minuteswest
;
228 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
230 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
239 /* XXX: hack just enough to get basic stdio w/uClibc ... */
240 tbuf
+= sprintf (tbuf
, "ioctl(%i, %#x, %u)", args
[0], args
[1], args
[2]);
241 if (sc
.arg2
== 0x5401)
243 sc
.result
= !isatty (sc
.arg1
);
249 sc
.errcode
= TARGET_EINVAL
;
255 static bu32 heap
= BFIN_DEFAULT_MEM_SIZE
/ 2;
258 tbuf
+= sprintf (tbuf
, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
259 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
263 if (sc
.arg4
& 0x20 /*MAP_ANONYMOUS*/)
264 /* XXX: We don't handle zeroing, but default is all zeros. */;
265 else if (args
[4] >= MAX_CALLBACK_FDS
)
266 sc
.errcode
= TARGET_ENOSYS
;
270 char *data
= xmalloc (sc
.arg2
);
272 /* XXX: Should add a cb->pread. */
273 if (pread (cb
->fdmap
[args
[4]], data
, sc
.arg2
, args
[5] << 12) == sc
.arg2
)
274 sc
.write_mem (cb
, &sc
, heap
, data
, sc
.arg2
);
276 sc
.errcode
= TARGET_EINVAL
;
280 sc
.errcode
= TARGET_ENOSYS
;
292 /* Keep it page aligned. */
293 heap
= align_up (heap
, 4096);
299 /* XXX: meh, just lie for mmap(). */
300 tbuf
+= sprintf (tbuf
, "munmap(%#x, %u)", args
[0], args
[1]);
305 tbuf
+= sprintf (tbuf
, "dup2(%i, %i)", args
[0], args
[1]);
306 if (sc
.arg1
>= MAX_CALLBACK_FDS
|| sc
.arg2
>= MAX_CALLBACK_FDS
)
309 sc
.errcode
= TARGET_EINVAL
;
313 sc
.result
= dup2 (cb
->fdmap
[sc
.arg1
], cb
->fdmap
[sc
.arg2
]);
319 tbuf
+= sprintf (tbuf
, "llseek(%i, %u, %u, %#x, %u)",
320 args
[0], args
[1], args
[2], args
[3], args
[4]);
321 sc
.func
= TARGET_LINUX_SYS_lseek
;
325 sc
.errcode
= TARGET_EINVAL
;
331 cb_syscall (cb
, &sc
);
335 sc
.write_mem (cb
, &sc
, args
[3], (void *)&sc
.result
, 4);
336 sc
.write_mem (cb
, &sc
, args
[3] + 4, (void *)&z
, 4);
341 /* XXX: Should add a cb->pread. */
343 tbuf
+= sprintf (tbuf
, "pread(%i, %#x, %u, %i)",
344 args
[0], args
[1], args
[2], args
[3]);
345 if (sc
.arg1
>= MAX_CALLBACK_FDS
)
348 sc
.errcode
= TARGET_EINVAL
;
352 long old_pos
, read_result
, read_errcode
;
354 /* Get current filepos. */
355 sc
.func
= TARGET_LINUX_SYS_lseek
;
358 cb_syscall (cb
, &sc
);
363 /* Move to the new pos. */
364 sc
.func
= TARGET_LINUX_SYS_lseek
;
367 cb_syscall (cb
, &sc
);
372 sc
.func
= TARGET_LINUX_SYS_read
;
375 cb_syscall (cb
, &sc
);
376 read_result
= sc
.result
;
377 read_errcode
= sc
.errcode
;
379 /* Move back to the old pos. */
380 sc
.func
= TARGET_LINUX_SYS_lseek
;
383 cb_syscall (cb
, &sc
);
385 sc
.result
= read_result
;
386 sc
.errcode
= read_errcode
;
391 tbuf
+= sprintf (tbuf
, "getcwd(%#x, %u)", args
[0], args
[1]);
393 p
= alloca (sc
.arg2
);
394 if (getcwd (p
, sc
.arg2
) == NULL
)
397 sc
.errcode
= TARGET_EINVAL
;
401 sc
.write_mem (cb
, &sc
, sc
.arg1
, p
, sc
.arg2
);
407 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
408 strcpy (tstr
, "???");
409 tbuf
+= sprintf (tbuf
, "stat64(%#x:\"%s\", %u)", args
[0], tstr
, args
[1]);
410 cb
->stat_map
= stat_map_64
;
411 sc
.func
= TARGET_LINUX_SYS_stat
;
412 cb_syscall (cb
, &sc
);
413 cb
->stat_map
= stat_map_32
;
416 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
417 strcpy (tstr
, "???");
418 tbuf
+= sprintf (tbuf
, "lstat64(%#x:\"%s\", %u)", args
[0], tstr
, args
[1]);
419 cb
->stat_map
= stat_map_64
;
420 sc
.func
= TARGET_LINUX_SYS_lstat
;
421 cb_syscall (cb
, &sc
);
422 cb
->stat_map
= stat_map_32
;
425 tbuf
+= sprintf (tbuf
, "fstat64(%#x, %u)", args
[0], args
[1]);
426 cb
->stat_map
= stat_map_64
;
427 sc
.func
= TARGET_LINUX_SYS_fstat
;
428 cb_syscall (cb
, &sc
);
429 cb
->stat_map
= stat_map_32
;
432 case CB_SYS_ftruncate64
:
433 tbuf
+= sprintf (tbuf
, "ftruncate64(%u, %u)", args
[0], args
[1]);
434 sc
.func
= TARGET_LINUX_SYS_ftruncate
;
435 cb_syscall (cb
, &sc
);
439 case CB_SYS_getuid32
:
440 tbuf
+= sprintf (tbuf
, "getuid()");
441 sc
.result
= getuid ();
444 case CB_SYS_getgid32
:
445 tbuf
+= sprintf (tbuf
, "getgid()");
446 sc
.result
= getgid ();
450 case CB_SYS_setuid32
:
451 tbuf
+= sprintf (tbuf
, "setuid(%u)", args
[0]);
452 sc
.result
= setuid (sc
.arg1
);
456 case CB_SYS_setgid32
:
457 tbuf
+= sprintf (tbuf
, "setgid(%u)", args
[0]);
458 sc
.result
= setgid (sc
.arg1
);
462 tbuf
+= sprintf (tbuf
, "kill(%u, %i)", args
[0], args
[1]);
463 /* Only let the app kill itself. */
464 if (sc
.arg1
!= getpid ())
467 sc
.errcode
= TARGET_EPERM
;
472 sc
.result
= kill (sc
.arg1
, sc
.arg2
);
476 sc
.errcode
= TARGET_ENOSYS
;
482 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
483 strcpy (tstr
, "???");
484 tbuf
+= sprintf (tbuf
, "open(%#x:\"%s\", %#x, %o)",
485 args
[0], tstr
, args
[1], args
[2]);
488 tbuf
+= sprintf (tbuf
, "close(%i)", args
[0]);
491 tbuf
+= sprintf (tbuf
, "read(%i, %#x, %u)", args
[0], args
[1], args
[2]);
494 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[1]))
495 strcpy (tstr
, "???");
496 tbuf
+= sprintf (tbuf
, "write(%i, %#x:\"%s\", %u)",
497 args
[0], args
[1], tstr
, args
[2]);
500 tbuf
+= sprintf (tbuf
, "lseek(%i, %i, %i)", args
[0], args
[1], args
[2]);
503 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
504 strcpy (tstr
, "???");
505 tbuf
+= sprintf (tbuf
, "unlink(%#x:\"%s\")", args
[0], tstr
);
507 case CB_SYS_truncate
:
508 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
509 strcpy (tstr
, "???");
510 tbuf
+= sprintf (tbuf
, "truncate(%#x:\"%s\", %i)", args
[0], tstr
, args
[1]);
512 case CB_SYS_ftruncate
:
513 tbuf
+= sprintf (tbuf
, "ftruncate(%i, %i)", args
[0], args
[1]);
516 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
517 strcpy (tstr
, "???");
518 tbuf
+= sprintf (tbuf
, "rename(%#x:\"%s\", ", args
[0], tstr
);
519 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[1]))
520 strcpy (tstr
, "???");
521 tbuf
+= sprintf (tbuf
, "%#x:\"%s\")", args
[1], tstr
);
524 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
525 strcpy (tstr
, "???");
526 tbuf
+= sprintf (tbuf
, "stat(%#x:\"%s\", %#x)", args
[0], tstr
, args
[1]);
529 tbuf
+= sprintf (tbuf
, "fstat(%i, %#x)", args
[0], args
[1]);
532 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
533 strcpy (tstr
, "???");
534 tbuf
+= sprintf (tbuf
, "lstat(%#x:\"%s\", %#x)", args
[0], tstr
, args
[1]);
537 tbuf
+= sprintf (tbuf
, "pipe(%#x, %#x)", args
[0], args
[1]);
541 tbuf
+= sprintf (tbuf
, "???_%i(%#x, %#x, %#x, %#x, %#x, %#x)", sc
.func
,
542 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
544 cb_syscall (cb
, &sc
);
550 cb
->last_errno
= errno
;
551 sc
.errcode
= cb
->get_errno (cb
);
555 TRACE_EVENTS (cpu
, "syscall_%i(%#x, %#x, %#x, %#x, %#x, %#x) = %li (error = %i)",
556 sc
.func
, args
[0], args
[1], args
[2], args
[3], args
[4], args
[5],
557 sc
.result
, sc
.errcode
);
559 tbuf
+= sprintf (tbuf
, " = ");
560 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
564 tbuf
+= sprintf (tbuf
, "-1 (error = %i)", sc
.errcode
);
565 if (sc
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
567 sim_io_eprintf (sd
, "bfin-sim: %#x: unimplemented syscall %i\n",
570 SET_DREG (0, -sc
.errcode
);
575 tbuf
+= sprintf (tbuf
, "%#lx", sc
.result
);
577 tbuf
+= sprintf (tbuf
, "%lu", sc
.result
);
578 SET_DREG (0, sc
.result
);
583 tbuf
+= sprintf (tbuf
, "%lu (error = %i)", sc
.result
, sc
.errcode
);
584 SET_DREG (0, sc
.result
);
585 SET_DREG (1, sc
.result2
);
586 SET_DREG (2, sc
.errcode
);
589 TRACE_SYSCALL (cpu
, "%s", _tbuf
);
592 /* Execute a single instruction. */
595 step_once (SIM_CPU
*cpu
)
597 SIM_DESC sd
= CPU_STATE (cpu
);
598 bu32 insn_len
, oldpc
= PCREG
;
602 if (TRACE_ANY_P (cpu
))
603 trace_prefix (sd
, cpu
, NULL_CIA
, oldpc
, TRACE_LINENUM_P (cpu
),
604 NULL
, 0, " "); /* Use a space for gcc warnings. */
606 TRACE_DISASM (cpu
, oldpc
);
608 /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
609 has already had the SSSTEP bit enabled. */
611 if (STATE_ENVIRONMENT (sd
) == OPERATING_ENVIRONMENT
612 && (SYSCFGREG
& SYSCFG_SSSTEP
))
614 int ivg
= cec_get_ivg (cpu
);
615 if (ivg
== -1 || ivg
> 3)
620 /* XXX: Is this what happens on the hardware ? */
621 if (cec_get_ivg (cpu
) == EVT_EMU
)
622 cec_return (cpu
, EVT_EMU
);
625 BFIN_CPU_STATE
.did_jump
= false;
627 insn_len
= interp_insn_bfin (cpu
, oldpc
);
629 /* If we executed this insn successfully, then we always decrement
630 the loop counter. We don't want to update the PC though if the
631 last insn happened to be a change in code flow (jump/etc...). */
632 if (!BFIN_CPU_STATE
.did_jump
)
633 SET_PCREG (hwloop_get_next_pc (cpu
, oldpc
, insn_len
));
634 for (i
= 1; i
>= 0; --i
)
635 if (LCREG (i
) && oldpc
== LBREG (i
))
637 SET_LCREG (i
, LCREG (i
) - 1);
642 ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
));
644 /* Handle hardware single stepping only if we're still lower than EVT3.
645 XXX: May not be entirely correct wrt EXCPT insns. */
648 int ivg
= cec_get_ivg (cpu
);
649 if (ivg
== -1 || ivg
> 3)
652 cec_exception (cpu
, VEC_STEP
);
660 sim_engine_run (SIM_DESC sd
,
661 int next_cpu_nr
, /* ignore */
662 int nr_cpus
, /* ignore */
663 int siggnal
) /* ignore */
668 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
670 cpu
= STATE_CPU (sd
, 0);
675 /* Process any events -- can't use tickn because it may
676 advance right over the next event. */
677 for (ticks
= 0; ticks
< CYCLE_DELAY
; ++ticks
)
678 if (sim_events_tick (sd
))
679 sim_events_process (sd
);
683 /* Cover function of sim_state_free to free the cpu buffers as well. */
686 free_state (SIM_DESC sd
)
688 if (STATE_MODULES (sd
) != NULL
)
689 sim_module_uninstall (sd
);
690 sim_cpu_free_all (sd
);
694 /* Create an instance of the simulator. */
697 bfin_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
699 memset (&cpu
->state
, 0, sizeof (cpu
->state
));
701 PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
)) = 0;
703 bfin_model_cpu_init (sd
, cpu
);
705 /* Set default stack to top of scratch pad. */
706 SET_SPREG (BFIN_DEFAULT_MEM_SIZE
);
707 SET_KSPREG (BFIN_DEFAULT_MEM_SIZE
);
708 SET_USPREG (BFIN_DEFAULT_MEM_SIZE
);
710 /* This is what the hardware likes. */
711 SET_SYSCFGREG (0x30);
715 sim_open (SIM_OPEN_KIND kind
, host_callback
*callback
,
716 struct bfd
*abfd
, char * const *argv
)
720 SIM_DESC sd
= sim_state_alloc_extra (kind
, callback
,
721 sizeof (struct bfin_board_data
));
723 /* The cpu data is kept in a separately allocated chunk of memory. */
724 if (sim_cpu_alloc_all (sd
, 1) != SIM_RC_OK
)
730 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
736 /* XXX: Default to the Virtual environment. */
737 if (STATE_ENVIRONMENT (sd
) == ALL_ENVIRONMENT
)
738 STATE_ENVIRONMENT (sd
) = VIRTUAL_ENVIRONMENT
;
740 /* The parser will print an error message for us, so we silently return. */
741 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
747 /* Allocate external memory if none specified by user.
748 Use address 4 here in case the user wanted address 0 unmapped. */
749 if (sim_core_read_buffer (sd
, NULL
, read_map
, &c
, 4, 1) == 0)
751 bu16 emuexcpt
= 0x25;
752 sim_do_commandf (sd
, "memory-size 0x%x", BFIN_DEFAULT_MEM_SIZE
);
753 sim_write (sd
, 0, (void *)&emuexcpt
, 2);
756 /* Check for/establish the a reference program image. */
757 if (sim_analyze_program (sd
,
758 (STATE_PROG_ARGV (sd
) != NULL
759 ? *STATE_PROG_ARGV (sd
)
760 : NULL
), abfd
) != SIM_RC_OK
)
766 /* Establish any remaining configuration options. */
767 if (sim_config (sd
) != SIM_RC_OK
)
773 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
779 /* CPU specific initialization. */
780 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
782 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
783 bfin_initialize_cpu (sd
, cpu
);
789 /* Some utils don't like having a NULL environ. */
790 static char * const simple_env
[] = { "HOME=/", "PATH=/bin", NULL
};
792 static bu32 fdpic_load_offset
;
795 bfin_fdpic_load (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
, bu32
*sp
,
796 bu32
*elf_addrs
, char **ldso_path
)
801 Elf_Internal_Ehdr
*iehdr
;
802 Elf32_External_Ehdr ehdr
;
803 Elf_Internal_Phdr
*phdrs
;
811 unsigned char null
[4] = { 0, 0, 0, 0 };
816 /* See if this an FDPIC ELF. */
819 goto skip_fdpic_init
;
820 if (bfd_seek (abfd
, 0, SEEK_SET
) != 0)
821 goto skip_fdpic_init
;
822 if (bfd_bread (&ehdr
, sizeof (ehdr
), abfd
) != sizeof (ehdr
))
823 goto skip_fdpic_init
;
824 iehdr
= elf_elfheader (abfd
);
825 if (!(iehdr
->e_flags
& EF_BFIN_FDPIC
))
826 goto skip_fdpic_init
;
828 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
829 sim_io_printf (sd
, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
830 bfd_get_filename (abfd
), fdpic_load_offset
, elf_addrs
[0]);
832 /* Grab the Program Headers to set up the loadsegs on the stack. */
833 phdr_size
= bfd_get_elf_phdr_upper_bound (abfd
);
835 goto skip_fdpic_init
;
836 phdrs
= xmalloc (phdr_size
);
837 phdrc
= bfd_get_elf_phdrs (abfd
, phdrs
);
839 goto skip_fdpic_init
;
841 /* Push the Ehdr onto the stack. */
842 *sp
-= sizeof (ehdr
);
844 sim_write (sd
, *sp
, (void *)&ehdr
, sizeof (ehdr
));
845 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
846 sim_io_printf (sd
, " Elf_Ehdr: %#x\n", *sp
);
848 /* Since we're relocating things ourselves, we need to relocate
849 the start address as well. */
850 elf_addrs
[0] = bfd_get_start_address (abfd
) + fdpic_load_offset
;
852 /* And the Exec's Phdrs onto the stack. */
853 if (STATE_PROG_BFD (sd
) == abfd
)
855 elf_addrs
[4] = elf_addrs
[0];
857 phdr_size
= iehdr
->e_phentsize
* iehdr
->e_phnum
;
858 if (bfd_seek (abfd
, iehdr
->e_phoff
, SEEK_SET
) != 0)
859 goto skip_fdpic_init
;
860 data
= xmalloc (phdr_size
);
861 if (bfd_bread (data
, phdr_size
, abfd
) != phdr_size
)
862 goto skip_fdpic_init
;
865 elf_addrs
[2] = phdrc
;
866 sim_write (sd
, *sp
, data
, phdr_size
);
868 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
869 sim_io_printf (sd
, " Elf_Phdrs: %#x\n", *sp
);
872 /* Now push all the loadsegs. */
875 for (i
= phdrc
; i
>= 0; --i
)
876 if (phdrs
[i
].p_type
== PT_LOAD
)
878 Elf_Internal_Phdr
*p
= &phdrs
[i
];
879 bu32 paddr
, vaddr
, memsz
, filesz
;
881 paddr
= p
->p_paddr
+ fdpic_load_offset
;
884 filesz
= p
->p_filesz
;
886 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
887 sim_io_printf (sd
, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
888 i
, vaddr
, paddr
, filesz
, memsz
);
890 data
= xmalloc (memsz
);
892 memset (data
+ filesz
, 0, memsz
- filesz
);
894 if (bfd_seek (abfd
, p
->p_offset
, SEEK_SET
) == 0
895 && bfd_bread (data
, filesz
, abfd
) == filesz
)
896 sim_write (sd
, paddr
, data
, memsz
);
900 max_load_addr
= max (paddr
+ memsz
, max_load_addr
);
903 sim_write (sd
, *sp
+0, (void *)&paddr
, 4); /* loadseg.addr */
904 sim_write (sd
, *sp
+4, (void *)&vaddr
, 4); /* loadseg.p_vaddr */
905 sim_write (sd
, *sp
+8, (void *)&memsz
, 4); /* loadseg.p_memsz */
908 else if (phdrs
[i
].p_type
== PT_DYNAMIC
)
910 elf_addrs
[5] = phdrs
[i
].p_paddr
+ fdpic_load_offset
;
911 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
912 sim_io_printf (sd
, " PT_DYNAMIC: %#x\n", elf_addrs
[5]);
914 else if (phdrs
[i
].p_type
== PT_INTERP
)
916 uint32_t off
= phdrs
[i
].p_offset
;
917 uint32_t len
= phdrs
[i
].p_filesz
;
919 *ldso_path
= xmalloc (len
);
920 if (bfd_seek (abfd
, off
, SEEK_SET
) != 0
921 || bfd_bread (*ldso_path
, len
, abfd
) != len
)
926 else if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
927 sim_io_printf (sd
, " PT_INTERP: %s\n", *ldso_path
);
930 /* Update the load offset with a few extra pages. */
931 fdpic_load_offset
= align_up (max (max_load_addr
, fdpic_load_offset
),
933 fdpic_load_offset
+= 0x10000;
935 /* Push the summary loadmap info onto the stack last. */
937 sim_write (sd
, *sp
+0, null
, 2); /* loadmap.version */
938 sim_write (sd
, *sp
+2, (void *)&nsegs
, 2); /* loadmap.nsegs */
948 bfin_user_init (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
,
949 char * const *argv
, char * const *env
)
951 /* XXX: Missing host -> target endian ... */
952 /* Linux starts the user app with the stack:
954 argv[0] -- pointers to the actual strings
960 auxvt[0].type -- ELF Auxiliary Vector Table
965 argv[0..N][0..M] -- actual argv/env strings
967 FDPIC loadmaps -- for FDPIC apps
968 So set things up the same way. */
970 bu32 argv_flat
, env_flat
;
974 /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
977 bu32 exec_loadmap
, ldso_loadmap
;
980 unsigned char null
[4] = { 0, 0, 0, 0 };
982 host_callback
*cb
= STATE_CALLBACK (sd
);
984 elf_addrs
[0] = elf_addrs
[4] = bfd_get_start_address (abfd
);
985 elf_addrs
[1] = elf_addrs
[2] = elf_addrs
[3] = elf_addrs
[5] = 0;
987 /* Keep the load addresses consistent between runs. Also make sure we make
988 space for the fixed code region (part of the Blackfin Linux ABI). */
989 fdpic_load_offset
= 0x1000;
991 /* First try to load this as an FDPIC executable. */
993 if (!bfin_fdpic_load (sd
, cpu
, STATE_PROG_BFD (sd
), &sp
, elf_addrs
, &ldso_path
))
994 goto skip_fdpic_init
;
997 /* If that worked, then load the fixed code region. We only do this for
998 FDPIC ELFs atm because they are PIEs and let us relocate them without
999 manual fixups. FLAT files however require location processing which
1000 we do not do ourselves, and they link with a VMA of 0. */
1001 sim_write (sd
, 0x400, bfin_linux_fixed_code
, sizeof (bfin_linux_fixed_code
));
1003 /* If the FDPIC needs an interpreter, then load it up too. */
1006 const char *ldso_full_path
= concat (simulator_sysroot
, ldso_path
, NULL
);
1007 struct bfd
*ldso_bfd
;
1009 ldso_bfd
= bfd_openr (ldso_full_path
, STATE_TARGET (sd
));
1012 sim_io_eprintf (sd
, "bfin-sim: bfd open failed: %s\n", ldso_full_path
);
1015 if (!bfd_check_format (ldso_bfd
, bfd_object
))
1016 sim_io_eprintf (sd
, "bfin-sim: bfd format not valid: %s\n", ldso_full_path
);
1017 bfd_set_arch_info (ldso_bfd
, STATE_ARCHITECTURE (sd
));
1019 if (!bfin_fdpic_load (sd
, cpu
, ldso_bfd
, &sp
, elf_addrs
, &ldso_path
))
1020 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path
);
1022 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
1023 ldso_full_path
, ldso_path
);
1031 /* Finally setup the registers required by the FDPIC ABI. */
1032 SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up. */
1033 SET_PREG (0, exec_loadmap
); /* Exec loadmap addr. */
1034 SET_PREG (1, ldso_loadmap
); /* Interp loadmap addr. */
1035 SET_PREG (2, elf_addrs
[5]); /* PT_DYNAMIC map addr. */
1040 sim_pc_set (cpu
, elf_addrs
[0]);
1042 /* Figure out how much storage the argv/env strings need. */
1043 argc
= countargv ((char **)argv
);
1046 argv_flat
= argc
; /* NUL bytes */
1047 for (i
= 0; i
< argc
; ++i
)
1048 argv_flat
+= strlen (argv
[i
]);
1052 envc
= countargv ((char **)env
);
1053 env_flat
= envc
; /* NUL bytes */
1054 for (i
= 0; i
< envc
; ++i
)
1055 env_flat
+= strlen (env
[i
]);
1057 /* Push the Auxiliary Vector Table between argv/env and actual strings. */
1058 sp_flat
= sp
= align_up (SPREG
- argv_flat
- env_flat
- 4, 4);
1061 # define AT_PUSH(at, val) \
1065 sim_write (sd, sp, (void *)&auxvt, 4); \
1068 sim_write (sd, sp, (void *)&auxvt, 4)
1069 unsigned int egid
= getegid (), gid
= getgid ();
1070 unsigned int euid
= geteuid (), uid
= getuid ();
1071 bu32 auxvt_size
= 0;
1072 AT_PUSH (AT_NULL
, 0);
1073 AT_PUSH (AT_SECURE
, egid
!= gid
|| euid
!= uid
);
1074 AT_PUSH (AT_EGID
, egid
);
1075 AT_PUSH (AT_GID
, gid
);
1076 AT_PUSH (AT_EUID
, euid
);
1077 AT_PUSH (AT_UID
, uid
);
1078 AT_PUSH (AT_ENTRY
, elf_addrs
[4]);
1079 AT_PUSH (AT_FLAGS
, 0);
1080 AT_PUSH (AT_BASE
, elf_addrs
[3]);
1081 AT_PUSH (AT_PHNUM
, elf_addrs
[2]);
1082 AT_PUSH (AT_PHENT
, sizeof (Elf32_External_Phdr
));
1083 AT_PUSH (AT_PHDR
, elf_addrs
[1]);
1084 AT_PUSH (AT_CLKTCK
, 100); /* XXX: This ever not 100 ? */
1085 AT_PUSH (AT_PAGESZ
, 4096);
1086 AT_PUSH (AT_HWCAP
, 0);
1091 /* Push the argc/argv/env after the auxvt. */
1092 sp
-= ((1 + argc
+ 1 + envc
+ 1) * 4);
1095 /* First push the argc value. */
1096 sim_write (sd
, sp
, (void *)&argc
, 4);
1099 /* Then the actual argv strings so we know where to point argv[]. */
1100 for (i
= 0; i
< argc
; ++i
)
1102 unsigned len
= strlen (argv
[i
]) + 1;
1103 sim_write (sd
, sp_flat
, (void *)argv
[i
], len
);
1104 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1108 sim_write (sd
, sp
, null
, 4);
1111 /* Then the actual env strings so we know where to point env[]. */
1112 for (i
= 0; i
< envc
; ++i
)
1114 unsigned len
= strlen (env
[i
]) + 1;
1115 sim_write (sd
, sp_flat
, (void *)env
[i
], len
);
1116 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1121 /* Set some callbacks. */
1122 cb
->syscall_map
= cb_linux_syscall_map
;
1123 cb
->errno_map
= cb_linux_errno_map
;
1124 cb
->open_map
= cb_linux_open_map
;
1125 cb
->signal_map
= cb_linux_signal_map
;
1126 cb
->stat_map
= stat_map_32
= cb_linux_stat_map_32
;
1127 stat_map_64
= cb_linux_stat_map_64
;
1131 bfin_os_init (SIM_DESC sd
, SIM_CPU
*cpu
, char * const *argv
)
1133 /* Pass the command line via a string in R0 like Linux expects. */
1136 bu32 cmdline
= BFIN_L1_SRAM_SCRATCH
;
1138 SET_DREG (0, cmdline
);
1139 if (argv
&& argv
[0])
1145 bu32 len
= strlen (argv
[i
]);
1146 sim_write (sd
, cmdline
, (void *)argv
[i
], len
);
1148 sim_write (sd
, cmdline
, &byte
, 1);
1154 sim_write (sd
, cmdline
, &byte
, 1);
1158 bfin_virtual_init (SIM_DESC sd
, SIM_CPU
*cpu
)
1160 host_callback
*cb
= STATE_CALLBACK (sd
);
1162 cb
->stat_map
= stat_map_32
= cb_libgloss_stat_map_32
;
1167 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
1168 char * const *argv
, char * const *env
)
1170 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
1175 addr
= bfd_get_start_address (abfd
);
1178 sim_pc_set (cpu
, addr
);
1180 /* Standalone mode (i.e. `run`) will take care of the argv for us in
1181 sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim'
1182 with `gdb`), we need to handle it because the user can change the
1183 argv on the fly via gdb's 'run'. */
1184 if (STATE_PROG_ARGV (sd
) != argv
)
1186 freeargv (STATE_PROG_ARGV (sd
));
1187 STATE_PROG_ARGV (sd
) = dupargv (argv
);
1190 switch (STATE_ENVIRONMENT (sd
))
1192 case USER_ENVIRONMENT
:
1193 bfin_user_init (sd
, cpu
, abfd
, argv
, env
);
1195 case OPERATING_ENVIRONMENT
:
1196 bfin_os_init (sd
, cpu
, argv
);
1199 bfin_virtual_init (sd
, cpu
);