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 "portability.h"
34 #include "sim/callback.h"
35 #include "gdb/signals.h"
37 #include "sim-syscall.h"
40 #include "targ-vals.h"
42 /* The numbers here do not matter. They just need to be unique. They also
43 need not be static across releases -- they're used internally only. The
44 mapping from the Linux ABI to the CB values is in linux-targ-map.h. */
45 #define CB_SYS_ioctl 201
46 #define CB_SYS_mmap2 202
47 #define CB_SYS_munmap 203
48 #define CB_SYS_dup2 204
49 #define CB_SYS_getuid 205
50 #define CB_SYS_getuid32 206
51 #define CB_SYS_getgid 207
52 #define CB_SYS_getgid32 208
53 #define CB_SYS_setuid 209
54 #define CB_SYS_setuid32 210
55 #define CB_SYS_setgid 211
56 #define CB_SYS_setgid32 212
57 #define CB_SYS_pread 213
58 #define CB_SYS__llseek 214
59 #define CB_SYS_getcwd 215
60 #define CB_SYS_stat64 216
61 #define CB_SYS_lstat64 217
62 #define CB_SYS_fstat64 218
63 #define CB_SYS_ftruncate64 219
64 #define CB_SYS_gettimeofday 220
65 #define CB_SYS_access 221
66 #include "linux-targ-map.h"
67 #include "linux-fixed-code.h"
69 #include "elf/common.h"
70 #include "elf/external.h"
71 #include "elf/internal.h"
75 #include "dv-bfin_cec.h"
76 #include "dv-bfin_mmu.h"
78 static const char cb_linux_stat_map_32
[] =
79 /* Linux kernel 32bit layout: */
80 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
81 "space,2:st_size,4:st_blksize,4:st_blocks,4:st_atime,4:st_atimensec,4:"
82 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:space,4";
83 /* uClibc public ABI 32bit layout:
84 "st_dev,8:space,2:space,2:st_ino,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:"
85 "st_rdev,8:space,2:space,2:st_size,4:st_blksiez,4:st_blocks,4:st_atime,4:"
86 "st_atimensec,4:st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:"
88 static const char cb_linux_stat_map_64
[] =
89 "st_dev,8:space,4:space,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:st_rdev,8:"
90 "space,4:st_size,8:st_blksize,4:st_blocks,8:st_atime,4:st_atimensec,4:"
91 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:st_ino,8";
92 static const char cb_libgloss_stat_map_32
[] =
93 "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
94 "st_size,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:"
95 "space,4:st_blksize,4:st_blocks,4:space,8";
96 static const char *stat_map_32
, *stat_map_64
;
98 /* Simulate a monitor trap, put the result into r0 and errno into r1
99 return offset by which to adjust pc. */
102 bfin_syscall (SIM_CPU
*cpu
)
104 SIM_DESC sd
= CPU_STATE (cpu
);
105 char * const *argv
= (void *)STATE_PROG_ARGV (sd
);
106 host_callback
*cb
= STATE_CALLBACK (sd
);
110 char _tbuf
[1024 * 3], *tbuf
= _tbuf
, tstr
[1024];
113 CB_SYSCALL_INIT (&sc
);
115 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
119 sc
.arg1
= args
[0] = DREG (0);
120 sc
.arg2
= args
[1] = DREG (1);
121 sc
.arg3
= args
[2] = DREG (2);
122 sc
.arg4
= args
[3] = DREG (3);
123 sc
.arg5
= args
[4] = DREG (4);
124 sc
.arg6
= args
[5] = DREG (5);
128 /* libgloss syscall. */
130 sc
.arg1
= args
[0] = GET_LONG (DREG (0));
131 sc
.arg2
= args
[1] = GET_LONG (DREG (0) + 4);
132 sc
.arg3
= args
[2] = GET_LONG (DREG (0) + 8);
133 sc
.arg4
= args
[3] = GET_LONG (DREG (0) + 12);
134 sc
.arg5
= args
[4] = GET_LONG (DREG (0) + 16);
135 sc
.arg6
= args
[5] = GET_LONG (DREG (0) + 20);
139 sc
.read_mem
= sim_syscall_read_mem
;
140 sc
.write_mem
= sim_syscall_write_mem
;
142 /* Common cb_syscall() handles most functions. */
143 switch (cb_target_to_host_syscall (cb
, sc
.func
))
146 tbuf
+= sprintf (tbuf
, "exit(%i)", args
[0]);
147 sim_engine_halt (sd
, cpu
, NULL
, PCREG
, sim_exited
, sc
.arg1
);
151 tbuf
+= sprintf (tbuf
, "argc()");
152 sc
.result
= countargv ((char **)argv
);
156 tbuf
+= sprintf (tbuf
, "argnlen(%u)", args
[0]);
157 if (sc
.arg1
< countargv ((char **)argv
))
158 sc
.result
= strlen (argv
[sc
.arg1
]);
165 tbuf
+= sprintf (tbuf
, "argn(%u)", args
[0]);
166 if (sc
.arg1
< countargv ((char **)argv
))
168 const char *argn
= argv
[sc
.arg1
];
169 int len
= strlen (argn
);
170 int written
= sc
.write_mem (cb
, &sc
, sc
.arg2
, argn
, len
+ 1);
171 if (written
== len
+ 1)
182 case CB_SYS_gettimeofday
:
184 struct timeval _tv
, *tv
= &_tv
;
185 struct timezone _tz
, *tz
= &_tz
;
187 tbuf
+= sprintf (tbuf
, "gettimeofday(%#x, %#x)", args
[0], args
[1]);
193 sc
.result
= gettimeofday (tv
, tz
);
202 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
204 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
209 t
= tz
->tz_minuteswest
;
210 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
212 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
221 /* XXX: hack just enough to get basic stdio w/uClibc ... */
222 tbuf
+= sprintf (tbuf
, "ioctl(%i, %#x, %u)", args
[0], args
[1], args
[2]);
223 if (sc
.arg2
== 0x5401)
225 sc
.result
= !isatty (sc
.arg1
);
231 sc
.errcode
= TARGET_EINVAL
;
237 static bu32 heap
= BFIN_DEFAULT_MEM_SIZE
/ 2;
240 tbuf
+= sprintf (tbuf
, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
241 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
245 if (sc
.arg4
& 0x20 /*MAP_ANONYMOUS*/)
246 /* XXX: We don't handle zeroing, but default is all zeros. */;
247 else if (args
[4] >= MAX_CALLBACK_FDS
)
248 sc
.errcode
= TARGET_ENOSYS
;
252 char *data
= xmalloc (sc
.arg2
);
254 /* XXX: Should add a cb->pread. */
255 if (pread (cb
->fdmap
[args
[4]], data
, sc
.arg2
, args
[5] << 12) == sc
.arg2
)
256 sc
.write_mem (cb
, &sc
, heap
, data
, sc
.arg2
);
258 sc
.errcode
= TARGET_EINVAL
;
262 sc
.errcode
= TARGET_ENOSYS
;
274 /* Keep it page aligned. */
275 heap
= align_up (heap
, 4096);
281 /* XXX: meh, just lie for mmap(). */
282 tbuf
+= sprintf (tbuf
, "munmap(%#x, %u)", args
[0], args
[1]);
287 tbuf
+= sprintf (tbuf
, "dup2(%i, %i)", args
[0], args
[1]);
288 if (sc
.arg1
>= MAX_CALLBACK_FDS
|| sc
.arg2
>= MAX_CALLBACK_FDS
)
291 sc
.errcode
= TARGET_EINVAL
;
295 sc
.result
= dup2 (cb
->fdmap
[sc
.arg1
], cb
->fdmap
[sc
.arg2
]);
301 tbuf
+= sprintf (tbuf
, "llseek(%i, %u, %u, %#x, %u)",
302 args
[0], args
[1], args
[2], args
[3], args
[4]);
303 sc
.func
= TARGET_LINUX_SYS_lseek
;
307 sc
.errcode
= TARGET_EINVAL
;
313 cb_syscall (cb
, &sc
);
317 sc
.write_mem (cb
, &sc
, args
[3], (void *)&sc
.result
, 4);
318 sc
.write_mem (cb
, &sc
, args
[3] + 4, (void *)&z
, 4);
323 /* XXX: Should add a cb->pread. */
325 tbuf
+= sprintf (tbuf
, "pread(%i, %#x, %u, %i)",
326 args
[0], args
[1], args
[2], args
[3]);
327 if (sc
.arg1
>= MAX_CALLBACK_FDS
)
330 sc
.errcode
= TARGET_EINVAL
;
334 long old_pos
, read_result
, read_errcode
;
336 /* Get current filepos. */
337 sc
.func
= TARGET_LINUX_SYS_lseek
;
340 cb_syscall (cb
, &sc
);
345 /* Move to the new pos. */
346 sc
.func
= TARGET_LINUX_SYS_lseek
;
349 cb_syscall (cb
, &sc
);
354 sc
.func
= TARGET_LINUX_SYS_read
;
357 cb_syscall (cb
, &sc
);
358 read_result
= sc
.result
;
359 read_errcode
= sc
.errcode
;
361 /* Move back to the old pos. */
362 sc
.func
= TARGET_LINUX_SYS_lseek
;
365 cb_syscall (cb
, &sc
);
367 sc
.result
= read_result
;
368 sc
.errcode
= read_errcode
;
373 tbuf
+= sprintf (tbuf
, "getcwd(%#x, %u)", args
[0], args
[1]);
375 p
= alloca (sc
.arg2
);
376 if (getcwd (p
, sc
.arg2
) == NULL
)
379 sc
.errcode
= TARGET_EINVAL
;
383 sc
.write_mem (cb
, &sc
, sc
.arg1
, p
, sc
.arg2
);
389 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
390 strcpy (tstr
, "???");
391 tbuf
+= sprintf (tbuf
, "stat64(%#x:\"%s\", %u)", args
[0], tstr
, args
[1]);
392 cb
->stat_map
= stat_map_64
;
393 sc
.func
= TARGET_LINUX_SYS_stat
;
394 cb_syscall (cb
, &sc
);
395 cb
->stat_map
= stat_map_32
;
398 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
399 strcpy (tstr
, "???");
400 tbuf
+= sprintf (tbuf
, "lstat64(%#x:\"%s\", %u)", args
[0], tstr
, args
[1]);
401 cb
->stat_map
= stat_map_64
;
402 sc
.func
= TARGET_LINUX_SYS_lstat
;
403 cb_syscall (cb
, &sc
);
404 cb
->stat_map
= stat_map_32
;
407 tbuf
+= sprintf (tbuf
, "fstat64(%#x, %u)", args
[0], args
[1]);
408 cb
->stat_map
= stat_map_64
;
409 sc
.func
= TARGET_LINUX_SYS_fstat
;
410 cb_syscall (cb
, &sc
);
411 cb
->stat_map
= stat_map_32
;
414 case CB_SYS_ftruncate64
:
415 tbuf
+= sprintf (tbuf
, "ftruncate64(%u, %u)", args
[0], args
[1]);
416 sc
.func
= TARGET_LINUX_SYS_ftruncate
;
417 cb_syscall (cb
, &sc
);
421 case CB_SYS_getuid32
:
422 tbuf
+= sprintf (tbuf
, "getuid()");
423 sc
.result
= getuid ();
426 case CB_SYS_getgid32
:
427 tbuf
+= sprintf (tbuf
, "getgid()");
428 sc
.result
= getgid ();
432 case CB_SYS_setuid32
:
433 tbuf
+= sprintf (tbuf
, "setuid(%u)", args
[0]);
434 sc
.result
= setuid (sc
.arg1
);
438 case CB_SYS_setgid32
:
439 tbuf
+= sprintf (tbuf
, "setgid(%u)", args
[0]);
440 sc
.result
= setgid (sc
.arg1
);
444 tbuf
+= sprintf (tbuf
, "kill(%u, %i)", args
[0], args
[1]);
445 /* Only let the app kill itself. */
446 if (sc
.arg1
!= getpid ())
449 sc
.errcode
= TARGET_EPERM
;
454 sc
.result
= kill (sc
.arg1
, sc
.arg2
);
458 sc
.errcode
= TARGET_ENOSYS
;
464 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
465 strcpy (tstr
, "???");
466 tbuf
+= sprintf (tbuf
, "open(%#x:\"%s\", %#x, %o)",
467 args
[0], tstr
, args
[1], args
[2]);
470 tbuf
+= sprintf (tbuf
, "close(%i)", args
[0]);
473 tbuf
+= sprintf (tbuf
, "read(%i, %#x, %u)", args
[0], args
[1], args
[2]);
476 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[1]))
477 strcpy (tstr
, "???");
478 tbuf
+= sprintf (tbuf
, "write(%i, %#x:\"%s\", %u)",
479 args
[0], args
[1], tstr
, args
[2]);
482 tbuf
+= sprintf (tbuf
, "lseek(%i, %i, %i)", args
[0], args
[1], args
[2]);
485 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
486 strcpy (tstr
, "???");
487 tbuf
+= sprintf (tbuf
, "unlink(%#x:\"%s\")", args
[0], tstr
);
489 case CB_SYS_truncate
:
490 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
491 strcpy (tstr
, "???");
492 tbuf
+= sprintf (tbuf
, "truncate(%#x:\"%s\", %i)", args
[0], tstr
, args
[1]);
494 case CB_SYS_ftruncate
:
495 tbuf
+= sprintf (tbuf
, "ftruncate(%i, %i)", args
[0], args
[1]);
498 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
499 strcpy (tstr
, "???");
500 tbuf
+= sprintf (tbuf
, "rename(%#x:\"%s\", ", args
[0], tstr
);
501 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[1]))
502 strcpy (tstr
, "???");
503 tbuf
+= sprintf (tbuf
, "%#x:\"%s\")", args
[1], tstr
);
506 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
507 strcpy (tstr
, "???");
508 tbuf
+= sprintf (tbuf
, "stat(%#x:\"%s\", %#x)", args
[0], tstr
, args
[1]);
511 tbuf
+= sprintf (tbuf
, "fstat(%i, %#x)", args
[0], args
[1]);
514 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
515 strcpy (tstr
, "???");
516 tbuf
+= sprintf (tbuf
, "lstat(%#x:\"%s\", %#x)", args
[0], tstr
, args
[1]);
519 tbuf
+= sprintf (tbuf
, "pipe(%#x, %#x)", args
[0], args
[1]);
523 tbuf
+= sprintf (tbuf
, "???_%i(%#x, %#x, %#x, %#x, %#x, %#x)", sc
.func
,
524 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
526 cb_syscall (cb
, &sc
);
532 cb
->last_errno
= errno
;
533 sc
.errcode
= cb
->get_errno (cb
);
537 TRACE_EVENTS (cpu
, "syscall_%i(%#x, %#x, %#x, %#x, %#x, %#x) = %li (error = %i)",
538 sc
.func
, args
[0], args
[1], args
[2], args
[3], args
[4], args
[5],
539 sc
.result
, sc
.errcode
);
541 tbuf
+= sprintf (tbuf
, " = ");
542 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
546 tbuf
+= sprintf (tbuf
, "-1 (error = %i)", sc
.errcode
);
547 if (sc
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
549 sim_io_eprintf (sd
, "bfin-sim: %#x: unimplemented syscall %i\n",
552 SET_DREG (0, -sc
.errcode
);
557 tbuf
+= sprintf (tbuf
, "%#lx", sc
.result
);
559 tbuf
+= sprintf (tbuf
, "%lu", sc
.result
);
560 SET_DREG (0, sc
.result
);
565 tbuf
+= sprintf (tbuf
, "%lu (error = %i)", sc
.result
, sc
.errcode
);
566 SET_DREG (0, sc
.result
);
567 SET_DREG (1, sc
.result2
);
568 SET_DREG (2, sc
.errcode
);
571 TRACE_SYSCALL (cpu
, "%s", _tbuf
);
574 /* Execute a single instruction. */
577 step_once (SIM_CPU
*cpu
)
579 SIM_DESC sd
= CPU_STATE (cpu
);
580 bu32 insn_len
, oldpc
= PCREG
;
584 if (TRACE_ANY_P (cpu
))
585 trace_prefix (sd
, cpu
, NULL_CIA
, oldpc
, TRACE_LINENUM_P (cpu
),
586 NULL
, 0, " "); /* Use a space for gcc warnings. */
588 TRACE_DISASM (cpu
, oldpc
);
590 /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
591 has already had the SSSTEP bit enabled. */
593 if (STATE_ENVIRONMENT (sd
) == OPERATING_ENVIRONMENT
594 && (SYSCFGREG
& SYSCFG_SSSTEP
))
596 int ivg
= cec_get_ivg (cpu
);
597 if (ivg
== -1 || ivg
> 3)
602 /* XXX: Is this what happens on the hardware ? */
603 if (cec_get_ivg (cpu
) == EVT_EMU
)
604 cec_return (cpu
, EVT_EMU
);
607 BFIN_CPU_STATE
.did_jump
= false;
609 insn_len
= interp_insn_bfin (cpu
, oldpc
);
611 /* If we executed this insn successfully, then we always decrement
612 the loop counter. We don't want to update the PC though if the
613 last insn happened to be a change in code flow (jump/etc...). */
614 if (!BFIN_CPU_STATE
.did_jump
)
615 SET_PCREG (hwloop_get_next_pc (cpu
, oldpc
, insn_len
));
616 for (i
= 1; i
>= 0; --i
)
617 if (LCREG (i
) && oldpc
== LBREG (i
))
619 SET_LCREG (i
, LCREG (i
) - 1);
624 ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
));
626 /* Handle hardware single stepping only if we're still lower than EVT3.
627 XXX: May not be entirely correct wrt EXCPT insns. */
630 int ivg
= cec_get_ivg (cpu
);
631 if (ivg
== -1 || ivg
> 3)
634 cec_exception (cpu
, VEC_STEP
);
642 sim_engine_run (SIM_DESC sd
,
643 int next_cpu_nr
, /* ignore */
644 int nr_cpus
, /* ignore */
645 int siggnal
) /* ignore */
650 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
652 cpu
= STATE_CPU (sd
, 0);
657 /* Process any events -- can't use tickn because it may
658 advance right over the next event. */
659 for (ticks
= 0; ticks
< CYCLE_DELAY
; ++ticks
)
660 if (sim_events_tick (sd
))
661 sim_events_process (sd
);
665 /* Cover function of sim_state_free to free the cpu buffers as well. */
668 free_state (SIM_DESC sd
)
670 if (STATE_MODULES (sd
) != NULL
)
671 sim_module_uninstall (sd
);
672 sim_cpu_free_all (sd
);
676 /* Create an instance of the simulator. */
679 bfin_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
681 memset (&cpu
->state
, 0, sizeof (cpu
->state
));
683 PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
)) = 0;
685 bfin_model_cpu_init (sd
, cpu
);
687 /* Set default stack to top of scratch pad. */
688 SET_SPREG (BFIN_DEFAULT_MEM_SIZE
);
689 SET_KSPREG (BFIN_DEFAULT_MEM_SIZE
);
690 SET_USPREG (BFIN_DEFAULT_MEM_SIZE
);
692 /* This is what the hardware likes. */
693 SET_SYSCFGREG (0x30);
697 sim_open (SIM_OPEN_KIND kind
, host_callback
*callback
,
698 struct bfd
*abfd
, char * const *argv
)
702 SIM_DESC sd
= sim_state_alloc_extra (kind
, callback
,
703 sizeof (struct bfin_board_data
));
705 /* Set default options before parsing user options. */
706 STATE_MACHS (sd
) = bfin_sim_machs
;
707 current_alignment
= STRICT_ALIGNMENT
;
708 current_target_byte_order
= BFD_ENDIAN_LITTLE
;
710 /* The cpu data is kept in a separately allocated chunk of memory. */
711 if (sim_cpu_alloc_all (sd
, 1) != SIM_RC_OK
)
717 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
723 /* XXX: Default to the Virtual environment. */
724 if (STATE_ENVIRONMENT (sd
) == ALL_ENVIRONMENT
)
725 STATE_ENVIRONMENT (sd
) = VIRTUAL_ENVIRONMENT
;
727 /* The parser will print an error message for us, so we silently return. */
728 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
734 /* Allocate external memory if none specified by user.
735 Use address 4 here in case the user wanted address 0 unmapped. */
736 if (sim_core_read_buffer (sd
, NULL
, read_map
, &c
, 4, 1) == 0)
738 bu16 emuexcpt
= 0x25;
739 sim_do_commandf (sd
, "memory-size 0x%x", BFIN_DEFAULT_MEM_SIZE
);
740 sim_write (sd
, 0, (void *)&emuexcpt
, 2);
743 /* Check for/establish the a reference program image. */
744 if (sim_analyze_program (sd
,
745 (STATE_PROG_ARGV (sd
) != NULL
746 ? *STATE_PROG_ARGV (sd
)
747 : NULL
), abfd
) != SIM_RC_OK
)
753 /* Establish any remaining configuration options. */
754 if (sim_config (sd
) != SIM_RC_OK
)
760 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
766 /* CPU specific initialization. */
767 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
769 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
770 bfin_initialize_cpu (sd
, cpu
);
776 /* Some utils don't like having a NULL environ. */
777 static char * const simple_env
[] = { "HOME=/", "PATH=/bin", NULL
};
779 static bu32 fdpic_load_offset
;
782 bfin_fdpic_load (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
, bu32
*sp
,
783 bu32
*elf_addrs
, char **ldso_path
)
788 Elf_Internal_Ehdr
*iehdr
;
789 Elf32_External_Ehdr ehdr
;
790 Elf_Internal_Phdr
*phdrs
;
798 unsigned char null
[4] = { 0, 0, 0, 0 };
803 /* See if this an FDPIC ELF. */
806 goto skip_fdpic_init
;
807 if (bfd_seek (abfd
, 0, SEEK_SET
) != 0)
808 goto skip_fdpic_init
;
809 if (bfd_bread (&ehdr
, sizeof (ehdr
), abfd
) != sizeof (ehdr
))
810 goto skip_fdpic_init
;
811 iehdr
= elf_elfheader (abfd
);
812 if (!(iehdr
->e_flags
& EF_BFIN_FDPIC
))
813 goto skip_fdpic_init
;
815 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
816 sim_io_printf (sd
, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
817 bfd_get_filename (abfd
), fdpic_load_offset
, elf_addrs
[0]);
819 /* Grab the Program Headers to set up the loadsegs on the stack. */
820 phdr_size
= bfd_get_elf_phdr_upper_bound (abfd
);
822 goto skip_fdpic_init
;
823 phdrs
= xmalloc (phdr_size
);
824 phdrc
= bfd_get_elf_phdrs (abfd
, phdrs
);
826 goto skip_fdpic_init
;
828 /* Push the Ehdr onto the stack. */
829 *sp
-= sizeof (ehdr
);
831 sim_write (sd
, *sp
, (void *)&ehdr
, sizeof (ehdr
));
832 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
833 sim_io_printf (sd
, " Elf_Ehdr: %#x\n", *sp
);
835 /* Since we're relocating things ourselves, we need to relocate
836 the start address as well. */
837 elf_addrs
[0] = bfd_get_start_address (abfd
) + fdpic_load_offset
;
839 /* And the Exec's Phdrs onto the stack. */
840 if (STATE_PROG_BFD (sd
) == abfd
)
842 elf_addrs
[4] = elf_addrs
[0];
844 phdr_size
= iehdr
->e_phentsize
* iehdr
->e_phnum
;
845 if (bfd_seek (abfd
, iehdr
->e_phoff
, SEEK_SET
) != 0)
846 goto skip_fdpic_init
;
847 data
= xmalloc (phdr_size
);
848 if (bfd_bread (data
, phdr_size
, abfd
) != phdr_size
)
849 goto skip_fdpic_init
;
852 elf_addrs
[2] = phdrc
;
853 sim_write (sd
, *sp
, data
, phdr_size
);
855 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
856 sim_io_printf (sd
, " Elf_Phdrs: %#x\n", *sp
);
859 /* Now push all the loadsegs. */
862 for (i
= phdrc
; i
>= 0; --i
)
863 if (phdrs
[i
].p_type
== PT_LOAD
)
865 Elf_Internal_Phdr
*p
= &phdrs
[i
];
866 bu32 paddr
, vaddr
, memsz
, filesz
;
868 paddr
= p
->p_paddr
+ fdpic_load_offset
;
871 filesz
= p
->p_filesz
;
873 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
874 sim_io_printf (sd
, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
875 i
, vaddr
, paddr
, filesz
, memsz
);
877 data
= xmalloc (memsz
);
879 memset (data
+ filesz
, 0, memsz
- filesz
);
881 if (bfd_seek (abfd
, p
->p_offset
, SEEK_SET
) == 0
882 && bfd_bread (data
, filesz
, abfd
) == filesz
)
883 sim_write (sd
, paddr
, data
, memsz
);
887 max_load_addr
= max (paddr
+ memsz
, max_load_addr
);
890 sim_write (sd
, *sp
+0, (void *)&paddr
, 4); /* loadseg.addr */
891 sim_write (sd
, *sp
+4, (void *)&vaddr
, 4); /* loadseg.p_vaddr */
892 sim_write (sd
, *sp
+8, (void *)&memsz
, 4); /* loadseg.p_memsz */
895 else if (phdrs
[i
].p_type
== PT_DYNAMIC
)
897 elf_addrs
[5] = phdrs
[i
].p_paddr
+ fdpic_load_offset
;
898 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
899 sim_io_printf (sd
, " PT_DYNAMIC: %#x\n", elf_addrs
[5]);
901 else if (phdrs
[i
].p_type
== PT_INTERP
)
903 uint32_t off
= phdrs
[i
].p_offset
;
904 uint32_t len
= phdrs
[i
].p_filesz
;
906 *ldso_path
= xmalloc (len
);
907 if (bfd_seek (abfd
, off
, SEEK_SET
) != 0
908 || bfd_bread (*ldso_path
, len
, abfd
) != len
)
913 else if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
914 sim_io_printf (sd
, " PT_INTERP: %s\n", *ldso_path
);
917 /* Update the load offset with a few extra pages. */
918 fdpic_load_offset
= align_up (max (max_load_addr
, fdpic_load_offset
),
920 fdpic_load_offset
+= 0x10000;
922 /* Push the summary loadmap info onto the stack last. */
924 sim_write (sd
, *sp
+0, null
, 2); /* loadmap.version */
925 sim_write (sd
, *sp
+2, (void *)&nsegs
, 2); /* loadmap.nsegs */
935 bfin_user_init (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
,
936 char * const *argv
, char * const *env
)
938 /* XXX: Missing host -> target endian ... */
939 /* Linux starts the user app with the stack:
941 argv[0] -- pointers to the actual strings
947 auxvt[0].type -- ELF Auxiliary Vector Table
952 argv[0..N][0..M] -- actual argv/env strings
954 FDPIC loadmaps -- for FDPIC apps
955 So set things up the same way. */
957 bu32 argv_flat
, env_flat
;
961 /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
964 bu32 exec_loadmap
, ldso_loadmap
;
967 unsigned char null
[4] = { 0, 0, 0, 0 };
969 host_callback
*cb
= STATE_CALLBACK (sd
);
971 elf_addrs
[0] = elf_addrs
[4] = bfd_get_start_address (abfd
);
972 elf_addrs
[1] = elf_addrs
[2] = elf_addrs
[3] = elf_addrs
[5] = 0;
974 /* Keep the load addresses consistent between runs. Also make sure we make
975 space for the fixed code region (part of the Blackfin Linux ABI). */
976 fdpic_load_offset
= 0x1000;
978 /* First try to load this as an FDPIC executable. */
980 if (!bfin_fdpic_load (sd
, cpu
, STATE_PROG_BFD (sd
), &sp
, elf_addrs
, &ldso_path
))
981 goto skip_fdpic_init
;
984 /* If that worked, then load the fixed code region. We only do this for
985 FDPIC ELFs atm because they are PIEs and let us relocate them without
986 manual fixups. FLAT files however require location processing which
987 we do not do ourselves, and they link with a VMA of 0. */
988 sim_write (sd
, 0x400, bfin_linux_fixed_code
, sizeof (bfin_linux_fixed_code
));
990 /* If the FDPIC needs an interpreter, then load it up too. */
993 const char *ldso_full_path
= concat (simulator_sysroot
, ldso_path
, NULL
);
994 struct bfd
*ldso_bfd
;
996 ldso_bfd
= bfd_openr (ldso_full_path
, STATE_TARGET (sd
));
999 sim_io_eprintf (sd
, "bfin-sim: bfd open failed: %s\n", ldso_full_path
);
1002 if (!bfd_check_format (ldso_bfd
, bfd_object
))
1003 sim_io_eprintf (sd
, "bfin-sim: bfd format not valid: %s\n", ldso_full_path
);
1004 bfd_set_arch_info (ldso_bfd
, STATE_ARCHITECTURE (sd
));
1006 if (!bfin_fdpic_load (sd
, cpu
, ldso_bfd
, &sp
, elf_addrs
, &ldso_path
))
1007 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path
);
1009 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
1010 ldso_full_path
, ldso_path
);
1018 /* Finally setup the registers required by the FDPIC ABI. */
1019 SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up. */
1020 SET_PREG (0, exec_loadmap
); /* Exec loadmap addr. */
1021 SET_PREG (1, ldso_loadmap
); /* Interp loadmap addr. */
1022 SET_PREG (2, elf_addrs
[5]); /* PT_DYNAMIC map addr. */
1027 sim_pc_set (cpu
, elf_addrs
[0]);
1029 /* Figure out how much storage the argv/env strings need. */
1030 argc
= countargv ((char **)argv
);
1033 argv_flat
= argc
; /* NUL bytes */
1034 for (i
= 0; i
< argc
; ++i
)
1035 argv_flat
+= strlen (argv
[i
]);
1039 envc
= countargv ((char **)env
);
1040 env_flat
= envc
; /* NUL bytes */
1041 for (i
= 0; i
< envc
; ++i
)
1042 env_flat
+= strlen (env
[i
]);
1044 /* Push the Auxiliary Vector Table between argv/env and actual strings. */
1045 sp_flat
= sp
= align_up (SPREG
- argv_flat
- env_flat
- 4, 4);
1048 # define AT_PUSH(at, val) \
1052 sim_write (sd, sp, (void *)&auxvt, 4); \
1055 sim_write (sd, sp, (void *)&auxvt, 4)
1056 unsigned int egid
= getegid (), gid
= getgid ();
1057 unsigned int euid
= geteuid (), uid
= getuid ();
1058 bu32 auxvt_size
= 0;
1059 AT_PUSH (AT_NULL
, 0);
1060 AT_PUSH (AT_SECURE
, egid
!= gid
|| euid
!= uid
);
1061 AT_PUSH (AT_EGID
, egid
);
1062 AT_PUSH (AT_GID
, gid
);
1063 AT_PUSH (AT_EUID
, euid
);
1064 AT_PUSH (AT_UID
, uid
);
1065 AT_PUSH (AT_ENTRY
, elf_addrs
[4]);
1066 AT_PUSH (AT_FLAGS
, 0);
1067 AT_PUSH (AT_BASE
, elf_addrs
[3]);
1068 AT_PUSH (AT_PHNUM
, elf_addrs
[2]);
1069 AT_PUSH (AT_PHENT
, sizeof (Elf32_External_Phdr
));
1070 AT_PUSH (AT_PHDR
, elf_addrs
[1]);
1071 AT_PUSH (AT_CLKTCK
, 100); /* XXX: This ever not 100 ? */
1072 AT_PUSH (AT_PAGESZ
, 4096);
1073 AT_PUSH (AT_HWCAP
, 0);
1078 /* Push the argc/argv/env after the auxvt. */
1079 sp
-= ((1 + argc
+ 1 + envc
+ 1) * 4);
1082 /* First push the argc value. */
1083 sim_write (sd
, sp
, (void *)&argc
, 4);
1086 /* Then the actual argv strings so we know where to point argv[]. */
1087 for (i
= 0; i
< argc
; ++i
)
1089 unsigned len
= strlen (argv
[i
]) + 1;
1090 sim_write (sd
, sp_flat
, (void *)argv
[i
], len
);
1091 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1095 sim_write (sd
, sp
, null
, 4);
1098 /* Then the actual env strings so we know where to point env[]. */
1099 for (i
= 0; i
< envc
; ++i
)
1101 unsigned len
= strlen (env
[i
]) + 1;
1102 sim_write (sd
, sp_flat
, (void *)env
[i
], len
);
1103 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1108 /* Set some callbacks. */
1109 cb
->syscall_map
= cb_linux_syscall_map
;
1110 cb
->errno_map
= cb_linux_errno_map
;
1111 cb
->open_map
= cb_linux_open_map
;
1112 cb
->signal_map
= cb_linux_signal_map
;
1113 cb
->stat_map
= stat_map_32
= cb_linux_stat_map_32
;
1114 stat_map_64
= cb_linux_stat_map_64
;
1118 bfin_os_init (SIM_DESC sd
, SIM_CPU
*cpu
, char * const *argv
)
1120 /* Pass the command line via a string in R0 like Linux expects. */
1123 bu32 cmdline
= BFIN_L1_SRAM_SCRATCH
;
1125 SET_DREG (0, cmdline
);
1126 if (argv
&& argv
[0])
1132 bu32 len
= strlen (argv
[i
]);
1133 sim_write (sd
, cmdline
, (void *)argv
[i
], len
);
1135 sim_write (sd
, cmdline
, &byte
, 1);
1141 sim_write (sd
, cmdline
, &byte
, 1);
1145 bfin_virtual_init (SIM_DESC sd
, SIM_CPU
*cpu
)
1147 host_callback
*cb
= STATE_CALLBACK (sd
);
1149 cb
->stat_map
= stat_map_32
= cb_libgloss_stat_map_32
;
1154 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
1155 char * const *argv
, char * const *env
)
1157 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
1162 addr
= bfd_get_start_address (abfd
);
1165 sim_pc_set (cpu
, addr
);
1167 /* Standalone mode (i.e. `run`) will take care of the argv for us in
1168 sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim'
1169 with `gdb`), we need to handle it because the user can change the
1170 argv on the fly via gdb's 'run'. */
1171 if (STATE_PROG_ARGV (sd
) != argv
)
1173 freeargv (STATE_PROG_ARGV (sd
));
1174 STATE_PROG_ARGV (sd
) = dupargv (argv
);
1177 switch (STATE_ENVIRONMENT (sd
))
1179 case USER_ENVIRONMENT
:
1180 bfin_user_init (sd
, cpu
, abfd
, argv
, env
);
1182 case OPERATING_ENVIRONMENT
:
1183 bfin_os_init (sd
, cpu
, argv
);
1186 bfin_virtual_init (sd
, cpu
);