mirror of
https://github.com/bminor/binutils-gdb.git
synced 2025-12-26 01:07:52 +00:00
Replace memory model with one from sim/common directory.
This commit is contained in:
@@ -1,3 +1,43 @@
|
||||
Thu Sep 4 18:11:37 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* simops.c (fetch_argv): New function, fetch a arg vector from
|
||||
simulator memory.
|
||||
|
||||
* configure.in: Check for fork, execve, execv.
|
||||
* configure: Regenerate.
|
||||
|
||||
* interp.c (sim_store_register, sim_fetch_register): Use H2T_4 and
|
||||
T2H_4 for byte swapping.
|
||||
|
||||
* sim-main.h, interp.c (get_word, get_half, get_byte, put_word,
|
||||
put_half, put_byte): Delete.
|
||||
|
||||
* Makefile.in (SIM_OBJS): Add sim-memopt.o module.
|
||||
|
||||
* sim-main.h (load_mem, store_mem): Redefine as macros.
|
||||
(IMEM, IMEM_IMMED): New macros - fetch instructions.
|
||||
|
||||
* simops.c (OP_10007E0): For SYS_read, SYS_write, SYS_open
|
||||
transfer data via a buffer.
|
||||
(fetch_str): New function, fetch string from memory.
|
||||
|
||||
* Makefile.in (SIM_OBJS): Add sim-hrw.o module.
|
||||
|
||||
* interp.c (sim_open): Establish memory maps using sim-memopt.c
|
||||
via sim_do_command.
|
||||
(sim_do_command): Print error if memory-map command is used. Call
|
||||
sim_args_command.
|
||||
(map): Delete, replaced by sim-core.
|
||||
(sim_memory_init): Delete, replaced by sim-core.
|
||||
(sim_set_memory_map): Delete, replaced by sim-memopt.
|
||||
(load_mem): Delete, replaced by sim-core.
|
||||
(store_mem): Delete, replaced by sim-core.
|
||||
(sim_write): Delete, replaced by sim-hrw.
|
||||
(sim_read): Delete, replaced by sim-hrw.
|
||||
|
||||
* sim-main.h (struct sim_state): Remove memory members, using
|
||||
sim-core.c
|
||||
|
||||
Wed Sep 3 10:18:55 1997 Andrew Cagney <cagney@b1.cygnus.com>
|
||||
|
||||
* sim-main.h: Replace SIM_HAVE_FLATMEM with mem ptr.
|
||||
|
||||
@@ -25,8 +25,10 @@ SIM_OBJS = interp.o table.o simops.o \
|
||||
sim-endian.o \
|
||||
sim-events.o \
|
||||
sim-hload.o \
|
||||
sim-hrw.o \
|
||||
sim-io.o \
|
||||
sim-load.o \
|
||||
sim-memopt.o \
|
||||
sim-module.o \
|
||||
sim-options.o \
|
||||
sim-profile.o \
|
||||
|
||||
18
sim/v850/configure
vendored
18
sim/v850/configure
vendored
@@ -1460,7 +1460,7 @@ fi
|
||||
|
||||
|
||||
|
||||
for ac_func in time
|
||||
for ac_func in time chmod utime fork execve execv chown
|
||||
do
|
||||
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
|
||||
echo "configure:1467: checking for $ac_func" >&5
|
||||
@@ -1509,10 +1509,9 @@ if eval "test \"`echo '$ac_cv_func_'$ac_func`\" = yes"; then
|
||||
cat >> confdefs.h <<EOF
|
||||
#define $ac_tr_func 1
|
||||
EOF
|
||||
chmod
|
||||
|
||||
else
|
||||
echo "$ac_t""no" 1>&6
|
||||
utime
|
||||
fi
|
||||
done
|
||||
|
||||
@@ -1520,17 +1519,17 @@ for ac_hdr in unistd.h stdlib.h string.h strings.h utime.h time.h
|
||||
do
|
||||
ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'`
|
||||
echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6
|
||||
echo "configure:1524: checking for $ac_hdr" >&5
|
||||
echo "configure:1523: checking for $ac_hdr" >&5
|
||||
if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then
|
||||
echo $ac_n "(cached) $ac_c" 1>&6
|
||||
else
|
||||
cat > conftest.$ac_ext <<EOF
|
||||
#line 1529 "configure"
|
||||
#line 1528 "configure"
|
||||
#include "confdefs.h"
|
||||
#include <$ac_hdr>
|
||||
EOF
|
||||
ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out"
|
||||
{ (eval echo configure:1534: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
{ (eval echo configure:1533: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }
|
||||
ac_err=`grep -v '^ *+' conftest.out`
|
||||
if test -z "$ac_err"; then
|
||||
rm -rf conftest*
|
||||
@@ -1660,7 +1659,7 @@ done
|
||||
ac_given_srcdir=$srcdir
|
||||
ac_given_INSTALL="$INSTALL"
|
||||
|
||||
trap 'rm -fr `echo "Makefile.sim:Makefile.in Make-common.sim:../common/Make-common.in config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
|
||||
trap 'rm -fr `echo "Makefile.sim:Makefile.in Make-common.sim:../common/Make-common.in .gdbinit:../common/gdbinit.in config.h:config.in" | sed "s/:[^ ]*//g"` conftest*; exit 1' 1 2 15
|
||||
EOF
|
||||
cat >> $CONFIG_STATUS <<EOF
|
||||
|
||||
@@ -1763,7 +1762,7 @@ EOF
|
||||
|
||||
cat >> $CONFIG_STATUS <<EOF
|
||||
|
||||
CONFIG_FILES=\${CONFIG_FILES-"Makefile.sim:Makefile.in Make-common.sim:../common/Make-common.in"}
|
||||
CONFIG_FILES=\${CONFIG_FILES-"Makefile.sim:Makefile.in Make-common.sim:../common/Make-common.in .gdbinit:../common/gdbinit.in"}
|
||||
EOF
|
||||
cat >> $CONFIG_STATUS <<\EOF
|
||||
for ac_file in .. $CONFIG_FILES; do if test "x$ac_file" != x..; then
|
||||
@@ -1979,7 +1978,8 @@ cat >> $CONFIG_STATUS <<EOF
|
||||
|
||||
EOF
|
||||
cat >> $CONFIG_STATUS <<\EOF
|
||||
case "x$CONFIG_FILES" in xMakefile*)
|
||||
case "x$CONFIG_FILES" in
|
||||
xMakefile*)
|
||||
echo "Merging Makefile.sim+Make-common.sim into Makefile ..."
|
||||
rm -f Makesim1.tmp Makesim2.tmp Makefile
|
||||
sed -n -e '/^## COMMON_PRE_/,/^## End COMMON_PRE_/ p' <Make-common.sim >Makesim1.tmp
|
||||
|
||||
@@ -9,7 +9,7 @@ SIM_AC_OPTION_ENDIAN(LITTLE_ENDIAN)
|
||||
SIM_AC_OPTION_HOSTENDIAN
|
||||
SIM_AC_OPTION_WARNINGS
|
||||
|
||||
AC_CHECK_FUNCS(time, chmod, utime)
|
||||
AC_CHECK_FUNCS(time chmod utime fork execve execv chown)
|
||||
AC_CHECK_HEADERS(unistd.h stdlib.h string.h strings.h utime.h time.h)
|
||||
|
||||
SIM_AC_OUTPUT
|
||||
|
||||
@@ -155,249 +155,6 @@ lookup_hash (sd, ins)
|
||||
return (h);
|
||||
}
|
||||
|
||||
/* FIXME These would more efficient to use than load_mem/store_mem,
|
||||
but need to be changed to use the memory map. */
|
||||
|
||||
uint8
|
||||
get_byte (x)
|
||||
uint8 *x;
|
||||
{
|
||||
return *x;
|
||||
}
|
||||
|
||||
uint16
|
||||
get_half (x)
|
||||
uint8 *x;
|
||||
{
|
||||
uint8 *a = x;
|
||||
return (a[1] << 8) + (a[0]);
|
||||
}
|
||||
|
||||
uint32
|
||||
get_word (x)
|
||||
uint8 *x;
|
||||
{
|
||||
uint8 *a = x;
|
||||
return (a[3]<<24) + (a[2]<<16) + (a[1]<<8) + (a[0]);
|
||||
}
|
||||
|
||||
void
|
||||
put_byte (addr, data)
|
||||
uint8 *addr;
|
||||
uint8 data;
|
||||
{
|
||||
uint8 *a = addr;
|
||||
a[0] = data;
|
||||
}
|
||||
|
||||
void
|
||||
put_half (addr, data)
|
||||
uint8 *addr;
|
||||
uint16 data;
|
||||
{
|
||||
uint8 *a = addr;
|
||||
a[0] = data & 0xff;
|
||||
a[1] = (data >> 8) & 0xff;
|
||||
}
|
||||
|
||||
void
|
||||
put_word (addr, data)
|
||||
uint8 *addr;
|
||||
uint32 data;
|
||||
{
|
||||
uint8 *a = addr;
|
||||
a[0] = data & 0xff;
|
||||
a[1] = (data >> 8) & 0xff;
|
||||
a[2] = (data >> 16) & 0xff;
|
||||
a[3] = (data >> 24) & 0xff;
|
||||
}
|
||||
|
||||
uint8 *
|
||||
map (addr)
|
||||
SIM_ADDR addr;
|
||||
{
|
||||
/* Mask down to 24 bits. */
|
||||
addr &= 0xffffff;
|
||||
|
||||
if (addr < 0x100000)
|
||||
{
|
||||
/* "Mirror" the addresses below 1MB. */
|
||||
addr = addr & (simulator->rom_size - 1);
|
||||
return (uint8 *) (simulator->mem) + addr;
|
||||
}
|
||||
else if (addr < simulator->low_end)
|
||||
{
|
||||
/* chunk is just after the rom */
|
||||
addr = addr - 0x100000 + simulator->rom_size;
|
||||
return (uint8 *) (simulator->mem) + addr;
|
||||
}
|
||||
else if (addr >= simulator->high_start)
|
||||
{
|
||||
/* If in the peripheral I/O region, mirror 1K region across 4K,
|
||||
and similarly if in the internal RAM region. */
|
||||
if (addr >= 0xfff000)
|
||||
addr &= 0xfff3ff;
|
||||
else if (addr >= 0xffe000)
|
||||
addr &= 0xffe3ff;
|
||||
addr = addr - simulator->high_start + simulator->high_base;
|
||||
return (uint8 *) (simulator->mem) + addr;
|
||||
}
|
||||
else
|
||||
{
|
||||
sim_io_eprintf (simulator, "segmentation fault: access address: %lx not below %lx or above %lx [ep = %lx]\n",
|
||||
(long) addr,
|
||||
(long) simulator->low_end,
|
||||
(long) simulator->high_start,
|
||||
State.regs[30]);
|
||||
|
||||
/* Signal a memory error. */
|
||||
State.exception = SIGSEGV;
|
||||
/* Point to a location not in main memory - renders invalid
|
||||
addresses harmless until we get back to main insn loop. */
|
||||
return (uint8 *) &(State.dummy_mem);
|
||||
}
|
||||
}
|
||||
|
||||
uint32
|
||||
load_mem (addr, len)
|
||||
SIM_ADDR addr;
|
||||
int len;
|
||||
{
|
||||
uint8 *p = map (addr);
|
||||
|
||||
switch (len)
|
||||
{
|
||||
case 1:
|
||||
return p[0];
|
||||
case 2:
|
||||
return p[1] << 8 | p[0];
|
||||
case 4:
|
||||
return p[3] << 24 | p[2] << 16 | p[1] << 8 | p[0];
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
store_mem (addr, len, data)
|
||||
SIM_ADDR addr;
|
||||
int len;
|
||||
uint32 data;
|
||||
{
|
||||
uint8 *p = map (addr);
|
||||
|
||||
switch (len)
|
||||
{
|
||||
case 1:
|
||||
p[0] = data;
|
||||
return;
|
||||
case 2:
|
||||
p[0] = data;
|
||||
p[1] = data >> 8;
|
||||
return;
|
||||
case 4:
|
||||
p[0] = data;
|
||||
p[1] = data >> 8;
|
||||
p[2] = data >> 16;
|
||||
p[3] = data >> 24;
|
||||
return;
|
||||
default:
|
||||
abort ();
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
sim_memory_init (SIM_DESC sd)
|
||||
{
|
||||
int totsize;
|
||||
|
||||
if (sd->mem)
|
||||
zfree (sd->mem);
|
||||
|
||||
totsize = (simulator->rom_size
|
||||
+ (sd->low_end - 0x100000)
|
||||
+ (0x1000000 - sd->high_start));
|
||||
|
||||
sd->high_base = sd->rom_size + (sd->low_end - 0x100000);
|
||||
|
||||
sd->mem = zalloc (totsize);
|
||||
if (!sd->mem)
|
||||
{
|
||||
sim_io_error (sd, "Allocation of main memory failed.");
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
sim_parse_number (str, rest)
|
||||
char *str, **rest;
|
||||
{
|
||||
if (str[0] == '0' && str[1] == 'x')
|
||||
return strtoul (str, rest, 16);
|
||||
else if (str[0] == '0')
|
||||
return strtoul (str, rest, 16);
|
||||
else
|
||||
return strtoul (str, rest, 10);
|
||||
}
|
||||
|
||||
static void
|
||||
sim_set_memory_map (sd, spec)
|
||||
SIM_DESC sd;
|
||||
char *spec;
|
||||
{
|
||||
char *reststr, *nreststr;
|
||||
SIM_ADDR new_low_end, new_high_start;
|
||||
|
||||
new_low_end = sd->low_end;
|
||||
new_high_start = sd->high_start;
|
||||
if (! strncmp (spec, "hole=", 5))
|
||||
{
|
||||
new_low_end = sim_parse_number (spec + 5, &reststr);
|
||||
if (new_low_end < 0x100000)
|
||||
{
|
||||
sim_io_printf (sd, "Low end must be at least 0x100000\n");
|
||||
return;
|
||||
}
|
||||
if (*reststr == ',')
|
||||
{
|
||||
++reststr;
|
||||
new_high_start = sim_parse_number (reststr, &nreststr);
|
||||
/* FIXME Check high_start also */
|
||||
}
|
||||
sim_io_printf (sd, "Hole goes from 0x%x to 0x%x\n",
|
||||
new_low_end, new_high_start);
|
||||
}
|
||||
else
|
||||
{
|
||||
sim_io_printf (sd, "Invalid specification for memory map, must be `hole=<m>[,<n>]'\n");
|
||||
}
|
||||
|
||||
if (new_low_end != sd->low_end || new_high_start != sd->high_start)
|
||||
{
|
||||
sd->low_end = new_low_end;
|
||||
sd->high_start = new_high_start;
|
||||
sim_io_printf (sd, "Reconfiguring memory (old contents will be lost)\n");
|
||||
sim_memory_init (sd);
|
||||
}
|
||||
}
|
||||
|
||||
/* Parse a number in hex, octal, or decimal form. */
|
||||
|
||||
int
|
||||
sim_write (sd, addr, buffer, size)
|
||||
SIM_DESC sd;
|
||||
SIM_ADDR addr;
|
||||
unsigned char *buffer;
|
||||
int size;
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < size; i++)
|
||||
store_mem (addr + i, 1, buffer[i]);
|
||||
|
||||
return size;
|
||||
}
|
||||
|
||||
|
||||
SIM_DESC
|
||||
sim_open (kind, cb, abfd, argv)
|
||||
SIM_OPEN_KIND kind;
|
||||
@@ -405,6 +162,7 @@ sim_open (kind, cb, abfd, argv)
|
||||
struct _bfd *abfd;
|
||||
char **argv;
|
||||
{
|
||||
char *buf;
|
||||
SIM_DESC sd = sim_state_alloc (kind, cb);
|
||||
struct simops *s;
|
||||
struct hash_entry *h;
|
||||
@@ -412,16 +170,23 @@ sim_open (kind, cb, abfd, argv)
|
||||
/* for compatibility */
|
||||
simulator = sd;
|
||||
|
||||
sd->rom_size = V850_ROM_SIZE;
|
||||
sd->low_end = V850_LOW_END;
|
||||
sd->high_start = V850_HIGH_START;
|
||||
|
||||
/* Allocate memory */
|
||||
sim_memory_init (sd);
|
||||
|
||||
if (sim_pre_argv_init (sd, argv[0]) != SIM_RC_OK)
|
||||
return 0;
|
||||
|
||||
/* Allocate core managed memory */
|
||||
/* "Mirror" the ROM addresses below 1MB. */
|
||||
asprintf (&buf, "memory region 0,0x100000,0x%lx", V850_ROM_SIZE);
|
||||
sim_do_command (sd, buf);
|
||||
free (buf);
|
||||
/* Chunk of ram adjacent to rom */
|
||||
asprintf (&buf, "memory region 0x100000,0x%lx", V850_LOW_END - 0x100000);
|
||||
sim_do_command (sd, buf);
|
||||
free (buf);
|
||||
/* peripheral I/O region - mirror 1K across 4k (0x1000) */
|
||||
sim_do_command (sd, "memory region 0xfff000,0x1000,1024");
|
||||
/* similarly if in the internal RAM region */
|
||||
sim_do_command (sd, "memory region 0xffe000,0x1000,1024");
|
||||
|
||||
/* 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. */
|
||||
@@ -718,7 +483,7 @@ sim_fetch_register (sd, rn, memory)
|
||||
int rn;
|
||||
unsigned char *memory;
|
||||
{
|
||||
put_word (memory, State.regs[rn]);
|
||||
*(unsigned32*)memory = H2T_4 (State.regs[rn]);
|
||||
}
|
||||
|
||||
void
|
||||
@@ -727,22 +492,20 @@ sim_store_register (sd, rn, memory)
|
||||
int rn;
|
||||
unsigned char *memory;
|
||||
{
|
||||
State.regs[rn] = get_word (memory);
|
||||
State.regs[rn] = T2H_4 (*(unsigned32*)memory);
|
||||
}
|
||||
|
||||
int
|
||||
sim_read (sd, addr, buffer, size)
|
||||
SIM_DESC sd;
|
||||
SIM_ADDR addr;
|
||||
unsigned char *buffer;
|
||||
int size;
|
||||
static int
|
||||
sim_parse_number (str, rest)
|
||||
char *str, **rest;
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < size; i++)
|
||||
buffer[i] = load_mem (addr + i, 1);
|
||||
|
||||
return size;
|
||||
}
|
||||
if (str[0] == '0' && str[1] == 'x')
|
||||
return strtoul (str, rest, 16);
|
||||
else if (str[0] == '0')
|
||||
return strtoul (str, rest, 16);
|
||||
else
|
||||
return strtoul (str, rest, 10);
|
||||
}
|
||||
|
||||
int current_intgen_number = 1;
|
||||
|
||||
@@ -890,24 +653,13 @@ sim_do_command (sd, cmd)
|
||||
char *mm_cmd = "memory-map";
|
||||
char *int_cmd = "interrupt";
|
||||
|
||||
if (! strncmp (cmd, mm_cmd, strlen (mm_cmd))
|
||||
&& strchr (" ", cmd[strlen(mm_cmd)]))
|
||||
sim_set_memory_map (sd, cmd + strlen(mm_cmd) + 1);
|
||||
if (strncmp (cmd, mm_cmd, strlen (mm_cmd) == 0))
|
||||
sim_io_eprintf (sd, "`memory-map' command replaced by `sim memory'\n");
|
||||
|
||||
else if (! strncmp (cmd, int_cmd, strlen (int_cmd))
|
||||
&& strchr (" ", cmd[strlen(int_cmd)]))
|
||||
sim_set_interrupt (sd, cmd + strlen(int_cmd) + 1);
|
||||
|
||||
else if (! strcmp (cmd, "help"))
|
||||
{
|
||||
sim_io_printf (sd, "V850 simulator commands:\n\n");
|
||||
sim_io_printf (sd, "interrupt add <inttype> { pc | time } <value> -- Set up an interrupt generator\n");
|
||||
sim_io_printf (sd, "interrupt remove <n> -- Remove an existing interrupt generator\n");
|
||||
sim_io_printf (sd, "interrupt info -- List all the interrupt generators\n");
|
||||
sim_io_printf (sd, "memory-map hole=<m>,<n> -- Set the memory map to have a hole between <m> and <n>\n");
|
||||
sim_io_printf (sd, "\n");
|
||||
}
|
||||
else
|
||||
sim_io_printf (sd, "\"%s\" is not a valid V850 simulator command.\n",
|
||||
cmd);
|
||||
else if (sim_args_command (sd, cmd) != SIM_RC_OK)
|
||||
sim_io_eprintf (sd, "Unknown command `%s'\n", cmd);
|
||||
}
|
||||
|
||||
@@ -43,11 +43,13 @@ struct sim_state {
|
||||
#else
|
||||
#define STATE_CPU(sd,n) (&(sd)->cpu[0])
|
||||
#endif
|
||||
#if 0
|
||||
SIM_ADDR rom_size;
|
||||
SIM_ADDR low_end;
|
||||
SIM_ADDR high_start;
|
||||
SIM_ADDR high_base;
|
||||
void *mem;
|
||||
#endif
|
||||
sim_state_base base;
|
||||
};
|
||||
|
||||
@@ -158,14 +160,18 @@ extern struct simops Simops[];
|
||||
|
||||
/* Function declarations. */
|
||||
|
||||
uint32 get_word PARAMS ((uint8 *));
|
||||
uint16 get_half PARAMS ((uint8 *));
|
||||
uint8 get_byte PARAMS ((uint8 *));
|
||||
void put_word PARAMS ((uint8 *, uint32));
|
||||
void put_half PARAMS ((uint8 *, uint16));
|
||||
void put_byte PARAMS ((uint8 *, uint8));
|
||||
#define IMEM(EA) \
|
||||
sim_core_read_aligned_2 (STATE_CPU (sd, 0), \
|
||||
PC, sim_core_execute_map, (EA))
|
||||
|
||||
extern uint32 load_mem PARAMS ((SIM_ADDR addr, int len));
|
||||
extern void store_mem PARAMS ((SIM_ADDR addr, int len, uint32 data));
|
||||
#define IMEM_IMMED(EA,N) \
|
||||
sim_core_read_aligned_2 (STATE_CPU (sd, 0), \
|
||||
PC, sim_core_execute_map, (EA) + (N) * 4)
|
||||
|
||||
extern uint8 *map PARAMS ((SIM_ADDR addr));
|
||||
#define load_mem(ADDR,LEN) \
|
||||
sim_core_read_unaligned_##LEN (STATE_CPU (simulator, 0), \
|
||||
PC, sim_core_read_map, (ADDR))
|
||||
|
||||
#define store_mem(ADDR,LEN,DATA) \
|
||||
sim_core_write_unaligned_##LEN (STATE_CPU (simulator, 0), \
|
||||
PC, sim_core_write_map, (ADDR), (DATA))
|
||||
|
||||
@@ -9,6 +9,10 @@
|
||||
|
||||
#ifdef HAVE_TIME_H
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
/* FIXME - should be including a version of syscall.h that does not
|
||||
@@ -16,6 +20,8 @@
|
||||
#include "../../libgloss/v850/sys/syscall.h"
|
||||
|
||||
#include "bfd.h"
|
||||
#include "libiberty.h"
|
||||
|
||||
#include <errno.h>
|
||||
#if !defined(__GO32__) && !defined(_WIN32)
|
||||
#include <sys/stat.h>
|
||||
@@ -589,6 +595,50 @@ Multiply64 (boolean sign, unsigned long op0)
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
/* Read a null terminated string from memory, return in a buffer */
|
||||
static char *
|
||||
fetch_str (sd, addr)
|
||||
SIM_DESC sd;
|
||||
address_word addr;
|
||||
{
|
||||
char *buf;
|
||||
int nr = 0;
|
||||
while (sim_core_read_1 (STATE_CPU (sd, 0),
|
||||
PC, sim_core_read_map, addr + nr) != 0)
|
||||
nr++;
|
||||
buf = NZALLOC (char, nr + 1);
|
||||
sim_read (simulator, addr, buf, nr);
|
||||
return buf;
|
||||
}
|
||||
|
||||
/* Read a null terminated argument vector from memory, return in a
|
||||
buffer */
|
||||
static char **
|
||||
fetch_argv (sd, addr)
|
||||
SIM_DESC sd;
|
||||
address_word addr;
|
||||
{
|
||||
int max_nr = 64;
|
||||
int nr = 0;
|
||||
char **buf = xmalloc (max_nr * sizeof (char*));
|
||||
while (1)
|
||||
{
|
||||
unsigned32 a = sim_core_read_4 (STATE_CPU (sd, 0),
|
||||
PC, sim_core_read_map, addr + nr * 4);
|
||||
if (a == 0) break;
|
||||
buf[nr] = fetch_str (sd, a);
|
||||
nr ++;
|
||||
if (nr == max_nr - 1)
|
||||
{
|
||||
max_nr += 50;
|
||||
buf = xrealloc (buf, max_nr * sizeof (char*));
|
||||
}
|
||||
}
|
||||
buf[nr] = 0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
||||
/* sld.b */
|
||||
int
|
||||
@@ -2226,7 +2276,7 @@ OP_10007E0 ()
|
||||
switch (FUNC)
|
||||
{
|
||||
|
||||
#if !defined(__GO32__) && !defined(_WIN32)
|
||||
#ifdef HAVE_FORK
|
||||
#ifdef SYS_fork
|
||||
case SYS_fork:
|
||||
RETVAL = fork ();
|
||||
@@ -2234,20 +2284,33 @@ OP_10007E0 ()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(__GO32__) && !defined(_WIN32)
|
||||
#ifdef HAVE_EXECVE
|
||||
#ifdef SYS_execv
|
||||
case SYS_execve:
|
||||
RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2),
|
||||
(char **)MEMPTR (PARM3));
|
||||
break;
|
||||
{
|
||||
char *path = fetch_str (simulator, PARM1);
|
||||
char **argv = fetch_argv (simulator, PARM2);
|
||||
char **envp = fetch_argv (simulator, PARM3);
|
||||
RETVAL = execve (path, argv, envp);
|
||||
zfree (path);
|
||||
freeargv (argv);
|
||||
freeargv (envp);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(__GO32__) && !defined(_WIN32)
|
||||
#if HAVE_EXECV
|
||||
#ifdef SYS_execv
|
||||
case SYS_execv:
|
||||
RETVAL = execve (MEMPTR (PARM1), (char **) MEMPTR (PARM2), NULL);
|
||||
break;
|
||||
{
|
||||
char *path = fetch_str (simulator, PARM1);
|
||||
char **argv = fetch_argv (simulator, PARM2);
|
||||
RETVAL = execv (path, argv);
|
||||
zfree (path);
|
||||
freeargv (argv);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -2283,17 +2346,27 @@ OP_10007E0 ()
|
||||
|
||||
#ifdef SYS_read
|
||||
case SYS_read:
|
||||
RETVAL = sim_io_read (simulator, PARM1, MEMPTR (PARM2), PARM3);
|
||||
break;
|
||||
{
|
||||
char *buf = zalloc (PARM3);
|
||||
RETVAL = sim_io_read (simulator, PARM1, buf, PARM3);
|
||||
sim_write (simulator, PARM2, buf, PARM3);
|
||||
zfree (buf);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SYS_write
|
||||
case SYS_write:
|
||||
if (PARM1 == 1)
|
||||
RETVAL = sim_io_write_stdout (simulator, MEMPTR (PARM2), PARM3);
|
||||
else
|
||||
RETVAL = sim_io_write (simulator, PARM1, MEMPTR (PARM2), PARM3);
|
||||
break;
|
||||
{
|
||||
char *buf = zalloc (PARM3);
|
||||
sim_read (simulator, PARM2, buf, PARM3);
|
||||
if (PARM1 == 1)
|
||||
RETVAL = sim_io_write_stdout (simulator, buf, PARM3);
|
||||
else
|
||||
RETVAL = sim_io_write (simulator, PARM1, buf, PARM3);
|
||||
zfree (buf);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SYS_lseek
|
||||
@@ -2310,8 +2383,12 @@ OP_10007E0 ()
|
||||
|
||||
#ifdef SYS_open
|
||||
case SYS_open:
|
||||
RETVAL = sim_io_open (simulator, MEMPTR (PARM1), PARM2);
|
||||
break;
|
||||
{
|
||||
char *buf = fetch_str (simulator, PARM1);
|
||||
RETVAL = sim_io_open (simulator, buf, PARM2);
|
||||
zfree (buf);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef SYS_exit
|
||||
@@ -2332,9 +2409,11 @@ OP_10007E0 ()
|
||||
{
|
||||
struct stat host_stat;
|
||||
reg_t buf;
|
||||
char *path = fetch_str (simulator, PARM1);
|
||||
|
||||
RETVAL = stat (MEMPTR (PARM1), &host_stat);
|
||||
RETVAL = stat (path, &host_stat);
|
||||
|
||||
zfree (path);
|
||||
buf = PARM2;
|
||||
|
||||
/* Just wild-assed guesses. */
|
||||
@@ -2354,18 +2433,26 @@ OP_10007E0 ()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if !defined(__GO32__) && !defined(_WIN32)
|
||||
#ifdef HAVE_CHOWN
|
||||
#ifdef SYS_chown
|
||||
case SYS_chown:
|
||||
RETVAL = chown (MEMPTR (PARM1), PARM2, PARM3);
|
||||
{
|
||||
char *path = fetch_str (simulator, PARM1);
|
||||
RETVAL = chown (path, PARM2, PARM3);
|
||||
zfree (path);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef SYS_chmod
|
||||
#if HAVE_CHMOD
|
||||
#ifdef SYS_chmod
|
||||
case SYS_chmod:
|
||||
RETVAL = chmod (MEMPTR (PARM1), PARM2);
|
||||
{
|
||||
char *path = fetch_str (simulator, PARM1);
|
||||
RETVAL = chmod (path, PARM2);
|
||||
zfree (path);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
@@ -2416,9 +2503,12 @@ OP_10007E0 ()
|
||||
#ifdef SYS_utime
|
||||
#if HAVE_UTIME
|
||||
case SYS_utime:
|
||||
/* Cast the second argument to void *, to avoid type mismatch
|
||||
if a prototype is present. */
|
||||
RETVAL = utime (MEMPTR (PARM1), (void *) MEMPTR (PARM2));
|
||||
{
|
||||
/* Cast the second argument to void *, to avoid type mismatch
|
||||
if a prototype is present. */
|
||||
sim_io_error (simulator, "Utime not supported");
|
||||
/* RETVAL = utime (path, (void *) MEMPTR (PARM2)); */
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user