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 /* Set default options before parsing user options. */
724 current_alignment
= STRICT_ALIGNMENT
;
726 /* The cpu data is kept in a separately allocated chunk of memory. */
727 if (sim_cpu_alloc_all (sd
, 1) != SIM_RC_OK
)
733 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
739 /* XXX: Default to the Virtual environment. */
740 if (STATE_ENVIRONMENT (sd
) == ALL_ENVIRONMENT
)
741 STATE_ENVIRONMENT (sd
) = VIRTUAL_ENVIRONMENT
;
743 /* The parser will print an error message for us, so we silently return. */
744 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
750 /* Allocate external memory if none specified by user.
751 Use address 4 here in case the user wanted address 0 unmapped. */
752 if (sim_core_read_buffer (sd
, NULL
, read_map
, &c
, 4, 1) == 0)
754 bu16 emuexcpt
= 0x25;
755 sim_do_commandf (sd
, "memory-size 0x%x", BFIN_DEFAULT_MEM_SIZE
);
756 sim_write (sd
, 0, (void *)&emuexcpt
, 2);
759 /* Check for/establish the a reference program image. */
760 if (sim_analyze_program (sd
,
761 (STATE_PROG_ARGV (sd
) != NULL
762 ? *STATE_PROG_ARGV (sd
)
763 : NULL
), abfd
) != SIM_RC_OK
)
769 /* Establish any remaining configuration options. */
770 if (sim_config (sd
) != SIM_RC_OK
)
776 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
782 /* CPU specific initialization. */
783 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
785 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
786 bfin_initialize_cpu (sd
, cpu
);
792 /* Some utils don't like having a NULL environ. */
793 static char * const simple_env
[] = { "HOME=/", "PATH=/bin", NULL
};
795 static bu32 fdpic_load_offset
;
798 bfin_fdpic_load (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
, bu32
*sp
,
799 bu32
*elf_addrs
, char **ldso_path
)
804 Elf_Internal_Ehdr
*iehdr
;
805 Elf32_External_Ehdr ehdr
;
806 Elf_Internal_Phdr
*phdrs
;
814 unsigned char null
[4] = { 0, 0, 0, 0 };
819 /* See if this an FDPIC ELF. */
822 goto skip_fdpic_init
;
823 if (bfd_seek (abfd
, 0, SEEK_SET
) != 0)
824 goto skip_fdpic_init
;
825 if (bfd_bread (&ehdr
, sizeof (ehdr
), abfd
) != sizeof (ehdr
))
826 goto skip_fdpic_init
;
827 iehdr
= elf_elfheader (abfd
);
828 if (!(iehdr
->e_flags
& EF_BFIN_FDPIC
))
829 goto skip_fdpic_init
;
831 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
832 sim_io_printf (sd
, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
833 bfd_get_filename (abfd
), fdpic_load_offset
, elf_addrs
[0]);
835 /* Grab the Program Headers to set up the loadsegs on the stack. */
836 phdr_size
= bfd_get_elf_phdr_upper_bound (abfd
);
838 goto skip_fdpic_init
;
839 phdrs
= xmalloc (phdr_size
);
840 phdrc
= bfd_get_elf_phdrs (abfd
, phdrs
);
842 goto skip_fdpic_init
;
844 /* Push the Ehdr onto the stack. */
845 *sp
-= sizeof (ehdr
);
847 sim_write (sd
, *sp
, (void *)&ehdr
, sizeof (ehdr
));
848 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
849 sim_io_printf (sd
, " Elf_Ehdr: %#x\n", *sp
);
851 /* Since we're relocating things ourselves, we need to relocate
852 the start address as well. */
853 elf_addrs
[0] = bfd_get_start_address (abfd
) + fdpic_load_offset
;
855 /* And the Exec's Phdrs onto the stack. */
856 if (STATE_PROG_BFD (sd
) == abfd
)
858 elf_addrs
[4] = elf_addrs
[0];
860 phdr_size
= iehdr
->e_phentsize
* iehdr
->e_phnum
;
861 if (bfd_seek (abfd
, iehdr
->e_phoff
, SEEK_SET
) != 0)
862 goto skip_fdpic_init
;
863 data
= xmalloc (phdr_size
);
864 if (bfd_bread (data
, phdr_size
, abfd
) != phdr_size
)
865 goto skip_fdpic_init
;
868 elf_addrs
[2] = phdrc
;
869 sim_write (sd
, *sp
, data
, phdr_size
);
871 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
872 sim_io_printf (sd
, " Elf_Phdrs: %#x\n", *sp
);
875 /* Now push all the loadsegs. */
878 for (i
= phdrc
; i
>= 0; --i
)
879 if (phdrs
[i
].p_type
== PT_LOAD
)
881 Elf_Internal_Phdr
*p
= &phdrs
[i
];
882 bu32 paddr
, vaddr
, memsz
, filesz
;
884 paddr
= p
->p_paddr
+ fdpic_load_offset
;
887 filesz
= p
->p_filesz
;
889 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
890 sim_io_printf (sd
, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
891 i
, vaddr
, paddr
, filesz
, memsz
);
893 data
= xmalloc (memsz
);
895 memset (data
+ filesz
, 0, memsz
- filesz
);
897 if (bfd_seek (abfd
, p
->p_offset
, SEEK_SET
) == 0
898 && bfd_bread (data
, filesz
, abfd
) == filesz
)
899 sim_write (sd
, paddr
, data
, memsz
);
903 max_load_addr
= max (paddr
+ memsz
, max_load_addr
);
906 sim_write (sd
, *sp
+0, (void *)&paddr
, 4); /* loadseg.addr */
907 sim_write (sd
, *sp
+4, (void *)&vaddr
, 4); /* loadseg.p_vaddr */
908 sim_write (sd
, *sp
+8, (void *)&memsz
, 4); /* loadseg.p_memsz */
911 else if (phdrs
[i
].p_type
== PT_DYNAMIC
)
913 elf_addrs
[5] = phdrs
[i
].p_paddr
+ fdpic_load_offset
;
914 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
915 sim_io_printf (sd
, " PT_DYNAMIC: %#x\n", elf_addrs
[5]);
917 else if (phdrs
[i
].p_type
== PT_INTERP
)
919 uint32_t off
= phdrs
[i
].p_offset
;
920 uint32_t len
= phdrs
[i
].p_filesz
;
922 *ldso_path
= xmalloc (len
);
923 if (bfd_seek (abfd
, off
, SEEK_SET
) != 0
924 || bfd_bread (*ldso_path
, len
, abfd
) != len
)
929 else if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
930 sim_io_printf (sd
, " PT_INTERP: %s\n", *ldso_path
);
933 /* Update the load offset with a few extra pages. */
934 fdpic_load_offset
= align_up (max (max_load_addr
, fdpic_load_offset
),
936 fdpic_load_offset
+= 0x10000;
938 /* Push the summary loadmap info onto the stack last. */
940 sim_write (sd
, *sp
+0, null
, 2); /* loadmap.version */
941 sim_write (sd
, *sp
+2, (void *)&nsegs
, 2); /* loadmap.nsegs */
951 bfin_user_init (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
,
952 char * const *argv
, char * const *env
)
954 /* XXX: Missing host -> target endian ... */
955 /* Linux starts the user app with the stack:
957 argv[0] -- pointers to the actual strings
963 auxvt[0].type -- ELF Auxiliary Vector Table
968 argv[0..N][0..M] -- actual argv/env strings
970 FDPIC loadmaps -- for FDPIC apps
971 So set things up the same way. */
973 bu32 argv_flat
, env_flat
;
977 /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
980 bu32 exec_loadmap
, ldso_loadmap
;
983 unsigned char null
[4] = { 0, 0, 0, 0 };
985 host_callback
*cb
= STATE_CALLBACK (sd
);
987 elf_addrs
[0] = elf_addrs
[4] = bfd_get_start_address (abfd
);
988 elf_addrs
[1] = elf_addrs
[2] = elf_addrs
[3] = elf_addrs
[5] = 0;
990 /* Keep the load addresses consistent between runs. Also make sure we make
991 space for the fixed code region (part of the Blackfin Linux ABI). */
992 fdpic_load_offset
= 0x1000;
994 /* First try to load this as an FDPIC executable. */
996 if (!bfin_fdpic_load (sd
, cpu
, STATE_PROG_BFD (sd
), &sp
, elf_addrs
, &ldso_path
))
997 goto skip_fdpic_init
;
1000 /* If that worked, then load the fixed code region. We only do this for
1001 FDPIC ELFs atm because they are PIEs and let us relocate them without
1002 manual fixups. FLAT files however require location processing which
1003 we do not do ourselves, and they link with a VMA of 0. */
1004 sim_write (sd
, 0x400, bfin_linux_fixed_code
, sizeof (bfin_linux_fixed_code
));
1006 /* If the FDPIC needs an interpreter, then load it up too. */
1009 const char *ldso_full_path
= concat (simulator_sysroot
, ldso_path
, NULL
);
1010 struct bfd
*ldso_bfd
;
1012 ldso_bfd
= bfd_openr (ldso_full_path
, STATE_TARGET (sd
));
1015 sim_io_eprintf (sd
, "bfin-sim: bfd open failed: %s\n", ldso_full_path
);
1018 if (!bfd_check_format (ldso_bfd
, bfd_object
))
1019 sim_io_eprintf (sd
, "bfin-sim: bfd format not valid: %s\n", ldso_full_path
);
1020 bfd_set_arch_info (ldso_bfd
, STATE_ARCHITECTURE (sd
));
1022 if (!bfin_fdpic_load (sd
, cpu
, ldso_bfd
, &sp
, elf_addrs
, &ldso_path
))
1023 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path
);
1025 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
1026 ldso_full_path
, ldso_path
);
1034 /* Finally setup the registers required by the FDPIC ABI. */
1035 SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up. */
1036 SET_PREG (0, exec_loadmap
); /* Exec loadmap addr. */
1037 SET_PREG (1, ldso_loadmap
); /* Interp loadmap addr. */
1038 SET_PREG (2, elf_addrs
[5]); /* PT_DYNAMIC map addr. */
1043 sim_pc_set (cpu
, elf_addrs
[0]);
1045 /* Figure out how much storage the argv/env strings need. */
1046 argc
= countargv ((char **)argv
);
1049 argv_flat
= argc
; /* NUL bytes */
1050 for (i
= 0; i
< argc
; ++i
)
1051 argv_flat
+= strlen (argv
[i
]);
1055 envc
= countargv ((char **)env
);
1056 env_flat
= envc
; /* NUL bytes */
1057 for (i
= 0; i
< envc
; ++i
)
1058 env_flat
+= strlen (env
[i
]);
1060 /* Push the Auxiliary Vector Table between argv/env and actual strings. */
1061 sp_flat
= sp
= align_up (SPREG
- argv_flat
- env_flat
- 4, 4);
1064 # define AT_PUSH(at, val) \
1068 sim_write (sd, sp, (void *)&auxvt, 4); \
1071 sim_write (sd, sp, (void *)&auxvt, 4)
1072 unsigned int egid
= getegid (), gid
= getgid ();
1073 unsigned int euid
= geteuid (), uid
= getuid ();
1074 bu32 auxvt_size
= 0;
1075 AT_PUSH (AT_NULL
, 0);
1076 AT_PUSH (AT_SECURE
, egid
!= gid
|| euid
!= uid
);
1077 AT_PUSH (AT_EGID
, egid
);
1078 AT_PUSH (AT_GID
, gid
);
1079 AT_PUSH (AT_EUID
, euid
);
1080 AT_PUSH (AT_UID
, uid
);
1081 AT_PUSH (AT_ENTRY
, elf_addrs
[4]);
1082 AT_PUSH (AT_FLAGS
, 0);
1083 AT_PUSH (AT_BASE
, elf_addrs
[3]);
1084 AT_PUSH (AT_PHNUM
, elf_addrs
[2]);
1085 AT_PUSH (AT_PHENT
, sizeof (Elf32_External_Phdr
));
1086 AT_PUSH (AT_PHDR
, elf_addrs
[1]);
1087 AT_PUSH (AT_CLKTCK
, 100); /* XXX: This ever not 100 ? */
1088 AT_PUSH (AT_PAGESZ
, 4096);
1089 AT_PUSH (AT_HWCAP
, 0);
1094 /* Push the argc/argv/env after the auxvt. */
1095 sp
-= ((1 + argc
+ 1 + envc
+ 1) * 4);
1098 /* First push the argc value. */
1099 sim_write (sd
, sp
, (void *)&argc
, 4);
1102 /* Then the actual argv strings so we know where to point argv[]. */
1103 for (i
= 0; i
< argc
; ++i
)
1105 unsigned len
= strlen (argv
[i
]) + 1;
1106 sim_write (sd
, sp_flat
, (void *)argv
[i
], len
);
1107 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1111 sim_write (sd
, sp
, null
, 4);
1114 /* Then the actual env strings so we know where to point env[]. */
1115 for (i
= 0; i
< envc
; ++i
)
1117 unsigned len
= strlen (env
[i
]) + 1;
1118 sim_write (sd
, sp_flat
, (void *)env
[i
], len
);
1119 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1124 /* Set some callbacks. */
1125 cb
->syscall_map
= cb_linux_syscall_map
;
1126 cb
->errno_map
= cb_linux_errno_map
;
1127 cb
->open_map
= cb_linux_open_map
;
1128 cb
->signal_map
= cb_linux_signal_map
;
1129 cb
->stat_map
= stat_map_32
= cb_linux_stat_map_32
;
1130 stat_map_64
= cb_linux_stat_map_64
;
1134 bfin_os_init (SIM_DESC sd
, SIM_CPU
*cpu
, char * const *argv
)
1136 /* Pass the command line via a string in R0 like Linux expects. */
1139 bu32 cmdline
= BFIN_L1_SRAM_SCRATCH
;
1141 SET_DREG (0, cmdline
);
1142 if (argv
&& argv
[0])
1148 bu32 len
= strlen (argv
[i
]);
1149 sim_write (sd
, cmdline
, (void *)argv
[i
], len
);
1151 sim_write (sd
, cmdline
, &byte
, 1);
1157 sim_write (sd
, cmdline
, &byte
, 1);
1161 bfin_virtual_init (SIM_DESC sd
, SIM_CPU
*cpu
)
1163 host_callback
*cb
= STATE_CALLBACK (sd
);
1165 cb
->stat_map
= stat_map_32
= cb_libgloss_stat_map_32
;
1170 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
1171 char * const *argv
, char * const *env
)
1173 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
1178 addr
= bfd_get_start_address (abfd
);
1181 sim_pc_set (cpu
, addr
);
1183 /* Standalone mode (i.e. `run`) will take care of the argv for us in
1184 sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim'
1185 with `gdb`), we need to handle it because the user can change the
1186 argv on the fly via gdb's 'run'. */
1187 if (STATE_PROG_ARGV (sd
) != argv
)
1189 freeargv (STATE_PROG_ARGV (sd
));
1190 STATE_PROG_ARGV (sd
) = dupargv (argv
);
1193 switch (STATE_ENVIRONMENT (sd
))
1195 case USER_ENVIRONMENT
:
1196 bfin_user_init (sd
, cpu
, abfd
, argv
, env
);
1198 case OPERATING_ENVIRONMENT
:
1199 bfin_os_init (sd
, cpu
, argv
);
1202 bfin_virtual_init (sd
, cpu
);