1 /* Simulator for Analog Devices Blackfin processors.
3 Copyright (C) 2005-2022 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 /* The numbers here do not matter. They just need to be unique. They also
41 need not be static across releases -- they're used internally only. The
42 mapping from the Linux ABI to the CB values is in linux-targ-map.h. */
43 #define CB_SYS_ioctl 201
44 #define CB_SYS_mmap2 202
45 #define CB_SYS_munmap 203
46 #define CB_SYS_dup2 204
47 #define CB_SYS_getuid 205
48 #define CB_SYS_getuid32 206
49 #define CB_SYS_getgid 207
50 #define CB_SYS_getgid32 208
51 #define CB_SYS_setuid 209
52 #define CB_SYS_setuid32 210
53 #define CB_SYS_setgid 211
54 #define CB_SYS_setgid32 212
55 #define CB_SYS_pread 213
56 #define CB_SYS__llseek 214
57 #define CB_SYS_getcwd 215
58 #define CB_SYS_stat64 216
59 #define CB_SYS_lstat64 217
60 #define CB_SYS_fstat64 218
61 #define CB_SYS_ftruncate64 219
62 #define CB_SYS_gettimeofday 220
63 #define CB_SYS_access 221
64 #include "linux-targ-map.h"
65 #include "linux-fixed-code.h"
67 #include "elf/common.h"
68 #include "elf/external.h"
69 #include "elf/internal.h"
73 #include "dv-bfin_cec.h"
74 #include "dv-bfin_mmu.h"
76 static const char cb_linux_stat_map_32
[] =
77 /* Linux kernel 32bit layout: */
78 "st_dev,2:space,2:st_ino,4:st_mode,2:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
79 "space,2:st_size,4:st_blksize,4:st_blocks,4:st_atime,4:st_atimensec,4:"
80 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:space,4";
81 /* uClibc public ABI 32bit layout:
82 "st_dev,8:space,2:space,2:st_ino,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:"
83 "st_rdev,8:space,2:space,2:st_size,4:st_blksiez,4:st_blocks,4:st_atime,4:"
84 "st_atimensec,4:st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:space,4:"
86 static const char cb_linux_stat_map_64
[] =
87 "st_dev,8:space,4:space,4:st_mode,4:st_nlink,4:st_uid,4:st_gid,4:st_rdev,8:"
88 "space,4:st_size,8:st_blksize,4:st_blocks,8:st_atime,4:st_atimensec,4:"
89 "st_mtime,4:st_mtimensec,4:st_ctime,4:st_ctimensec,4:st_ino,8";
90 static const char cb_libgloss_stat_map_32
[] =
91 "st_dev,2:st_ino,2:st_mode,4:st_nlink,2:st_uid,2:st_gid,2:st_rdev,2:"
92 "st_size,4:st_atime,4:space,4:st_mtime,4:space,4:st_ctime,4:"
93 "space,4:st_blksize,4:st_blocks,4:space,8";
94 static const char *stat_map_32
, *stat_map_64
;
96 /* Simulate a monitor trap, put the result into r0 and errno into r1
97 return offset by which to adjust pc. */
100 bfin_syscall (SIM_CPU
*cpu
)
102 SIM_DESC sd
= CPU_STATE (cpu
);
103 char * const *argv
= (void *)STATE_PROG_ARGV (sd
);
104 host_callback
*cb
= STATE_CALLBACK (sd
);
108 char _tbuf
[1024 * 3], *tbuf
= _tbuf
, tstr
[1024];
111 CB_SYSCALL_INIT (&sc
);
113 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
117 sc
.arg1
= args
[0] = DREG (0);
118 sc
.arg2
= args
[1] = DREG (1);
119 sc
.arg3
= args
[2] = DREG (2);
120 sc
.arg4
= args
[3] = DREG (3);
121 sc
.arg5
= args
[4] = DREG (4);
122 sc
.arg6
= args
[5] = DREG (5);
126 /* libgloss syscall. */
128 sc
.arg1
= args
[0] = GET_LONG (DREG (0));
129 sc
.arg2
= args
[1] = GET_LONG (DREG (0) + 4);
130 sc
.arg3
= args
[2] = GET_LONG (DREG (0) + 8);
131 sc
.arg4
= args
[3] = GET_LONG (DREG (0) + 12);
132 sc
.arg5
= args
[4] = GET_LONG (DREG (0) + 16);
133 sc
.arg6
= args
[5] = GET_LONG (DREG (0) + 20);
137 sc
.read_mem
= sim_syscall_read_mem
;
138 sc
.write_mem
= sim_syscall_write_mem
;
140 /* Common cb_syscall() handles most functions. */
141 switch (cb_target_to_host_syscall (cb
, sc
.func
))
144 tbuf
+= sprintf (tbuf
, "exit(%i)", args
[0]);
145 sim_engine_halt (sd
, cpu
, NULL
, PCREG
, sim_exited
, sc
.arg1
);
147 case CB_SYS_gettimeofday
:
149 struct timeval _tv
, *tv
= &_tv
;
150 struct timezone _tz
, *tz
= &_tz
;
152 tbuf
+= sprintf (tbuf
, "gettimeofday(%#x, %#x)", args
[0], args
[1]);
158 sc
.result
= gettimeofday (tv
, tz
);
167 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
169 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
174 t
= tz
->tz_minuteswest
;
175 sc
.write_mem (cb
, &sc
, sc
.arg1
, (void *)&t
, 4);
177 sc
.write_mem (cb
, &sc
, sc
.arg1
+ 4, (void *)&t
, 4);
186 /* XXX: hack just enough to get basic stdio w/uClibc ... */
187 tbuf
+= sprintf (tbuf
, "ioctl(%i, %#x, %u)", args
[0], args
[1], args
[2]);
188 if (sc
.arg2
== 0x5401)
190 sc
.result
= !isatty (sc
.arg1
);
196 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
202 static bu32 heap
= BFIN_DEFAULT_MEM_SIZE
/ 2;
205 tbuf
+= sprintf (tbuf
, "mmap2(%#x, %u, %#x, %#x, %i, %u)",
206 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
210 if (sc
.arg4
& 0x20 /*MAP_ANONYMOUS*/)
211 /* XXX: We don't handle zeroing, but default is all zeros. */;
212 else if (args
[4] >= MAX_CALLBACK_FDS
)
213 sc
.errcode
= cb_host_to_target_errno (cb
, ENOSYS
);
217 char *data
= xmalloc (sc
.arg2
);
219 /* XXX: Should add a cb->pread. */
220 if (pread (cb
->fdmap
[args
[4]], data
, sc
.arg2
, args
[5] << 12) == sc
.arg2
)
221 sc
.write_mem (cb
, &sc
, heap
, data
, sc
.arg2
);
223 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
227 sc
.errcode
= cb_host_to_target_errno (cb
, ENOSYS
);
239 /* Keep it page aligned. */
240 heap
= align_up (heap
, 4096);
246 /* XXX: meh, just lie for mmap(). */
247 tbuf
+= sprintf (tbuf
, "munmap(%#x, %u)", args
[0], args
[1]);
252 tbuf
+= sprintf (tbuf
, "dup2(%i, %i)", args
[0], args
[1]);
253 if (sc
.arg1
>= MAX_CALLBACK_FDS
|| sc
.arg2
>= MAX_CALLBACK_FDS
)
256 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
260 sc
.result
= dup2 (cb
->fdmap
[sc
.arg1
], cb
->fdmap
[sc
.arg2
]);
266 tbuf
+= sprintf (tbuf
, "llseek(%i, %u, %u, %#x, %u)",
267 args
[0], args
[1], args
[2], args
[3], args
[4]);
268 sc
.func
= TARGET_LINUX_SYS_lseek
;
272 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
278 cb_syscall (cb
, &sc
);
282 sc
.write_mem (cb
, &sc
, args
[3], (void *)&sc
.result
, 4);
283 sc
.write_mem (cb
, &sc
, args
[3] + 4, (void *)&z
, 4);
288 /* XXX: Should add a cb->pread. */
290 tbuf
+= sprintf (tbuf
, "pread(%i, %#x, %u, %i)",
291 args
[0], args
[1], args
[2], args
[3]);
292 if (sc
.arg1
>= MAX_CALLBACK_FDS
)
295 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
299 long old_pos
, read_result
, read_errcode
;
301 /* Get current filepos. */
302 sc
.func
= TARGET_LINUX_SYS_lseek
;
305 cb_syscall (cb
, &sc
);
310 /* Move to the new pos. */
311 sc
.func
= TARGET_LINUX_SYS_lseek
;
314 cb_syscall (cb
, &sc
);
319 sc
.func
= TARGET_LINUX_SYS_read
;
322 cb_syscall (cb
, &sc
);
323 read_result
= sc
.result
;
324 read_errcode
= sc
.errcode
;
326 /* Move back to the old pos. */
327 sc
.func
= TARGET_LINUX_SYS_lseek
;
330 cb_syscall (cb
, &sc
);
332 sc
.result
= read_result
;
333 sc
.errcode
= read_errcode
;
338 tbuf
+= sprintf (tbuf
, "getcwd(%#x, %u)", args
[0], args
[1]);
340 p
= alloca (sc
.arg2
);
341 if (getcwd (p
, sc
.arg2
) == NULL
)
344 sc
.errcode
= cb_host_to_target_errno (cb
, EINVAL
);
348 sc
.write_mem (cb
, &sc
, sc
.arg1
, p
, sc
.arg2
);
354 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
355 strcpy (tstr
, "???");
356 tbuf
+= sprintf (tbuf
, "stat64(%#x:\"%s\", %u)", args
[0], tstr
, args
[1]);
357 cb
->stat_map
= stat_map_64
;
358 sc
.func
= TARGET_LINUX_SYS_stat
;
359 cb_syscall (cb
, &sc
);
360 cb
->stat_map
= stat_map_32
;
363 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
364 strcpy (tstr
, "???");
365 tbuf
+= sprintf (tbuf
, "lstat64(%#x:\"%s\", %u)", args
[0], tstr
, args
[1]);
366 cb
->stat_map
= stat_map_64
;
367 sc
.func
= TARGET_LINUX_SYS_lstat
;
368 cb_syscall (cb
, &sc
);
369 cb
->stat_map
= stat_map_32
;
372 tbuf
+= sprintf (tbuf
, "fstat64(%#x, %u)", args
[0], args
[1]);
373 cb
->stat_map
= stat_map_64
;
374 sc
.func
= TARGET_LINUX_SYS_fstat
;
375 cb_syscall (cb
, &sc
);
376 cb
->stat_map
= stat_map_32
;
379 case CB_SYS_ftruncate64
:
380 tbuf
+= sprintf (tbuf
, "ftruncate64(%u, %u)", args
[0], args
[1]);
381 sc
.func
= TARGET_LINUX_SYS_ftruncate
;
382 cb_syscall (cb
, &sc
);
386 case CB_SYS_getuid32
:
387 tbuf
+= sprintf (tbuf
, "getuid()");
388 sc
.result
= getuid ();
391 case CB_SYS_getgid32
:
392 tbuf
+= sprintf (tbuf
, "getgid()");
393 sc
.result
= getgid ();
397 case CB_SYS_setuid32
:
398 tbuf
+= sprintf (tbuf
, "setuid(%u)", args
[0]);
399 sc
.result
= setuid (sc
.arg1
);
403 case CB_SYS_setgid32
:
404 tbuf
+= sprintf (tbuf
, "setgid(%u)", args
[0]);
405 sc
.result
= setgid (sc
.arg1
);
409 tbuf
+= sprintf (tbuf
, "kill(%u, %i)", args
[0], args
[1]);
410 /* Only let the app kill itself. */
411 if (sc
.arg1
!= getpid ())
414 sc
.errcode
= cb_host_to_target_errno (cb
, EPERM
);
419 sc
.result
= kill (sc
.arg1
, sc
.arg2
);
423 sc
.errcode
= cb_host_to_target_errno (cb
, ENOSYS
);
429 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
430 strcpy (tstr
, "???");
431 tbuf
+= sprintf (tbuf
, "open(%#x:\"%s\", %#x, %o)",
432 args
[0], tstr
, args
[1], args
[2]);
435 tbuf
+= sprintf (tbuf
, "close(%i)", args
[0]);
438 tbuf
+= sprintf (tbuf
, "read(%i, %#x, %u)", args
[0], args
[1], args
[2]);
441 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[1]))
442 strcpy (tstr
, "???");
443 tbuf
+= sprintf (tbuf
, "write(%i, %#x:\"%s\", %u)",
444 args
[0], args
[1], tstr
, args
[2]);
447 tbuf
+= sprintf (tbuf
, "lseek(%i, %i, %i)", args
[0], args
[1], args
[2]);
450 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
451 strcpy (tstr
, "???");
452 tbuf
+= sprintf (tbuf
, "unlink(%#x:\"%s\")", args
[0], tstr
);
454 case CB_SYS_truncate
:
455 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
456 strcpy (tstr
, "???");
457 tbuf
+= sprintf (tbuf
, "truncate(%#x:\"%s\", %i)", args
[0], tstr
, args
[1]);
459 case CB_SYS_ftruncate
:
460 tbuf
+= sprintf (tbuf
, "ftruncate(%i, %i)", args
[0], args
[1]);
463 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
464 strcpy (tstr
, "???");
465 tbuf
+= sprintf (tbuf
, "rename(%#x:\"%s\", ", args
[0], tstr
);
466 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[1]))
467 strcpy (tstr
, "???");
468 tbuf
+= sprintf (tbuf
, "%#x:\"%s\")", args
[1], tstr
);
471 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
472 strcpy (tstr
, "???");
473 tbuf
+= sprintf (tbuf
, "stat(%#x:\"%s\", %#x)", args
[0], tstr
, args
[1]);
476 tbuf
+= sprintf (tbuf
, "fstat(%i, %#x)", args
[0], args
[1]);
479 if (cb_get_string (cb
, &sc
, tstr
, sizeof (tstr
), args
[0]))
480 strcpy (tstr
, "???");
481 tbuf
+= sprintf (tbuf
, "lstat(%#x:\"%s\", %#x)", args
[0], tstr
, args
[1]);
484 tbuf
+= sprintf (tbuf
, "pipe(%#x, %#x)", args
[0], args
[1]);
488 tbuf
+= sprintf (tbuf
, "???_%i(%#x, %#x, %#x, %#x, %#x, %#x)", sc
.func
,
489 args
[0], args
[1], args
[2], args
[3], args
[4], args
[5]);
491 cb_syscall (cb
, &sc
);
497 cb
->last_errno
= errno
;
498 sc
.errcode
= cb
->get_errno (cb
);
502 TRACE_EVENTS (cpu
, "syscall_%i(%#x, %#x, %#x, %#x, %#x, %#x) = %li (error = %i)",
503 sc
.func
, args
[0], args
[1], args
[2], args
[3], args
[4], args
[5],
504 sc
.result
, sc
.errcode
);
506 tbuf
+= sprintf (tbuf
, " = ");
507 if (STATE_ENVIRONMENT (sd
) == USER_ENVIRONMENT
)
511 tbuf
+= sprintf (tbuf
, "-1 (error = %i)", sc
.errcode
);
512 if (sc
.errcode
== cb_host_to_target_errno (cb
, ENOSYS
))
514 sim_io_eprintf (sd
, "bfin-sim: %#x: unimplemented syscall %i\n",
517 SET_DREG (0, -sc
.errcode
);
522 tbuf
+= sprintf (tbuf
, "%#lx", sc
.result
);
524 tbuf
+= sprintf (tbuf
, "%lu", sc
.result
);
525 SET_DREG (0, sc
.result
);
530 tbuf
+= sprintf (tbuf
, "%lu (error = %i)", sc
.result
, sc
.errcode
);
531 SET_DREG (0, sc
.result
);
532 SET_DREG (1, sc
.result2
);
533 SET_DREG (2, sc
.errcode
);
536 TRACE_SYSCALL (cpu
, "%s", _tbuf
);
539 /* Execute a single instruction. */
542 step_once (SIM_CPU
*cpu
)
544 SIM_DESC sd
= CPU_STATE (cpu
);
545 bu32 insn_len
, oldpc
= PCREG
;
549 if (TRACE_ANY_P (cpu
))
550 trace_prefix (sd
, cpu
, NULL_CIA
, oldpc
, TRACE_LINENUM_P (cpu
),
551 NULL
, 0, " "); /* Use a space for gcc warnings. */
553 TRACE_DISASM (cpu
, oldpc
);
555 /* Handle hardware single stepping when lower than EVT3, and when SYSCFG
556 has already had the SSSTEP bit enabled. */
558 if (STATE_ENVIRONMENT (sd
) == OPERATING_ENVIRONMENT
559 && (SYSCFGREG
& SYSCFG_SSSTEP
))
561 int ivg
= cec_get_ivg (cpu
);
562 if (ivg
== -1 || ivg
> 3)
567 /* XXX: Is this what happens on the hardware ? */
568 if (cec_get_ivg (cpu
) == EVT_EMU
)
569 cec_return (cpu
, EVT_EMU
);
572 BFIN_CPU_STATE
.did_jump
= false;
574 insn_len
= interp_insn_bfin (cpu
, oldpc
);
576 /* If we executed this insn successfully, then we always decrement
577 the loop counter. We don't want to update the PC though if the
578 last insn happened to be a change in code flow (jump/etc...). */
579 if (!BFIN_CPU_STATE
.did_jump
)
580 SET_PCREG (hwloop_get_next_pc (cpu
, oldpc
, insn_len
));
581 for (i
= 1; i
>= 0; --i
)
582 if (LCREG (i
) && oldpc
== LBREG (i
))
584 SET_LCREG (i
, LCREG (i
) - 1);
589 ++ PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
));
591 /* Handle hardware single stepping only if we're still lower than EVT3.
592 XXX: May not be entirely correct wrt EXCPT insns. */
595 int ivg
= cec_get_ivg (cpu
);
596 if (ivg
== -1 || ivg
> 3)
599 cec_exception (cpu
, VEC_STEP
);
607 sim_engine_run (SIM_DESC sd
,
608 int next_cpu_nr
, /* ignore */
609 int nr_cpus
, /* ignore */
610 int siggnal
) /* ignore */
615 SIM_ASSERT (STATE_MAGIC (sd
) == SIM_MAGIC_NUMBER
);
617 cpu
= STATE_CPU (sd
, 0);
622 /* Process any events -- can't use tickn because it may
623 advance right over the next event. */
624 for (ticks
= 0; ticks
< CYCLE_DELAY
; ++ticks
)
625 if (sim_events_tick (sd
))
626 sim_events_process (sd
);
630 /* Cover function of sim_state_free to free the cpu buffers as well. */
633 free_state (SIM_DESC sd
)
635 if (STATE_MODULES (sd
) != NULL
)
636 sim_module_uninstall (sd
);
637 sim_cpu_free_all (sd
);
641 /* Create an instance of the simulator. */
644 bfin_initialize_cpu (SIM_DESC sd
, SIM_CPU
*cpu
)
646 memset (&cpu
->state
, 0, sizeof (cpu
->state
));
648 PROFILE_TOTAL_INSN_COUNT (CPU_PROFILE_DATA (cpu
)) = 0;
650 bfin_model_cpu_init (sd
, cpu
);
652 /* Set default stack to top of scratch pad. */
653 SET_SPREG (BFIN_DEFAULT_MEM_SIZE
);
654 SET_KSPREG (BFIN_DEFAULT_MEM_SIZE
);
655 SET_USPREG (BFIN_DEFAULT_MEM_SIZE
);
657 /* This is what the hardware likes. */
658 SET_SYSCFGREG (0x30);
662 sim_open (SIM_OPEN_KIND kind
, host_callback
*callback
,
663 struct bfd
*abfd
, char * const *argv
)
667 SIM_DESC sd
= sim_state_alloc_extra (kind
, callback
,
668 sizeof (struct bfin_board_data
));
670 /* Set default options before parsing user options. */
671 STATE_MACHS (sd
) = bfin_sim_machs
;
672 STATE_MODEL_NAME (sd
) = "bf537";
673 current_alignment
= STRICT_ALIGNMENT
;
674 current_target_byte_order
= BFD_ENDIAN_LITTLE
;
676 /* The cpu data is kept in a separately allocated chunk of memory. */
677 if (sim_cpu_alloc_all (sd
, 1) != SIM_RC_OK
)
683 if (sim_pre_argv_init (sd
, argv
[0]) != SIM_RC_OK
)
689 /* XXX: Default to the Virtual environment. */
690 if (STATE_ENVIRONMENT (sd
) == ALL_ENVIRONMENT
)
691 STATE_ENVIRONMENT (sd
) = VIRTUAL_ENVIRONMENT
;
693 /* The parser will print an error message for us, so we silently return. */
694 if (sim_parse_args (sd
, argv
) != SIM_RC_OK
)
700 /* Allocate external memory if none specified by user.
701 Use address 4 here in case the user wanted address 0 unmapped. */
702 if (sim_core_read_buffer (sd
, NULL
, read_map
, &c
, 4, 1) == 0)
704 bu16 emuexcpt
= 0x25;
705 sim_do_commandf (sd
, "memory-size 0x%x", BFIN_DEFAULT_MEM_SIZE
);
706 sim_write (sd
, 0, (void *)&emuexcpt
, 2);
709 /* Check for/establish the a reference program image. */
710 if (sim_analyze_program (sd
, STATE_PROG_FILE (sd
), abfd
) != SIM_RC_OK
)
716 /* Establish any remaining configuration options. */
717 if (sim_config (sd
) != SIM_RC_OK
)
723 if (sim_post_argv_init (sd
) != SIM_RC_OK
)
729 /* CPU specific initialization. */
730 for (i
= 0; i
< MAX_NR_PROCESSORS
; ++i
)
732 SIM_CPU
*cpu
= STATE_CPU (sd
, i
);
733 bfin_initialize_cpu (sd
, cpu
);
739 /* Some utils don't like having a NULL environ. */
740 static char * const simple_env
[] = { "HOME=/", "PATH=/bin", NULL
};
742 static bu32 fdpic_load_offset
;
745 bfin_fdpic_load (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
, bu32
*sp
,
746 bu32
*elf_addrs
, char **ldso_path
)
751 Elf_Internal_Ehdr
*iehdr
;
752 Elf32_External_Ehdr ehdr
;
753 Elf_Internal_Phdr
*phdrs
;
761 unsigned char null
[4] = { 0, 0, 0, 0 };
766 /* See if this an FDPIC ELF. */
769 goto skip_fdpic_init
;
770 if (bfd_seek (abfd
, 0, SEEK_SET
) != 0)
771 goto skip_fdpic_init
;
772 if (bfd_bread (&ehdr
, sizeof (ehdr
), abfd
) != sizeof (ehdr
))
773 goto skip_fdpic_init
;
774 iehdr
= elf_elfheader (abfd
);
775 if (!(iehdr
->e_flags
& EF_BFIN_FDPIC
))
776 goto skip_fdpic_init
;
778 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
779 sim_io_printf (sd
, "Loading FDPIC ELF %s\n Load base: %#x\n ELF entry: %#x\n",
780 bfd_get_filename (abfd
), fdpic_load_offset
, elf_addrs
[0]);
782 /* Grab the Program Headers to set up the loadsegs on the stack. */
783 phdr_size
= bfd_get_elf_phdr_upper_bound (abfd
);
785 goto skip_fdpic_init
;
786 phdrs
= xmalloc (phdr_size
);
787 phdrc
= bfd_get_elf_phdrs (abfd
, phdrs
);
789 goto skip_fdpic_init
;
791 /* Push the Ehdr onto the stack. */
792 *sp
-= sizeof (ehdr
);
794 sim_write (sd
, *sp
, (void *)&ehdr
, sizeof (ehdr
));
795 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
796 sim_io_printf (sd
, " Elf_Ehdr: %#x\n", *sp
);
798 /* Since we're relocating things ourselves, we need to relocate
799 the start address as well. */
800 elf_addrs
[0] = bfd_get_start_address (abfd
) + fdpic_load_offset
;
802 /* And the Exec's Phdrs onto the stack. */
803 if (STATE_PROG_BFD (sd
) == abfd
)
805 elf_addrs
[4] = elf_addrs
[0];
807 phdr_size
= iehdr
->e_phentsize
* iehdr
->e_phnum
;
808 if (bfd_seek (abfd
, iehdr
->e_phoff
, SEEK_SET
) != 0)
809 goto skip_fdpic_init
;
810 data
= xmalloc (phdr_size
);
811 if (bfd_bread (data
, phdr_size
, abfd
) != phdr_size
)
812 goto skip_fdpic_init
;
815 elf_addrs
[2] = phdrc
;
816 sim_write (sd
, *sp
, data
, phdr_size
);
818 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
819 sim_io_printf (sd
, " Elf_Phdrs: %#x\n", *sp
);
822 /* Now push all the loadsegs. */
825 for (i
= phdrc
; i
>= 0; --i
)
826 if (phdrs
[i
].p_type
== PT_LOAD
)
828 Elf_Internal_Phdr
*p
= &phdrs
[i
];
829 bu32 paddr
, vaddr
, memsz
, filesz
;
831 paddr
= p
->p_paddr
+ fdpic_load_offset
;
834 filesz
= p
->p_filesz
;
836 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
837 sim_io_printf (sd
, " PHDR %i: vma %#x lma %#x filesz %#x memsz %#x\n",
838 i
, vaddr
, paddr
, filesz
, memsz
);
840 data
= xmalloc (memsz
);
842 memset (data
+ filesz
, 0, memsz
- filesz
);
844 if (bfd_seek (abfd
, p
->p_offset
, SEEK_SET
) == 0
845 && bfd_bread (data
, filesz
, abfd
) == filesz
)
846 sim_write (sd
, paddr
, data
, memsz
);
850 max_load_addr
= max (paddr
+ memsz
, max_load_addr
);
853 sim_write (sd
, *sp
+0, (void *)&paddr
, 4); /* loadseg.addr */
854 sim_write (sd
, *sp
+4, (void *)&vaddr
, 4); /* loadseg.p_vaddr */
855 sim_write (sd
, *sp
+8, (void *)&memsz
, 4); /* loadseg.p_memsz */
858 else if (phdrs
[i
].p_type
== PT_DYNAMIC
)
860 elf_addrs
[5] = phdrs
[i
].p_paddr
+ fdpic_load_offset
;
861 if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
862 sim_io_printf (sd
, " PT_DYNAMIC: %#x\n", elf_addrs
[5]);
864 else if (phdrs
[i
].p_type
== PT_INTERP
)
866 uint32_t off
= phdrs
[i
].p_offset
;
867 uint32_t len
= phdrs
[i
].p_filesz
;
869 *ldso_path
= xmalloc (len
);
870 if (bfd_seek (abfd
, off
, SEEK_SET
) != 0
871 || bfd_bread (*ldso_path
, len
, abfd
) != len
)
876 else if (STATE_OPEN_KIND (sd
) == SIM_OPEN_DEBUG
)
877 sim_io_printf (sd
, " PT_INTERP: %s\n", *ldso_path
);
880 /* Update the load offset with a few extra pages. */
881 fdpic_load_offset
= align_up (max (max_load_addr
, fdpic_load_offset
),
883 fdpic_load_offset
+= 0x10000;
885 /* Push the summary loadmap info onto the stack last. */
887 sim_write (sd
, *sp
+0, null
, 2); /* loadmap.version */
888 sim_write (sd
, *sp
+2, (void *)&nsegs
, 2); /* loadmap.nsegs */
898 bfin_user_init (SIM_DESC sd
, SIM_CPU
*cpu
, struct bfd
*abfd
,
899 char * const *argv
, char * const *env
)
901 /* XXX: Missing host -> target endian ... */
902 /* Linux starts the user app with the stack:
904 argv[0] -- pointers to the actual strings
910 auxvt[0].type -- ELF Auxiliary Vector Table
915 argv[0..N][0..M] -- actual argv/env strings
917 FDPIC loadmaps -- for FDPIC apps
918 So set things up the same way. */
920 bu32 argv_flat
, env_flat
;
924 /* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
927 bu32 exec_loadmap
, ldso_loadmap
;
930 unsigned char null
[4] = { 0, 0, 0, 0 };
932 host_callback
*cb
= STATE_CALLBACK (sd
);
934 elf_addrs
[0] = elf_addrs
[4] = bfd_get_start_address (abfd
);
935 elf_addrs
[1] = elf_addrs
[2] = elf_addrs
[3] = elf_addrs
[5] = 0;
937 /* Keep the load addresses consistent between runs. Also make sure we make
938 space for the fixed code region (part of the Blackfin Linux ABI). */
939 fdpic_load_offset
= 0x1000;
941 /* First try to load this as an FDPIC executable. */
943 if (!bfin_fdpic_load (sd
, cpu
, STATE_PROG_BFD (sd
), &sp
, elf_addrs
, &ldso_path
))
944 goto skip_fdpic_init
;
947 /* If that worked, then load the fixed code region. We only do this for
948 FDPIC ELFs atm because they are PIEs and let us relocate them without
949 manual fixups. FLAT files however require location processing which
950 we do not do ourselves, and they link with a VMA of 0. */
951 sim_write (sd
, 0x400, bfin_linux_fixed_code
, sizeof (bfin_linux_fixed_code
));
953 /* If the FDPIC needs an interpreter, then load it up too. */
956 const char *ldso_full_path
= concat (simulator_sysroot
, ldso_path
, NULL
);
957 struct bfd
*ldso_bfd
;
959 ldso_bfd
= bfd_openr (ldso_full_path
, STATE_TARGET (sd
));
962 sim_io_eprintf (sd
, "bfin-sim: bfd open failed: %s\n", ldso_full_path
);
965 if (!bfd_check_format (ldso_bfd
, bfd_object
))
966 sim_io_eprintf (sd
, "bfin-sim: bfd format not valid: %s\n", ldso_full_path
);
967 bfd_set_arch_info (ldso_bfd
, STATE_ARCHITECTURE (sd
));
969 if (!bfin_fdpic_load (sd
, cpu
, ldso_bfd
, &sp
, elf_addrs
, &ldso_path
))
970 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso failed to load: %s\n", ldso_full_path
);
972 sim_io_eprintf (sd
, "bfin-sim: FDPIC ldso (%s) needs an interpreter (%s) !?\n",
973 ldso_full_path
, ldso_path
);
981 /* Finally setup the registers required by the FDPIC ABI. */
982 SET_DREG (7, 0); /* Zero out FINI funcptr -- ldso will set this up. */
983 SET_PREG (0, exec_loadmap
); /* Exec loadmap addr. */
984 SET_PREG (1, ldso_loadmap
); /* Interp loadmap addr. */
985 SET_PREG (2, elf_addrs
[5]); /* PT_DYNAMIC map addr. */
990 sim_pc_set (cpu
, elf_addrs
[0]);
992 /* Figure out how much storage the argv/env strings need. */
993 argc
= countargv ((char **)argv
);
996 argv_flat
= argc
; /* NUL bytes */
997 for (i
= 0; i
< argc
; ++i
)
998 argv_flat
+= strlen (argv
[i
]);
1002 envc
= countargv ((char **)env
);
1003 env_flat
= envc
; /* NUL bytes */
1004 for (i
= 0; i
< envc
; ++i
)
1005 env_flat
+= strlen (env
[i
]);
1007 /* Push the Auxiliary Vector Table between argv/env and actual strings. */
1008 sp_flat
= sp
= align_up (SPREG
- argv_flat
- env_flat
- 4, 4);
1011 # define AT_PUSH(at, val) \
1015 sim_write (sd, sp, (void *)&auxvt, 4); \
1018 sim_write (sd, sp, (void *)&auxvt, 4)
1019 unsigned int egid
= getegid (), gid
= getgid ();
1020 unsigned int euid
= geteuid (), uid
= getuid ();
1021 bu32 auxvt_size
= 0;
1022 AT_PUSH (AT_NULL
, 0);
1023 AT_PUSH (AT_SECURE
, egid
!= gid
|| euid
!= uid
);
1024 AT_PUSH (AT_EGID
, egid
);
1025 AT_PUSH (AT_GID
, gid
);
1026 AT_PUSH (AT_EUID
, euid
);
1027 AT_PUSH (AT_UID
, uid
);
1028 AT_PUSH (AT_ENTRY
, elf_addrs
[4]);
1029 AT_PUSH (AT_FLAGS
, 0);
1030 AT_PUSH (AT_BASE
, elf_addrs
[3]);
1031 AT_PUSH (AT_PHNUM
, elf_addrs
[2]);
1032 AT_PUSH (AT_PHENT
, sizeof (Elf32_External_Phdr
));
1033 AT_PUSH (AT_PHDR
, elf_addrs
[1]);
1034 AT_PUSH (AT_CLKTCK
, 100); /* XXX: This ever not 100 ? */
1035 AT_PUSH (AT_PAGESZ
, 4096);
1036 AT_PUSH (AT_HWCAP
, 0);
1041 /* Push the argc/argv/env after the auxvt. */
1042 sp
-= ((1 + argc
+ 1 + envc
+ 1) * 4);
1045 /* First push the argc value. */
1046 sim_write (sd
, sp
, (void *)&argc
, 4);
1049 /* Then the actual argv strings so we know where to point argv[]. */
1050 for (i
= 0; i
< argc
; ++i
)
1052 unsigned len
= strlen (argv
[i
]) + 1;
1053 sim_write (sd
, sp_flat
, (void *)argv
[i
], len
);
1054 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1058 sim_write (sd
, sp
, null
, 4);
1061 /* Then the actual env strings so we know where to point env[]. */
1062 for (i
= 0; i
< envc
; ++i
)
1064 unsigned len
= strlen (env
[i
]) + 1;
1065 sim_write (sd
, sp_flat
, (void *)env
[i
], len
);
1066 sim_write (sd
, sp
, (void *)&sp_flat
, 4);
1071 /* Set some callbacks. */
1072 cb
->syscall_map
= cb_linux_syscall_map
;
1073 cb
->errno_map
= cb_linux_errno_map
;
1074 cb
->open_map
= cb_linux_open_map
;
1075 cb
->signal_map
= cb_linux_signal_map
;
1076 cb
->stat_map
= stat_map_32
= cb_linux_stat_map_32
;
1077 stat_map_64
= cb_linux_stat_map_64
;
1081 bfin_os_init (SIM_DESC sd
, SIM_CPU
*cpu
, char * const *argv
)
1083 /* Pass the command line via a string in R0 like Linux expects. */
1086 bu32 cmdline
= BFIN_L1_SRAM_SCRATCH
;
1088 SET_DREG (0, cmdline
);
1089 if (argv
&& argv
[0])
1095 bu32 len
= strlen (argv
[i
]);
1096 sim_write (sd
, cmdline
, (void *)argv
[i
], len
);
1098 sim_write (sd
, cmdline
, &byte
, 1);
1104 sim_write (sd
, cmdline
, &byte
, 1);
1108 bfin_virtual_init (SIM_DESC sd
, SIM_CPU
*cpu
)
1110 host_callback
*cb
= STATE_CALLBACK (sd
);
1112 cb
->stat_map
= stat_map_32
= cb_libgloss_stat_map_32
;
1117 sim_create_inferior (SIM_DESC sd
, struct bfd
*abfd
,
1118 char * const *argv
, char * const *env
)
1120 SIM_CPU
*cpu
= STATE_CPU (sd
, 0);
1121 host_callback
*cb
= STATE_CALLBACK (sd
);
1126 addr
= bfd_get_start_address (abfd
);
1129 sim_pc_set (cpu
, addr
);
1131 /* Standalone mode (i.e. `run`) will take care of the argv for us in
1132 sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim'
1133 with `gdb`), we need to handle it because the user can change the
1134 argv on the fly via gdb's 'run'. */
1135 if (STATE_PROG_ARGV (sd
) != argv
)
1137 freeargv (STATE_PROG_ARGV (sd
));
1138 STATE_PROG_ARGV (sd
) = dupargv (argv
);
1141 if (STATE_PROG_ENVP (sd
) != env
)
1143 freeargv (STATE_PROG_ENVP (sd
));
1144 STATE_PROG_ENVP (sd
) = dupargv (env
);
1147 cb
->argv
= STATE_PROG_ARGV (sd
);
1148 cb
->envp
= STATE_PROG_ENVP (sd
);
1150 switch (STATE_ENVIRONMENT (sd
))
1152 case USER_ENVIRONMENT
:
1153 bfin_user_init (sd
, cpu
, abfd
, argv
, env
);
1155 case OPERATING_ENVIRONMENT
:
1156 bfin_os_init (sd
, cpu
, argv
);
1159 bfin_virtual_init (sd
, cpu
);