/* Simulator for Analog Devices Blackfin processors.
- Copyright (C) 2005-2011 Free Software Foundation, Inc.
+ Copyright (C) 2005-2020 Free Software Foundation, Inc.
Contributed by Analog Devices, Inc.
This file is part of simulators.
#include "gdb/callback.h"
#include "gdb/signals.h"
#include "sim-main.h"
+#include "sim-syscall.h"
#include "sim-hw.h"
#include "targ-vals.h"
-/* The numbers here do not matter. They just need to be unique. */
+/* The numbers here do not matter. They just need to be unique. They also
+ need not be static across releases -- they're used internally only. The
+ mapping from the Linux ABI to the CB values is in linux-targ-map.h. */
#define CB_SYS_ioctl 201
#define CB_SYS_mmap2 202
#define CB_SYS_munmap 203
"space,4:st_blksize,4:st_blocks,4:space,8";
static const char *stat_map_32, *stat_map_64;
-/* Count the number of arguments in an argv. */
-static int
-count_argc (const char * const *argv)
-{
- int i;
-
- if (! argv)
- return -1;
-
- for (i = 0; argv[i] != NULL; ++i)
- continue;
- return i;
-}
-
-/* Read/write functions for system call interface. */
-
-static int
-syscall_read_mem (host_callback *cb, struct cb_syscall *sc,
- unsigned long taddr, char *buf, int bytes)
-{
- SIM_DESC sd = (SIM_DESC) sc->p1;
- SIM_CPU *cpu = (SIM_CPU *) sc->p2;
-
- MAYBE_TRACE (CORE, cpu, "DBUS FETCH (syscall) %i bytes @ 0x%08lx", bytes, taddr);
-
- return sim_core_read_buffer (sd, cpu, read_map, buf, taddr, bytes);
-}
-
-static int
-syscall_write_mem (host_callback *cb, struct cb_syscall *sc,
- unsigned long taddr, const char *buf, int bytes)
-{
- SIM_DESC sd = (SIM_DESC) sc->p1;
- SIM_CPU *cpu = (SIM_CPU *) sc->p2;
-
- MAYBE_TRACE (CORE, cpu, "DBUS STORE (syscall) %i bytes @ 0x%08lx", bytes, taddr);
-
- return sim_core_write_buffer (sd, cpu, write_map, buf, taddr, bytes);
-}
-
/* Simulate a monitor trap, put the result into r0 and errno into r1
return offset by which to adjust pc. */
bfin_syscall (SIM_CPU *cpu)
{
SIM_DESC sd = CPU_STATE (cpu);
- const char * const *argv = (void *)STATE_PROG_ARGV (sd);
+ char * const *argv = (void *)STATE_PROG_ARGV (sd);
host_callback *cb = STATE_CALLBACK (sd);
bu32 args[6];
CB_SYSCALL sc;
}
sc.p1 = (PTR) sd;
sc.p2 = (PTR) cpu;
- sc.read_mem = syscall_read_mem;
- sc.write_mem = syscall_write_mem;
+ sc.read_mem = sim_syscall_read_mem;
+ sc.write_mem = sim_syscall_write_mem;
/* Common cb_syscall() handles most functions. */
switch (cb_target_to_host_syscall (cb, sc.func))
#ifdef CB_SYS_argc
case CB_SYS_argc:
tbuf += sprintf (tbuf, "argc()");
- sc.result = count_argc (argv);
+ sc.result = countargv ((char **)argv);
break;
case CB_SYS_argnlen:
{
tbuf += sprintf (tbuf, "argnlen(%u)", args[0]);
- if (sc.arg1 < count_argc (argv))
+ if (sc.arg1 < countargv ((char **)argv))
sc.result = strlen (argv[sc.arg1]);
else
sc.result = -1;
case CB_SYS_argn:
{
tbuf += sprintf (tbuf, "argn(%u)", args[0]);
- if (sc.arg1 < count_argc (argv))
+ if (sc.arg1 < countargv ((char **)argv))
{
const char *argn = argv[sc.arg1];
int len = strlen (argn);
TRACE_SYSCALL (cpu, "%s", _tbuf);
}
-void
-trace_register (SIM_DESC sd,
- sim_cpu *cpu,
- const char *fmt,
- ...)
-{
- va_list ap;
- trace_printf (sd, cpu, "%s %s",
- "reg: ",
- TRACE_PREFIX (CPU_TRACE_DATA (cpu)));
- va_start (ap, fmt);
- trace_vprintf (sd, cpu, fmt, ap);
- va_end (ap);
- trace_printf (sd, cpu, "\n");
-}
-
/* Execute a single instruction. */
static sim_cia
trace_prefix (sd, cpu, NULL_CIA, oldpc, TRACE_LINENUM_P (cpu),
NULL, 0, " "); /* Use a space for gcc warnings. */
+ TRACE_DISASM (cpu, oldpc);
+
/* Handle hardware single stepping when lower than EVT3, and when SYSCFG
has already had the SSSTEP bit enabled. */
ssstep = false;
SIM_DESC
sim_open (SIM_OPEN_KIND kind, host_callback *callback,
- struct bfd *abfd, char **argv)
+ struct bfd *abfd, char * const *argv)
{
char c;
int i;
e_sim_add_option_table (sd, bfin_mmu_options);
e_sim_add_option_table (sd, bfin_mach_options);
- /* getopt will print the error message so we just have to exit if this fails.
- FIXME: Hmmm... in the case of gdb we need getopt to call
- print_filtered. */
+ /* The parser will print an error message for us, so we silently return. */
if (sim_parse_args (sd, argv) != SIM_RC_OK)
{
free_state (sd);
return sd;
}
-void
-sim_close (SIM_DESC sd, int quitting)
-{
- sim_module_uninstall (sd);
-}
-
/* Some utils don't like having a NULL environ. */
-static const char * const simple_env[] = { "HOME=/", "PATH=/bin", NULL };
+static char * const simple_env[] = { "HOME=/", "PATH=/bin", NULL };
static bu32 fdpic_load_offset;
free (data);
- max_load_addr = MAX (paddr + memsz, max_load_addr);
+ max_load_addr = max (paddr + memsz, max_load_addr);
*sp -= 12;
sim_write (sd, *sp+0, (void *)&paddr, 4); /* loadseg.addr */
}
/* Update the load offset with a few extra pages. */
- fdpic_load_offset = ALIGN (MAX (max_load_addr, fdpic_load_offset), 0x10000);
+ fdpic_load_offset = ALIGN (max (max_load_addr, fdpic_load_offset), 0x10000);
fdpic_load_offset += 0x10000;
/* Push the summary loadmap info onto the stack last. */
static void
bfin_user_init (SIM_DESC sd, SIM_CPU *cpu, struct bfd *abfd,
- const char * const *argv, const char * const *env)
+ char * const *argv, char * const *env)
{
/* XXX: Missing host -> target endian ... */
/* Linux starts the user app with the stack:
/* start, at_phdr, at_phnum, at_base, at_entry, pt_dynamic */
bu32 elf_addrs[6];
- bu32 auxvt, auxvt_size;
+ bu32 auxvt;
bu32 exec_loadmap, ldso_loadmap;
char *ldso_path;
sim_pc_set (cpu, elf_addrs[0]);
/* Figure out how much storage the argv/env strings need. */
- argc = count_argc (argv);
+ argc = countargv ((char **)argv);
if (argc == -1)
argc = 0;
argv_flat = argc; /* NUL bytes */
if (!env)
env = simple_env;
- envc = count_argc (env);
+ envc = countargv ((char **)env);
env_flat = envc; /* NUL bytes */
for (i = 0; i < envc; ++i)
env_flat += strlen (env[i]);
sp -= 4; \
auxvt = (at); \
sim_write (sd, sp, (void *)&auxvt, 4)
- auxvt_size = 0;
unsigned int egid = getegid (), gid = getgid ();
unsigned int euid = geteuid (), uid = getuid ();
+ bu32 auxvt_size = 0;
AT_PUSH (AT_NULL, 0);
AT_PUSH (AT_SECURE, egid != gid || euid != uid);
AT_PUSH (AT_EGID, egid);
}
static void
-bfin_os_init (SIM_DESC sd, SIM_CPU *cpu, const char * const *argv)
+bfin_os_init (SIM_DESC sd, SIM_CPU *cpu, char * const *argv)
{
/* Pass the command line via a string in R0 like Linux expects. */
int i;
SIM_RC
sim_create_inferior (SIM_DESC sd, struct bfd *abfd,
- char **argv, char **env)
+ char * const *argv, char * const *env)
{
SIM_CPU *cpu = STATE_CPU (sd, 0);
SIM_ADDR addr;
addr = 0;
sim_pc_set (cpu, addr);
- /* Standalone mode (i.e. `bfin-...-run`) will take care of the argv
- for us in sim_open() -> sim_parse_args(). But in debug mode (i.e.
- 'target sim' with `bfin-...-gdb`), we need to handle it. */
- if (STATE_OPEN_KIND (sd) == SIM_OPEN_DEBUG)
+ /* Standalone mode (i.e. `run`) will take care of the argv for us in
+ sim_open() -> sim_parse_args(). But in debug mode (i.e. 'target sim'
+ with `gdb`), we need to handle it because the user can change the
+ argv on the fly via gdb's 'run'. */
+ if (STATE_PROG_ARGV (sd) != argv)
{
freeargv (STATE_PROG_ARGV (sd));
STATE_PROG_ARGV (sd) = dupargv (argv);
switch (STATE_ENVIRONMENT (sd))
{
case USER_ENVIRONMENT:
- bfin_user_init (sd, cpu, abfd, (void *)argv, (void *)env);
+ bfin_user_init (sd, cpu, abfd, argv, env);
break;
case OPERATING_ENVIRONMENT:
- bfin_os_init (sd, cpu, (void *)argv);
+ bfin_os_init (sd, cpu, argv);
break;
default:
bfin_virtual_init (sd, cpu);