1 /* Simulator for Analog Devices Blackfin processors.
3 Copyright (C) 2005-2023 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-options.h"
38 #include "sim-syscall.h"
43 /* The numbers here do not matter. They just need to be unique. They also
44 need not be static across releases -- they're used internally only. The
45 mapping from the Linux ABI to the CB values is in linux-targ-map.h. */
46 #define CB_SYS_ioctl 201
47 #define CB_SYS_mmap2 202
48 #define CB_SYS_munmap 203
49 #define CB_SYS_dup2 204
50 #define CB_SYS_getuid 205
51 #define CB_SYS_getuid32 206
52 #define CB_SYS_getgid 207
53 #define CB_SYS_getgid32 208
54 #define CB_SYS_setuid 209
55 #define CB_SYS_setuid32 210
56 #define CB_SYS_setgid 211
57 #define CB_SYS_setgid32 212
58 #define CB_SYS_pread 213
59 #define CB_SYS__llseek 214
60 #define CB_SYS_getcwd 215
61 #define CB_SYS_stat64 216
62 #define CB_SYS_lstat64 217
63 #define CB_SYS_fstat64 218
64 #define CB_SYS_ftruncate64 219
65 #define CB_SYS_gettimeofday 220
66 #define CB_SYS_access 221
67 #include "linux-targ-map.h"
68 #include "linux-fixed-code.h"
70 #include "elf/common.h"
71 #include "elf/external.h"
72 #include "elf/internal.h"
76 #include "dv-bfin_cec.h"
77 #include "dv-bfin_mmu.h"
79 static const char cb_linux_stat_map_32
[] =
80 /* Linux kernel 32bit layout: */
81 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
82 "space,2:st_size,4:st_blksize,4:st_blocks,4:st_atime,4:st_atimensec,4:"
83 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:space,4";
84 /* uClibc public ABI 32bit layout:
85 "st_dev,8:space,2:space,2:st_ino,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:"
86 "st_rdev,8:space,2:space,2:st_size,4:st_blksiez,4:st_blocks,4:st_atime,4:"
87 "st_atimensec,4:st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:"
89 static const char cb_linux_stat_map_64
[] =
90 "st_dev,8:space,4:space,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:st_rdev,8:"
91 "space,4:st_size,8:st_blksize,4:st_blocks,8:st_atime,4:st_atimensec,4:"
92 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:st_ino,8";
93 static const char cb_libgloss_stat_map_32
[] =
94 "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
95 "st_size,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:"
96 "space,4:st_blksize,4:st_blocks,4:space,8";
97 static const char *stat_map_32
, *stat_map_64
;
99 /* Simulate a monitor trap, put the result into r0 and errno into r1
100 return offset by which to adjust pc. */
103 bfin_syscall (SIM_CPU
*cpu
)
105 SIM_DESC sd
= CPU_STATE (cpu
);
106 char * const *argv
= (void *)STATE_PROG_ARGV (sd
);
107 host_callback
*cb
= STATE_CALLBACK (sd
);
111 char _tbuf
[1024 * 3], *tbuf
= _tbuf
, tstr
[1024];
114 CB_SYSCALL_INIT (&sc
);
116 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
120 sc
.arg1
= args
[0] = DREG (0);
121 sc
.arg2
= args
[1] = DREG (1);
122 sc
.arg3
= args
[2] = DREG (2);
123 sc
.arg4
= args
[3] = DREG (3);
124 sc
.arg5
= args
[4] = DREG (4);
125 sc
.arg6
= args
[5] = DREG (5);
129 /* libgloss syscall. */
131 sc
.arg1
= args
[0] = GET_LONG (DREG (0));
132 sc
.arg2
= args
[1] = GET_LONG (DREG (0) + 4);
133 sc
.arg3
= args
[2] = GET_LONG (DREG (0) + 8);
134 sc
.arg4
= args
[3] = GET_LONG (DREG (0) + 12);
135 sc
.arg5
= args
[4] = GET_LONG (DREG (0) + 16);
136 sc
.arg6
= args
[5] = GET_LONG (DREG (0) + 20);
140 sc
.read_mem
= sim_syscall_read_mem
;
141 sc
.write_mem
= sim_syscall_write_mem
;
143 /* Common cb_syscall() handles most functions. */
144 switch (cb_target_to_host_syscall (cb
, sc
.func
))
147 tbuf
+= sprintf (tbuf
, "exit(%i)", args
[0]);
148 sim_engine_halt (sd
, cpu
, NULL
, PCREG
, sim_exited
, sc
.arg1
);
150 case CB_SYS_gettimeofday
:
152 struct timeval _tv
, *tv
= &_tv
;
153 struct timezone _tz
, *tz
= &_tz
;
155 tbuf
+= sprintf (tbuf
, "gettimeofday(%#x, %#x)", args
[0], args
[1]);
161 sc
.result
= gettimeofday (tv
, tz
);
170 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
172 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
177 t
= tz
->tz_minuteswest
;
178 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
180 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
189 /* XXX: hack just enough to get basic stdio w/uClibc ... */
190 tbuf
+= sprintf (tbuf
, "ioctl(%i, %#x, %u)", args
[0], args
[1], args
[2]);
191 if (sc
.arg2
== 0x5401)
193 sc
.result
= !isatty (sc
.arg1
);
199 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
205 static bu32 heap
= BFIN_DEFAULT_MEM_SIZE
/ 2;
208 tbuf
+= sprintf (tbuf
, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
209 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
213 if (sc
.arg4
& 0x20 /*MAP_ANONYMOUS*/)
214 /* XXX: We don't handle zeroing, but default is all zeros. */;
215 else if (args
[4] >= MAX_CALLBACK_FDS
)
216 sc
.errcode
= cb_host_to_target_errno (cb
, ENOSYS
);
220 char *data
= xmalloc (sc
.arg2
);
222 /* XXX: Should add a cb->pread. */
223 if (pread (cb
->fdmap
[args
[4]], data
, sc
.arg2
, args
[5] << 12) == sc
.arg2
)
224 sc
.write_mem (cb
, &sc
, heap
, data
, sc
.arg2
);
226 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
230 sc
.errcode
= cb_host_to_target_errno (cb
, ENOSYS
);
242 /* Keep it page aligned. */
243 heap
= align_up (heap
, 4096);
249 /* XXX: meh, just lie for mmap(). */
250 tbuf
+= sprintf (tbuf
, "munmap(%#x, %u)", args
[0], args
[1]);
255 tbuf
+= sprintf (tbuf
, "dup2(%i, %i)", args
[0], args
[1]);
256 if (sc
.arg1
>= MAX_CALLBACK_FDS
|| sc
.arg2
>= MAX_CALLBACK_FDS
)
259 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
263 sc
.result
= dup2 (cb
->fdmap
[sc
.arg1
], cb
->fdmap
[sc
.arg2
]);
269 tbuf
+= sprintf (tbuf
, "llseek(%i, %u, %u, %#x, %u)",
270 args
[0], args
[1], args
[2], args
[3], args
[4]);
271 sc
.func
= TARGET_LINUX_SYS_lseek
;
275 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
281 cb_syscall (cb
, &sc
);
285 sc
.write_mem (cb
, &sc
, args
[3], (void *)&sc
.result
, 4);
286 sc
.write_mem (cb
, &sc
, args
[3] + 4, (void *)&z
, 4);
291 /* XXX: Should add a cb->pread. */
293 tbuf
+= sprintf (tbuf
, "pread(%i, %#x, %u, %i)",
294 args
[0], args
[1], args
[2], args
[3]);
295 if (sc
.arg1
>= MAX_CALLBACK_FDS
)
298 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
302 long old_pos
, read_result
, read_errcode
;
304 /* Get current filepos. */
305 sc
.func
= TARGET_LINUX_SYS_lseek
;
308 cb_syscall (cb
, &sc
);
313 /* Move to the new pos. */
314 sc
.func
= TARGET_LINUX_SYS_lseek
;
317 cb_syscall (cb
, &sc
);
322 sc
.func
= TARGET_LINUX_SYS_read
;
325 cb_syscall (cb
, &sc
);
326 read_result
= sc
.result
;
327 read_errcode
= sc
.errcode
;
329 /* Move back to the old pos. */
330 sc
.func
= TARGET_LINUX_SYS_lseek
;
333 cb_syscall (cb
, &sc
);
335 sc
.result
= read_result
;
336 sc
.errcode
= read_errcode
;
341 tbuf
+= sprintf (tbuf
, "getcwd(%#x, %u)", args
[0], args
[1]);
343 p
= alloca (sc
.arg2
);
344 if (getcwd (p
, sc
.arg2
) == NULL
)
347 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
351 sc
.write_mem (cb
, &sc
, sc
.arg1
, p
, sc
.arg2
);
357 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
358 strcpy (tstr
, "???");
359 tbuf
+= sprintf (tbuf
, "stat64(%#x:\"%s\", %u)", args
[0], tstr
, args
[1]);
360 cb
->stat_map
= stat_map_64
;
361 sc
.func
= TARGET_LINUX_SYS_stat
;
362 cb_syscall (cb
, &sc
);
363 cb
->stat_map
= stat_map_32
;
366 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
367 strcpy (tstr
, "???");
368 tbuf
+= sprintf (tbuf
, "lstat64(%#x:\"%s\", %u)", args
[0], tstr
, args
[1]);
369 cb
->stat_map
= stat_map_64
;
370 sc
.func
= TARGET_LINUX_SYS_lstat
;
371 cb_syscall (cb
, &sc
);
372 cb
->stat_map
= stat_map_32
;
375 tbuf
+= sprintf (tbuf
, "fstat64(%#x, %u)", args
[0], args
[1]);
376 cb
->stat_map
= stat_map_64
;
377 sc
.func
= TARGET_LINUX_SYS_fstat
;
378 cb_syscall (cb
, &sc
);
379 cb
->stat_map
= stat_map_32
;
382 case CB_SYS_ftruncate64
:
383 tbuf
+= sprintf (tbuf
, "ftruncate64(%u, %u)", args
[0], args
[1]);
384 sc
.func
= TARGET_LINUX_SYS_ftruncate
;
385 cb_syscall (cb
, &sc
);
389 case CB_SYS_getuid32
:
390 tbuf
+= sprintf (tbuf
, "getuid()");
391 sc
.result
= getuid ();
394 case CB_SYS_getgid32
:
395 tbuf
+= sprintf (tbuf
, "getgid()");
396 sc
.result
= getgid ();
400 case CB_SYS_setuid32
:
401 tbuf
+= sprintf (tbuf
, "setuid(%u)", args
[0]);
402 sc
.result
= setuid (sc
.arg1
);
406 case CB_SYS_setgid32
:
407 tbuf
+= sprintf (tbuf
, "setgid(%u)", args
[0]);
408 sc
.result
= setgid (sc
.arg1
);
412 tbuf
+= sprintf (tbuf
, "kill(%u, %i)", args
[0], args
[1]);
413 /* Only let the app kill itself. */
414 if (sc
.arg1
!= getpid ())
417 sc
.errcode
= cb_host_to_target_errno (cb
, EPERM
);
422 sc
.result
= kill (sc
.arg1
, sc
.arg2
);
426 sc
.errcode
= cb_host_to_target_errno (cb
, ENOSYS
);
432 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
433 strcpy (tstr
, "???");
434 tbuf
+= sprintf (tbuf
, "open(%#x:\"%s\", %#x, %o)",
435 args
[0], tstr
, args
[1], args
[2]);
438 tbuf
+= sprintf (tbuf
, "close(%i)", args
[0]);
441 tbuf
+= sprintf (tbuf
, "read(%i, %#x, %u)", args
[0], args
[1], args
[2]);
444 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[1]))
445 strcpy (tstr
, "???");
446 tbuf
+= sprintf (tbuf
, "write(%i, %#x:\"%s\", %u)",
447 args
[0], args
[1], tstr
, args
[2]);
450 tbuf
+= sprintf (tbuf
, "lseek(%i, %i, %i)", args
[0], args
[1], args
[2]);
453 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
454 strcpy (tstr
, "???");
455 tbuf
+= sprintf (tbuf
, "unlink(%#x:\"%s\")", args
[0], tstr
);
457 case CB_SYS_truncate
:
458 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
459 strcpy (tstr
, "???");
460 tbuf
+= sprintf (tbuf
, "truncate(%#x:\"%s\", %i)", args
[0], tstr
, args
[1]);
462 case CB_SYS_ftruncate
:
463 tbuf
+= sprintf (tbuf
, "ftruncate(%i, %i)", args
[0], args
[1]);
466 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
467 strcpy (tstr
, "???");
468 tbuf
+= sprintf (tbuf
, "rename(%#x:\"%s\", ", args
[0], tstr
);
469 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[1]))
470 strcpy (tstr
, "???");
471 tbuf
+= sprintf (tbuf
, "%#x:\"%s\")", args
[1], tstr
);
474 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
475 strcpy (tstr
, "???");
476 tbuf
+= sprintf (tbuf
, "stat(%#x:\"%s\", %#x)", args
[0], tstr
, args
[1]);
479 tbuf
+= sprintf (tbuf
, "fstat(%i, %#x)", args
[0], args
[1]);
482 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
483 strcpy (tstr
, "???");
484 tbuf
+= sprintf (tbuf
, "lstat(%#x:\"%s\", %#x)", args
[0], tstr
, args
[1]);
487 tbuf
+= sprintf (tbuf
, "pipe(%#x, %#x)", args
[0], args
[1]);
491 tbuf
+= sprintf (tbuf
, "???_%i(%#x, %#x, %#x, %#x, %#x, %#x)", sc
.func
,
492 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
494 cb_syscall (cb
, &sc
);
500 cb
->last_errno
= errno
;
501 sc
.errcode
= cb
->get_errno (cb
);
505 TRACE_EVENTS (cpu
, "syscall_%i(%#x, %#x, %#x, %#x, %#x, %#x) = %li (error = %i)",
506 sc
.func
, args
[0], args
[1], args
[2], args
[3], args
[4], args
[5],
507 sc
.result
, sc
.errcode
);
509 tbuf
+= sprintf (tbuf
, " = ");
510 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
514 tbuf
+= sprintf (tbuf
, "-1 (error = %i)", sc
.errcode
);
515 if (sc
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
517 sim_io_eprintf (sd
, "bfin-sim: %#x: unimplemented syscall %i\n",
520 SET_DREG (0, -sc
.errcode
);
525 tbuf
+= sprintf (tbuf
, "%#lx", sc
.result
);
527 tbuf
+= sprintf (tbuf
, "%lu", sc
.result
);
528 SET_DREG (0, sc
.result
);
533 tbuf
+= sprintf (tbuf
, "%lu (error = %i)", sc
.result
, sc
.errcode
);
534 SET_DREG (0, sc
.result
);
535 SET_DREG (1, sc
.result2
);
536 SET_DREG (2, sc
.errcode
);
539 TRACE_SYSCALL (cpu
, "%s", _tbuf
);
542 /* Execute a single instruction. */
545 step_once (SIM_CPU
*cpu
)
547 SIM_DESC sd
= CPU_STATE (cpu
);
548 bu32 insn_len
, oldpc
= PCREG
;
552 if (TRACE_ANY_P (cpu
))
553 trace_prefix (sd
, cpu
, NULL_CIA
, oldpc
, TRACE_LINENUM_P (cpu
),
554 NULL
, 0, " "); /* Use a space for gcc warnings. */
556 TRACE_DISASM (cpu
, oldpc
);
558 /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
559 has already had the SSSTEP bit enabled. */
561 if (STATE_ENVIRONMENT (sd
) == OPERATING_ENVIRONMENT
562 && (SYSCFGREG
& SYSCFG_SSSTEP
))
564 int ivg
= cec_get_ivg (cpu
);
565 if (ivg
== -1 || ivg
> 3)
570 /* XXX: Is this what happens on the hardware ? */
571 if (cec_get_ivg (cpu
) == EVT_EMU
)
572 cec_return (cpu
, EVT_EMU
);
575 BFIN_CPU_STATE
.did_jump
= false;
577 insn_len
= interp_insn_bfin (cpu
, oldpc
);
579 /* If we executed this insn successfully, then we always decrement
580 the loop counter. We don't want to update the PC though if the
581 last insn happened to be a change in code flow (jump/etc...). */
582 if (!BFIN_CPU_STATE
.did_jump
)
583 SET_PCREG (hwloop_get_next_pc (cpu
, oldpc
, insn_len
));
584 for (i
= 1; i
>= 0; --i
)
585 if (LCREG (i
) && oldpc
== LBREG (i
))
587 SET_LCREG (i
, LCREG (i
) - 1);
592 ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
));
594 /* Handle hardware single stepping only if we're still lower than EVT3.
595 XXX: May not be entirely correct wrt EXCPT insns. */
598 int ivg
= cec_get_ivg (cpu
);
599 if (ivg
== -1 || ivg
> 3)
602 cec_exception (cpu
, VEC_STEP
);
610 sim_engine_run (SIM_DESC sd
,
611 int next_cpu_nr
, /* ignore */
612 int nr_cpus
, /* ignore */
613 int siggnal
) /* ignore */
618 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
620 cpu
= STATE_CPU (sd
, 0);
625 /* Process any events -- can't use tickn because it may
626 advance right over the next event. */
627 for (ticks
= 0; ticks
< CYCLE_DELAY
; ++ticks
)
628 if (sim_events_tick (sd
))
629 sim_events_process (sd
);
633 /* Cover function of sim_state_free to free the cpu buffers as well. */
636 free_state (SIM_DESC sd
)
638 if (STATE_MODULES (sd
) != NULL
)
639 sim_module_uninstall (sd
);
640 sim_cpu_free_all (sd
);
644 /* Create an instance of the simulator. */
647 bfin_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
649 PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
)) = 0;
651 bfin_model_cpu_init (sd
, cpu
);
653 /* Set default stack to top of scratch pad. */
654 SET_SPREG (BFIN_DEFAULT_MEM_SIZE
);
655 SET_KSPREG (BFIN_DEFAULT_MEM_SIZE
);
656 SET_USPREG (BFIN_DEFAULT_MEM_SIZE
);
658 /* This is what the hardware likes. */
659 SET_SYSCFGREG (0x30);
663 sim_open (SIM_OPEN_KIND kind
, host_callback
*callback
,
664 struct bfd
*abfd
, char * const *argv
)
668 SIM_DESC sd
= sim_state_alloc_extra (kind
, callback
,
669 sizeof (struct bfin_board_data
));
671 /* Set default options before parsing user options. */
672 STATE_MACHS (sd
) = bfin_sim_machs
;
673 STATE_MODEL_NAME (sd
) = "bf537";
674 current_alignment
= STRICT_ALIGNMENT
;
675 current_target_byte_order
= BFD_ENDIAN_LITTLE
;
677 /* The cpu data is kept in a separately allocated chunk of memory. */
678 if (sim_cpu_alloc_all_extra (sd
, 0, sizeof (struct bfin_cpu_state
))
685 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
691 /* XXX: Default to the Virtual environment. */
692 if (STATE_ENVIRONMENT (sd
) == ALL_ENVIRONMENT
)
693 STATE_ENVIRONMENT (sd
) = VIRTUAL_ENVIRONMENT
;
695 /* The parser will print an error message for us, so we silently return. */
696 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
702 /* Allocate external memory if none specified by user.
703 Use address 4 here in case the user wanted address 0 unmapped. */
704 if (sim_core_read_buffer (sd
, NULL
, read_map
, &c
, 4, 1) == 0)
706 bu16 emuexcpt
= 0x25;
707 sim_do_commandf (sd
, "memory-size 0x%x", BFIN_DEFAULT_MEM_SIZE
);
708 sim_write (sd
, 0, &emuexcpt
, 2);
711 /* Check for/establish the a reference program image. */
712 if (sim_analyze_program (sd
, STATE_PROG_FILE (sd
), abfd
) != SIM_RC_OK
)
718 /* Establish any remaining configuration options. */
719 if (sim_config (sd
) != SIM_RC_OK
)
725 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
731 /* CPU specific initialization. */
732 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
734 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
735 bfin_initialize_cpu (sd
, cpu
);
741 /* Some utils don't like having a NULL environ. */
742 static char * const simple_env
[] = { "HOME=/", "PATH=/bin", NULL
};
744 static bu32 fdpic_load_offset
;
747 bfin_fdpic_load (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
, bu32
*sp
,
748 bu32
*elf_addrs
, char **ldso_path
)
753 Elf_Internal_Ehdr
*iehdr
;
754 Elf32_External_Ehdr ehdr
;
755 Elf_Internal_Phdr
*phdrs
;
763 unsigned char null
[4] = { 0, 0, 0, 0 };
768 /* See if this an FDPIC ELF. */
771 goto skip_fdpic_init
;
772 if (bfd_seek (abfd
, 0, SEEK_SET
) != 0)
773 goto skip_fdpic_init
;
774 if (bfd_bread (&ehdr
, sizeof (ehdr
), abfd
) != sizeof (ehdr
))
775 goto skip_fdpic_init
;
776 iehdr
= elf_elfheader (abfd
);
777 if (!(iehdr
->e_flags
& EF_BFIN_FDPIC
))
778 goto skip_fdpic_init
;
780 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
781 sim_io_printf (sd
, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
782 bfd_get_filename (abfd
), fdpic_load_offset
, elf_addrs
[0]);
784 /* Grab the Program Headers to set up the loadsegs on the stack. */
785 phdr_size
= bfd_get_elf_phdr_upper_bound (abfd
);
787 goto skip_fdpic_init
;
788 phdrs
= xmalloc (phdr_size
);
789 phdrc
= bfd_get_elf_phdrs (abfd
, phdrs
);
791 goto skip_fdpic_init
;
793 /* Push the Ehdr onto the stack. */
794 *sp
-= sizeof (ehdr
);
796 sim_write (sd
, *sp
, &ehdr
, sizeof (ehdr
));
797 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
798 sim_io_printf (sd
, " Elf_Ehdr: %#x\n", *sp
);
800 /* Since we're relocating things ourselves, we need to relocate
801 the start address as well. */
802 elf_addrs
[0] = bfd_get_start_address (abfd
) + fdpic_load_offset
;
804 /* And the Exec's Phdrs onto the stack. */
805 if (STATE_PROG_BFD (sd
) == abfd
)
807 elf_addrs
[4] = elf_addrs
[0];
809 phdr_size
= iehdr
->e_phentsize
* iehdr
->e_phnum
;
810 if (bfd_seek (abfd
, iehdr
->e_phoff
, SEEK_SET
) != 0)
811 goto skip_fdpic_init
;
812 data
= xmalloc (phdr_size
);
813 if (bfd_bread (data
, phdr_size
, abfd
) != phdr_size
)
814 goto skip_fdpic_init
;
817 elf_addrs
[2] = phdrc
;
818 sim_write (sd
, *sp
, data
, phdr_size
);
820 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
821 sim_io_printf (sd
, " Elf_Phdrs: %#x\n", *sp
);
824 /* Now push all the loadsegs. */
827 for (i
= phdrc
; i
>= 0; --i
)
828 if (phdrs
[i
].p_type
== PT_LOAD
)
830 Elf_Internal_Phdr
*p
= &phdrs
[i
];
831 bu32 paddr
, vaddr
, memsz
, filesz
;
833 paddr
= p
->p_paddr
+ fdpic_load_offset
;
836 filesz
= p
->p_filesz
;
838 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
839 sim_io_printf (sd
, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
840 i
, vaddr
, paddr
, filesz
, memsz
);
842 data
= xmalloc (memsz
);
844 memset (data
+ filesz
, 0, memsz
- filesz
);
846 if (bfd_seek (abfd
, p
->p_offset
, SEEK_SET
) == 0
847 && bfd_bread (data
, filesz
, abfd
) == filesz
)
848 sim_write (sd
, paddr
, data
, memsz
);
852 max_load_addr
= max (paddr
+ memsz
, max_load_addr
);
855 sim_write (sd
, *sp
+0, &paddr
, 4); /* loadseg.addr */
856 sim_write (sd
, *sp
+4, &vaddr
, 4); /* loadseg.p_vaddr */
857 sim_write (sd
, *sp
+8, &memsz
, 4); /* loadseg.p_memsz */
860 else if (phdrs
[i
].p_type
== PT_DYNAMIC
)
862 elf_addrs
[5] = phdrs
[i
].p_paddr
+ fdpic_load_offset
;
863 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
864 sim_io_printf (sd
, " PT_DYNAMIC: %#x\n", elf_addrs
[5]);
866 else if (phdrs
[i
].p_type
== PT_INTERP
)
868 uint32_t off
= phdrs
[i
].p_offset
;
869 uint32_t len
= phdrs
[i
].p_filesz
;
871 *ldso_path
= xmalloc (len
);
872 if (bfd_seek (abfd
, off
, SEEK_SET
) != 0
873 || bfd_bread (*ldso_path
, len
, abfd
) != len
)
878 else if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
879 sim_io_printf (sd
, " PT_INTERP: %s\n", *ldso_path
);
882 /* Update the load offset with a few extra pages. */
883 fdpic_load_offset
= align_up (max (max_load_addr
, fdpic_load_offset
),
885 fdpic_load_offset
+= 0x10000;
887 /* Push the summary loadmap info onto the stack last. */
889 sim_write (sd
, *sp
+0, null
, 2); /* loadmap.version */
890 sim_write (sd
, *sp
+2, &nsegs
, 2); /* loadmap.nsegs */
900 bfin_user_init (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
,
901 char * const *argv
, char * const *env
)
903 /* XXX: Missing host -> target endian ... */
904 /* Linux starts the user app with the stack:
906 argv[0] -- pointers to the actual strings
912 auxvt[0].type -- ELF Auxiliary Vector Table
917 argv[0..N][0..M] -- actual argv/env strings
919 FDPIC loadmaps -- for FDPIC apps
920 So set things up the same way. */
922 bu32 argv_flat
, env_flat
;
926 /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
929 bu32 exec_loadmap
, ldso_loadmap
;
932 unsigned char null
[4] = { 0, 0, 0, 0 };
934 host_callback
*cb
= STATE_CALLBACK (sd
);
936 elf_addrs
[0] = elf_addrs
[4] = bfd_get_start_address (abfd
);
937 elf_addrs
[1] = elf_addrs
[2] = elf_addrs
[3] = elf_addrs
[5] = 0;
939 /* Keep the load addresses consistent between runs. Also make sure we make
940 space for the fixed code region (part of the Blackfin Linux ABI). */
941 fdpic_load_offset
= 0x1000;
943 /* First try to load this as an FDPIC executable. */
945 if (!bfin_fdpic_load (sd
, cpu
, STATE_PROG_BFD (sd
), &sp
, elf_addrs
, &ldso_path
))
946 goto skip_fdpic_init
;
949 /* If that worked, then load the fixed code region. We only do this for
950 FDPIC ELFs atm because they are PIEs and let us relocate them without
951 manual fixups. FLAT files however require location processing which
952 we do not do ourselves, and they link with a VMA of 0. */
953 sim_write (sd
, 0x400, bfin_linux_fixed_code
, sizeof (bfin_linux_fixed_code
));
955 /* If the FDPIC needs an interpreter, then load it up too. */
958 const char *ldso_full_path
= concat (simulator_sysroot
, ldso_path
, NULL
);
959 struct bfd
*ldso_bfd
;
961 ldso_bfd
= bfd_openr (ldso_full_path
, STATE_TARGET (sd
));
964 sim_io_eprintf (sd
, "bfin-sim: bfd open failed: %s\n", ldso_full_path
);
967 if (!bfd_check_format (ldso_bfd
, bfd_object
))
968 sim_io_eprintf (sd
, "bfin-sim: bfd format not valid: %s\n", ldso_full_path
);
969 bfd_set_arch_info (ldso_bfd
, STATE_ARCHITECTURE (sd
));
971 if (!bfin_fdpic_load (sd
, cpu
, ldso_bfd
, &sp
, elf_addrs
, &ldso_path
))
972 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path
);
974 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
975 ldso_full_path
, ldso_path
);
983 /* Finally setup the registers required by the FDPIC ABI. */
984 SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up. */
985 SET_PREG (0, exec_loadmap
); /* Exec loadmap addr. */
986 SET_PREG (1, ldso_loadmap
); /* Interp loadmap addr. */
987 SET_PREG (2, elf_addrs
[5]); /* PT_DYNAMIC map addr. */
992 sim_pc_set (cpu
, elf_addrs
[0]);
994 /* Figure out how much storage the argv/env strings need. */
995 argc
= countargv ((char **)argv
);
998 argv_flat
= argc
; /* NUL bytes */
999 for (i
= 0; i
< argc
; ++i
)
1000 argv_flat
+= strlen (argv
[i
]);
1004 envc
= countargv ((char **)env
);
1005 env_flat
= envc
; /* NUL bytes */
1006 for (i
= 0; i
< envc
; ++i
)
1007 env_flat
+= strlen (env
[i
]);
1009 /* Push the Auxiliary Vector Table between argv/env and actual strings. */
1010 sp_flat
= sp
= align_up (SPREG
- argv_flat
- env_flat
- 4, 4);
1013 # define AT_PUSH(at, val) \
1017 sim_write (sd, sp, &auxvt, 4); \
1020 sim_write (sd, sp, &auxvt, 4)
1021 unsigned int egid
= getegid (), gid
= getgid ();
1022 unsigned int euid
= geteuid (), uid
= getuid ();
1023 bu32 auxvt_size
= 0;
1024 AT_PUSH (AT_NULL
, 0);
1025 AT_PUSH (AT_SECURE
, egid
!= gid
|| euid
!= uid
);
1026 AT_PUSH (AT_EGID
, egid
);
1027 AT_PUSH (AT_GID
, gid
);
1028 AT_PUSH (AT_EUID
, euid
);
1029 AT_PUSH (AT_UID
, uid
);
1030 AT_PUSH (AT_ENTRY
, elf_addrs
[4]);
1031 AT_PUSH (AT_FLAGS
, 0);
1032 AT_PUSH (AT_BASE
, elf_addrs
[3]);
1033 AT_PUSH (AT_PHNUM
, elf_addrs
[2]);
1034 AT_PUSH (AT_PHENT
, sizeof (Elf32_External_Phdr
));
1035 AT_PUSH (AT_PHDR
, elf_addrs
[1]);
1036 AT_PUSH (AT_CLKTCK
, 100); /* XXX: This ever not 100 ? */
1037 AT_PUSH (AT_PAGESZ
, 4096);
1038 AT_PUSH (AT_HWCAP
, 0);
1043 /* Push the argc/argv/env after the auxvt. */
1044 sp
-= ((1 + argc
+ 1 + envc
+ 1) * 4);
1047 /* First push the argc value. */
1048 sim_write (sd
, sp
, &argc
, 4);
1051 /* Then the actual argv strings so we know where to point argv[]. */
1052 for (i
= 0; i
< argc
; ++i
)
1054 unsigned len
= strlen (argv
[i
]) + 1;
1055 sim_write (sd
, sp_flat
, argv
[i
], len
);
1056 sim_write (sd
, sp
, &sp_flat
, 4);
1060 sim_write (sd
, sp
, null
, 4);
1063 /* Then the actual env strings so we know where to point env[]. */
1064 for (i
= 0; i
< envc
; ++i
)
1066 unsigned len
= strlen (env
[i
]) + 1;
1067 sim_write (sd
, sp_flat
, env
[i
], len
);
1068 sim_write (sd
, sp
, &sp_flat
, 4);
1073 /* Set some callbacks. */
1074 cb
->syscall_map
= cb_linux_syscall_map
;
1075 cb
->errno_map
= cb_linux_errno_map
;
1076 cb
->open_map
= cb_linux_open_map
;
1077 cb
->signal_map
= cb_linux_signal_map
;
1078 cb
->stat_map
= stat_map_32
= cb_linux_stat_map_32
;
1079 stat_map_64
= cb_linux_stat_map_64
;
1083 bfin_os_init (SIM_DESC sd
, SIM_CPU
*cpu
, char * const *argv
)
1085 /* Pass the command line via a string in R0 like Linux expects. */
1088 bu32 cmdline
= BFIN_L1_SRAM_SCRATCH
;
1090 SET_DREG (0, cmdline
);
1091 if (argv
&& argv
[0])
1097 bu32 len
= strlen (argv
[i
]);
1098 sim_write (sd
, cmdline
, argv
[i
], len
);
1100 sim_write (sd
, cmdline
, &byte
, 1);
1106 sim_write (sd
, cmdline
, &byte
, 1);
1110 bfin_virtual_init (SIM_DESC sd
, SIM_CPU
*cpu
)
1112 host_callback
*cb
= STATE_CALLBACK (sd
);
1114 cb
->stat_map
= stat_map_32
= cb_libgloss_stat_map_32
;
1119 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
1120 char * const *argv
, char * const *env
)
1122 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
1123 host_callback
*cb
= STATE_CALLBACK (sd
);
1128 addr
= bfd_get_start_address (abfd
);
1131 sim_pc_set (cpu
, addr
);
1133 /* Standalone mode (i.e. `run`) will take care of the argv for us in
1134 sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim'
1135 with `gdb`), we need to handle it because the user can change the
1136 argv on the fly via gdb's 'run'. */
1137 if (STATE_PROG_ARGV (sd
) != argv
)
1139 freeargv (STATE_PROG_ARGV (sd
));
1140 STATE_PROG_ARGV (sd
) = dupargv (argv
);
1143 if (STATE_PROG_ENVP (sd
) != env
)
1145 freeargv (STATE_PROG_ENVP (sd
));
1146 STATE_PROG_ENVP (sd
) = dupargv (env
);
1149 cb
->argv
= STATE_PROG_ARGV (sd
);
1150 cb
->envp
= STATE_PROG_ENVP (sd
);
1152 switch (STATE_ENVIRONMENT (sd
))
1154 case USER_ENVIRONMENT
:
1155 bfin_user_init (sd
, cpu
, abfd
, argv
, env
);
1157 case OPERATING_ENVIRONMENT
:
1158 bfin_os_init (sd
, cpu
, argv
);
1161 bfin_virtual_init (sd
, cpu
);