commit - 1927278bfae34067f3006f13d739c0351f14a1d2
commit + 502e1ef880c10f53d5a8c8ea78a8b9f2fd4a5977
blob - 038e3eabdf2b72e8a0eb09c150efc3ad81ad0ebf
blob + bb18a8d865b5c24e0ade1a9488bb36d2f20106de
--- Makefile
+++ Makefile
cp -f linurv rootfs/bin
cp -f ${PROGS} rootfs/bin
cp -f test.txt rootfs/
- ${CHROOT} rootfs /bin/linurv /bin/$T.elf
+ ${CHROOT} rootfs /bin/linurv -v /bin/$T.elf
distclean: clean
(cd tools; ${MAKE} distclean)
blob - 60f901e6468c5e851aa49a7cac9874e15027d194
blob + 4f3bb6e1a4bb70d41d87025a1e948d9fc9a1ce9d
--- examples/test.c
+++ examples/test.c
+#include <sys/types.h>
+#include <sys/stat.h>
#include <sys/mman.h>
+#include <stdbool.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
printf ("Result: %u\n", mul (3, 2));
- execl ("/bin/ksh", "/bin/ksh", NULL);
+ execlp ("ksh", "ksh", NULL);
return 0;
}
blob - 9531dd891e95809b8f341424073df5a2e1596f40
blob + bc34f26155fd92483965e8e475cd02bf467bb46d
--- src/ecall.c
+++ src/ecall.c
{
memset (lst, 0, sizeof (*lst));
lst->dev = st->st_dev;
- lst->ino = st->st_dev;
- lst->mode = st->st_dev;
- lst->nlink = st->st_dev;
- lst->uid = st->st_dev;
- lst->gid = st->st_dev;
- lst->rdev = st->st_dev;
- lst->size = st->st_dev;
- lst->blksize = st->st_dev;
- lst->blocks = st->st_dev;
+ lst->ino = st->st_ino;
+ lst->mode = st->st_mode;
+ lst->nlink = st->st_nlink;
+ lst->uid = st->st_uid;
+ lst->gid = st->st_gid;
+ lst->rdev = st->st_rdev;
+ lst->size = st->st_size;
+ lst->blksize = st->st_blksize;
+ lst->blocks = st->st_blocks;
lst->atime = st->st_atim.tv_sec;
lst->atime_ns = st->st_atim.tv_nsec;
lst->mtime = st->st_mtim.tv_sec;
o |= PROT_READ;
if (x & 0x02)
o |= PROT_WRITE;
+ return o;
+}
+
+static int map_at (int fd)
+{
+ return fd == -100 ? AT_FDCWD : fd;
+}
+
+static int map_access (int x)
+{
+ int o = 0;
+
+ if (x == 0)
+ return F_OK;
+
+ if (x & 1)
+ o |= X_OK;
+ if (x & 2)
+ o |= W_OK;
+ if (x & 4)
+ o |= R_OK;
+
return o;
}
#define ptr(T, x) ((T *)(x))
#define str(x) ptr (const char, x)
+#define dbg0(fmt) debug (fmt ": %ld", ret)
+#define dbg(fmt, ...) debug (fmt ": %ld", __VA_ARGS__, ret)
void ecall (void)
{
struct linux_stat64 lst;
const u64 a4 = cpu_get (14);
const u64 a5 = cpu_get (15);
const u64 a7 = cpu_get (17);
+ const int i0 = (int)a0;
+ const int i1 = (int)a1;
+ const int i2 = (int)a2;
+ const int i3 = (int)a3;
+ const int i4 = (int)a4;
const char *name = NULL;
if (a7 <= SYS_debug)
name = syscall_names[a7];
- debug (
- "ecall a7=%"PRIu64" [%s], a0=%"PRIu64", a1=%"PRIu64", a2=%"PRIu64", a3=%"PRIu64", a4=%"PRIu64", a5=%"PRIu64,
- a7, name, a0, a1, a2, a3, a4, a5
- );
+ //debug (
+ // "ecall a7=%"PRIu64" [%s], a0=%"PRIu64", a1=%"PRIu64", a2=%"PRIu64", a3=%"PRIu64", a4=%"PRIu64", a5=%"PRIu64,
+ // a7, name, a0, a1, a2, a3, a4, a5
+ //);
- int tmp, tmp2;
- i64 ret;
+ int tmp, tmp2, tmp3;
+ long ret;
+ _Static_assert (sizeof (ret) == sizeof (i64));
switch (a7) {
case SYS_getcwd:
ret = map (getcwd ((char *)a0, (size_t)a1) != NULL ? 0 : -1);
+ dbg0 ("getcwd()");
break;
case SYS_dup:
- ret = map (dup ((int)a0));
+ ret = map (dup (i0));
+ dbg ("dup(%d)", i0);
break;
case SYS_dup3:
- ret = map (dup3 ((int)a0, (int)a1, (int)a2));
+ ret = map (dup3 (i0, i1, i2));
+ dbg ("dup3(%d, %d, %d)", i0, i1, i2);
break;
case SYS_fcntl:
ret = enosys ("fcntl");
ret = enosys ("ioctl");
break;
case SYS_flock:
- ret = map (flock ((int)a0, (int)a1));
+ ret = map (flock (i0, i1));
+ dbg ("flock(%d, %d)", i0, i1);
break;
case SYS_mknodat:
- ret = map (mknodat ((int)a0, str (a1), (mode_t)a2, (dev_t)a3));
+ ret = map (mknodat (i0, str (a1), (mode_t)a2, (dev_t)a3));
+ dbg ("mknodat(%d, \"%s\", %o, %d)", i0, str (a1), i2, i3);
break;
case SYS_mkdirat:
- ret = map (mkdirat ((int)a0, str (a1), (mode_t)a2));
+ ret = map (mkdirat (i0, str (a1), (mode_t)a2));
+ dbg ("mkdirat(%d, \"%s\", %o)", i0, str (a1), i2);
break;
case SYS_unlinkat:
- ret = map (unlinkat ((int)a0, str (a1), (int)a2));
+ ret = map (unlinkat (i0, str (a1), i2));
+ dbg ("unlinkat(%d, \"%s\", %d)", i0, str (a1), i2);
break;
case SYS_symlinkat:
- ret = map (symlinkat (str (a0), (int)a1, str (a2)));
+ ret = map (symlinkat (str (a0), i1, str (a2)));
+ dbg ("symlinkat(\"%s\", %d, \"%s\")", str (a0), i1, str (a2));
break;
case SYS_linkat:
- ret = map (linkat ((int)a0, str (a1), (int)a2, str (a3), (int)a4));
+ ret = map (linkat (i0, str (a1), i2, str (a3), i4));
+ dbg ("linkat(%d, \"%s\", %d, \"%s\", %d)", i0, str (a1), i2, str (a3), i4);
break;
case SYS_renameat:
- ret = map (renameat ((int)a0, str (a1), (int)a2, str (a3)));
+ ret = map (renameat (i0, str (a1), i2, str (a3)));
+ dbg ("renameat(%d, \"%s\", %d, \"%s\")", i0, str (a1), i2, str (a3));
break;
case SYS_umount:
ret = enosys ("umount");
break;
case SYS_truncate:
ret = map (truncate (str (a0), (off_t)a1));
+ dbg ("truncate(\"%s\", %llu)", str (a0), (unsigned long long)a1);
break;
- break;
case SYS_ftruncate:
- ret = map (ftruncate ((int)a0, (off_t)a1));
+ ret = map (ftruncate (i0, (off_t)a1));
+ dbg ("ftruncate(%d, %llu)", i0, (unsigned long long)a1);
break;
case SYS_fallocate:
ret = enosys ("fallocate");
break;
case SYS_faccessat:
- ret = map (faccessat ((int)a0, str (a1), (int)a2, (int)a3));
+ tmp = map_at (i0);
+ tmp2 = map_access (i2);
+ tmp3 = 0;
+ if (i3 & 0x200)
+ tmp3 |= AT_EACCESS;
+ ret = map (faccessat (tmp, str (a1), tmp2, tmp3));
+ dbg ("faccessat(%d, \"%s\", %o, %d)", tmp, str (a1), tmp2, tmp3);
break;
case SYS_chdir:
ret = map (chdir (str (a0)));
+ dbg ("chdir(\"%s\")", str (a0));
break;
case SYS_fchdir:
- ret = map (fchdir ((int)a0));
+ ret = map (fchdir (i0));
+ dbg ("fchdir(%d)", i0);
break;
case SYS_chroot:
ret = map (chroot (str (a0)));
+ dbg ("chroot(\"%s\")", str (a0));
break;
case SYS_fchmod:
- ret = map (fchmod ((int)a0, (mode_t)a1));
+ ret = map (fchmod (i0, (mode_t)a1));
+ dbg ("fchmod(%d, %o)", i0, i1);
break;
case SYS_fchmodat:
- ret = map (fchmodat ((int)a0, str (a1), (mode_t)a2, (int)a3));
+ tmp = map_at (i0);
+ ret = map (fchmodat (tmp, str (a1), (mode_t)a2, i3));
+ dbg ("fchmodat(%d, \"%s\", %o, %d)", tmp, str (a1), i2, i3);
break;
case SYS_fchownat:
- ret = map (fchownat ((int)a0, str (a1), (uid_t)a2, (gid_t)a3, (int)a4));
+ tmp = map_at (i0);
+ ret = map (fchownat (tmp, str (a1), (uid_t)a2, (gid_t)a3, i4));
+ dbg ("fchownat(%d, \"%s\", %d, %d, %d)", tmp, str (a1), i2, i3, i4);
break;
case SYS_fchown:
- ret = map (fchown ((int)a0, (uid_t)a1, (gid_t)a2));
+ ret = map (fchown (i0, (uid_t)a1, (gid_t)a2));
+ dbg ("fchown(%d, %d, %d)", i0, i1, i2);
break;
case SYS_openat:
- tmp = (int)a0;
- if (tmp == -100)
- tmp = AT_FDCWD;
- tmp2 = open_flags ((int)a2);
- debug ("openat(%d, %s, %d, %d);", tmp, str (a1), tmp2, (int)a3);
- ret = map (openat (tmp, str (a1), tmp2, (int)a3));
+ tmp = map_at (i0);
+ tmp2 = open_flags (i2);
+ ret = map (openat (tmp, str (a1), tmp2, i3));
+ dbg ("openat(%d, %s, %d, %d)", tmp, str (a1), tmp2, i3);
break;
case SYS_close:
- ret = map (close ((int)a0));
+ ret = map (close (i0));
+ dbg ("close(%d)", i0);
break;
case SYS_vhangup:
ret = enosys ("vhangup");
break;
case SYS_pipe2:
- ret = map (pipe2 (ptr (int, a0), (int)a1));
+ ret = map (pipe2 (ptr (int, a0), i1));
+ dbg ("pipe2(%p, %d)", ptr (int, a0), i1);
break;
case SYS_quotactl:
ret = enosys ("quotactl");
ret = enosys ("getdents64");
break;
case SYS_lseek:
- ret = map (lseek ((int)a0, (off_t)a1, (int)a2));
+ ret = map (lseek (i0, (off_t)a1, i2));
+ dbg ("lseek(%d, %llu, %d)", i0, (unsigned long long)a1, i2);
break;
case SYS_read:
- ret = map (read ((int)a0, ptr (void, a1), (size_t)a2));
+ ret = map (read (i0, ptr (void, a1), (size_t)a2));
+ dbg ("read(%d, %p, %zu)", i0, ptr (void, a1), (size_t)a2);
break;
case SYS_write:
- ret = map (write ((int)a0, ptr (const void, a1), (size_t)a2));
+ ret = map (write (i0, ptr (const void, a1), (size_t)a2));
+ dbg ("write(%d, %p, %zu)", i0, ptr (const void, a1), (size_t)a2);
break;
case SYS_readv:
- ret = map (readv ((int)a0, ptr (const struct iovec, a1), (int)a2));
+ ret = map (readv (i0, ptr (const struct iovec, a1), i2));
+ dbg ("readv(%d, %p, %d)", i0, ptr (const struct iovec, a1), i2);
break;
case SYS_writev:
- ret = map (writev ((int)a0, ptr (const struct iovec, a1), (int)a2));
+ ret = map (writev (i0, ptr (const struct iovec, a1), i2));
+ dbg ("writev(%d, %p, %d)", i0, ptr (const struct iovec, a1), i2);
break;
case SYS_pread:
- ret = map (pread ((int)a0, ptr (void, a1), (size_t)a2, (off_t)a3));
+ ret = map (pread (i0, ptr (void, a1), (size_t)a2, (off_t)a3));
+ dbg ("pread(%d, %p, %zu, %llu)", i0, ptr (void, a1), (size_t)a2, (unsigned long long)a3);
break;
case SYS_pwrite:
- ret = map (pwrite ((int)a0, ptr (const void, a1), (size_t)a2, (off_t)a3));
+ ret = map (pwrite (i0, ptr (const void, a1), (size_t)a2, (off_t)a3));
+ dbg ("pwrite(%d, %p, %zu, %llu)", i0, ptr (const void, a1), (size_t)a2, (unsigned long long)a3);
break;
case SYS_preadv:
ret = enosys ("preadv");
ret = enosys ("tee");
break;
case SYS_readlinkat:
- ret = map (readlinkat ((int)a0, str (a1), ptr (char, a2), (size_t)a3));
+ ret = map (readlinkat (i0, str (a1), ptr (char, a2), (size_t)a3));
+ dbg ("readlinkat(%d, \"%s\", %p, %zu)", i0, str (a1), ptr (char, a2), (size_t)a3);
break;
case SYS_fstatat:
- ret = map (fstatat ((int)a0, str (a1), &st, (int)a3));
+ tmp = map_at (i0);
+ ret = map (fstatat (tmp, str (a1), &st, i3));
stat_to_linux_stat (&lst, &st);
memcpy (ptr (void, a2), &lst, sizeof (lst));
+ dbg ("fstatat(%d, \"%s\", %p, %d)", tmp, str (a1), ptr (void, a2), i3);
break;
case SYS_fstat:
- ret = map (fstat ((int)a0, &st));
+ tmp = map_at (i0);
+ ret = map (fstat (tmp, &st));
stat_to_linux_stat (&lst, &st);
memcpy (ptr (void, a1), &lst, sizeof (lst));
+ dbg ("fstat(%d, %p)", tmp, ptr (void, a1));
break;
case SYS_sync:
sync ();
+ debug ("sync()");
ret = 0;
break;
case SYS_fsync:
- ret = map (fsync ((int)a0));
+ ret = map (fsync (i0));
+ dbg ("fsync(%d)", i0);
break;
case SYS_fdatasync:
- ret = map (fdatasync ((int)a0));
+ ret = map (fdatasync (i0));
+ dbg ("fdatasync(%d)", i0);
break;
case SYS_sync_file_range:
ret = enosys ("sync_file_range");
break;
case SYS_acct:
ret = acct (str (a0));
+ dbg ("acct(\"%s\")", str (a0));
break;
case SYS_capget:
ret = enosys ("capget");
ret = enosys ("personality");
break;
case SYS_exit:
- exit (a0);
+ debug ("exit(%d)", i0);
+ exit (i0);
ret = -1;
break;
case SYS_exit_group:
break;
case SYS_sched_yield:
ret = map (sched_yield ());
+ dbg0 ("sched_yield()");
break;
case SYS_sched_get_priority_max:
- ret = map (sched_get_priority_max ((int)a0));
+ ret = map (sched_get_priority_max (i0));
+ dbg ("sched_get_priority_max(%d)", i0);
break;
case SYS_sched_get_priority_min:
- ret = map (sched_get_priority_min ((int)a0));
+ ret = map (sched_get_priority_min (i0));
+ dbg ("sched_get_priority_min(%d)", i0);
break;
case SYS_sched_rr_get_interval:
ret = enosys ("sched_rr_get_interval");
ret = enosys ("restart_syscall");
break;
case SYS_kill:
- ret = map (kill ((pid_t)a0, (int)a1));
+ ret = map (kill ((pid_t)a0, i1));
+ dbg ("kill(%d, %d)", i0, i1);
break;
case SYS_tkill:
ret = enosys ("tkill");
ret = enosys ("signalstack");
break;
case SYS_sigsuspend:
- ret = enosys ("sigsuspend");
+ //ret = enosys ("sigsuspend");
+ ret = 0;
break;
case SYS_sigaction:
ret = enosys ("sigaction");
ret = enosys ("sigreturn");
break;
case SYS_setpriority:
- ret = map (setpriority ((int)a0, (id_t)a1, (int)a2));
+ ret = map (setpriority (i0, (id_t)a1, i2));
+ dbg ("setpriority(%d, %d, %d)", i0, i1, i2);
break;
case SYS_getpriority:
- ret = map (getpriority ((int)a0, (id_t)a1));
+ ret = map (getpriority (i0, (id_t)a1));
+ dbg ("getpriority(%d, %d)", i0, i1);
break;
case SYS_reboot:
ret = enosys ("reboot");
break;
case SYS_setregid:
ret = map (setregid ((gid_t)a0, (gid_t)a1));
+ dbg ("setregid(%d, %d)", i0, i1);
break;
case SYS_setgid:
ret = map (setgid ((gid_t)a0));
+ dbg ("setgid(%d)", i0);
break;
case SYS_setreuid:
ret = map (setreuid ((uid_t)a0, (uid_t)a1));
+ dbg ("setreuid(%d, %d)", i0, i1);
break;
case SYS_setuid:
ret = map (setuid ((uid_t)a0));
+ dbg ("setuid(%d)", i0);
break;
case SYS_setresuid:
#ifdef __NetBSD__
- if (a0 != a1 || a0 != a2)
+ if (a0 != a1 || a0 != a2) {
ret = enosys ("setresuid");
- ret = map (setuid ((uid_t)a0));
+ } else {
+ ret = map (setuid ((uid_t)a0));
+ dbg ("setresuid(%d, %d, %d)", i0, i1, i2);
+ }
#else
ret = map (setresuid ((uid_t)a0, (uid_t)a1, (uid_t)a2));
+ dbg ("setresuid(%d, %d, %d)", i0, i1, i2);
#endif
break;
case SYS_getresuid:
ret = enosys ("getresuid");
#else
ret = map (getresuid (ptr (uid_t, a0), ptr (uid_t, a1), ptr (uid_t, a2)));
+ dbg ("getresuid(%p, %p, %p)", ptr (uid_t, a0), ptr (uid_t, a1), ptr (uid_t, a2));
#endif
break;
case SYS_setresgid:
#ifdef __NetBSD__
- if (a0 != a1 || a0 != a2)
+ if (a0 != a1 || a0 != a2) {
ret = enosys ("setresgid");
- ret = map (setgid ((uid_t)a0));
+ } else {
+ ret = map (setgid ((uid_t)a0));
+ dbg ("setresgid(%d, %d, %d)", i0, i1, i2);
+ }
#else
ret = map (setresgid ((gid_t)a0, (gid_t)a1, (gid_t)a2));
+ dbg ("setresgid(%d, %d, %d)", i0, i1, i2);
#endif
break;
case SYS_getresgid:
#ifdef __NetBSD__
- ret = -enosys ("getresgid");
+ ret = enosys ("getresgid");
#else
ret = map (getresgid (ptr (gid_t, a0), ptr (gid_t, a1), ptr (gid_t, a2)));
+ dbg ("getresgid(%p, %p, %p)", ptr (gid_t, a0), ptr (gid_t, a1), ptr (gid_t, a2));
#endif
break;
case SYS_setfsuid:
break;
case SYS_setpgid:
ret = map (setpgid ((pid_t)a0, (pid_t)a1));
+ dbg ("setpgid(%d, %d)", i0, i1);
break;
case SYS_getpgid:
ret = map (getpgid ((pid_t)a0));
+ dbg ("getpgid(%d)", i0);
break;
case SYS_getsid:
ret = map (getsid ((pid_t)a0));
+ dbg ("getsid(%d)", i0);
break;
case SYS_setsid:
ret = map (setsid ());
+ dbg0 ("setsid()");
break;
case SYS_setgroups:
ret = enosys ("setgroups");
ret = map (uname (&un));
utsname_to_linux_utsname (&lun, &un);
memcpy (ptr (void, a0), &lun, sizeof (lun));
+ dbg ("uname(%p)", ptr (void, a0));
break;
case SYS_sethostname:
ret = enosys ("sethostname");
break;
case SYS_umask:
ret = map (umask ((mode_t)a0));
+ dbg ("umask(%o)", i0);
break;
case SYS_prctl:
ret = enosys ("prctl");
break;
case SYS_getpid:
ret = map (getpid ());
+ dbg0 ("getpid()");
break;
case SYS_getppid:
ret = map (getppid ());
+ dbg0 ("getppid()");
break;
case SYS_getuid:
ret = map (getuid ());
+ dbg0 ("getuid()");
break;
case SYS_geteuid:
ret = map (geteuid ());
+ dbg0 ("geteuid()");
break;
case SYS_getgid:
ret = map (getgid ());
+ dbg0 ("getgid()");
break;
case SYS_getegid:
ret = map (getegid ());
+ dbg0 ("getegid()");
break;
case SYS_gettid:
ret = enosys ("gettid");
ret = enosys ("mq_*");
break;
case SYS_msgget:
- ret = map(msgget ((key_t)a0, (int)a1));
+ ret = map(msgget ((key_t)a0, i1));
+ dbg ("msgget(%d, %d)", i0, i1);
break;
case SYS_msgctl:
ret = enosys ("msgctl");
break;
case SYS_msgrcv:
- ret = map (msgrcv ((int)a0, ptr (void, a1), (size_t)a2, (long)a3, (int)a4));
+ ret = map (msgrcv (i0, ptr (void, a1), (size_t)a2, (long)a3, i4));
+ dbg ("msgrcv(%d, %p, %zu, %ld, %d)", i0, ptr (void, a1), (size_t)a2, (long)a3, i4);
break;
case SYS_msgsnd:
- ret = map (msgsnd ((int)a0, ptr (const void, a1), (size_t)a2, (int)a3));
+ ret = map (msgsnd (i0, ptr (const void, a1), (size_t)a2, i3));
+ dbg ("msgsnd(%d, %p, %zu, %d)", i0, ptr (const void, a1), (size_t)a2, i3);
break;
case SYS_semget:
- ret = map (semget ((key_t)a0, (int)a1, (int)a2));
+ ret = map (semget ((key_t)a0, i1, i2));
+ dbg ("semget(%d, %d, %d)", i0, i1, i2);
break;
case SYS_semctl:
ret = enosys ("semctl");
break;
case SYS_brk:
ret = map (my_brk (a0));
+ debug ("brk(%p): %p", ptr (void, a0), (void *)ret);
break;
case SYS_munmap:
ret = map (munmap (ptr (void, a0), (size_t)a1));
+ dbg ("munmap(%p, %zu)", ptr (void, a0), (size_t)a1);
break;
case SYS_mremap:
ret = enosys ("mremap");
break;
case SYS_clone:
if (a0 == 17 && a1 == 0) {
- // fork
ret = map (fork ());
+ if (ret != 0)
+ dbg0 ("fork()");
} else {
ret = enosys ("clone");
}
break;
case SYS_execve:
+ debug ("execve(\"%s\", %p, %p)", str (a0), ptr (char *, a1), ptr (char *, a2));
ret = map (my_execve (str (a0), ptr (char *, a1), ptr (char *, a2)));
+ debug ("execve failed with %d", ret);
break;
case SYS_mmap:
- tmp = mmap_flags ((int)a3);
- tmp2 = mmap_prot ((int)a2);
- debug ("mmap (%p, %zu, %d, %d, %d, %lld);", ptr (void, a0), (size_t)a1, tmp2, tmp, (int)a4, (off_t)a5);
- ptr = mmap (ptr (void, a0), (size_t)a1, tmp2, tmp, (int)a4, (off_t)a5);
- debug ("ptr = %p", ptr);
+ tmp = mmap_flags (i3);
+ tmp2 = mmap_prot (i2);
+ ptr = mmap (ptr (void, a0), (size_t)a1, tmp2, tmp, i4, (off_t)a5);
if (ptr == NULL) {
ret = -map_errno (errno);
} else {
ret = (u64)ptr;
}
+ debug ("mmap(%p, %zu, %o, %d, %d, %llu): %p", ptr (void, a0), (size_t)a1, tmp2, tmp, i4, (unsigned long long)a5, (void *)ret);
break;
case SYS_fadvise64:
ret = enosys ("fadvise64");
ret = enosys ("swapoff");
break;
case SYS_mprotect:
- tmp = mmap_prot ((int)a2);
+ tmp = mmap_prot (a2);
ret = map (mprotect (ptr (void, a0), (size_t)a1, tmp));
+ dbg ("mprotect(%p, %zu, %d)", ptr (void, a0), (size_t)a1, tmp);
break;
case SYS_msync:
- ret = map (msync (ptr (void, a0), (size_t)a1, (int)a2));
+ ret = map (msync (ptr (void, a0), (size_t)a1, i2));
+ dbg ("msync(%p, %zu, %d)", ptr (void, a0), (size_t)a1, i2);
break;
case SYS_mlock:
ret = map (mlock (ptr (void, a0), (size_t)a1));
+ dbg ("mlock(%p, %zu)", ptr (void, a0), (size_t)a1);
break;
case SYS_munlock:
ret = map (munlock (ptr (void, a0), (size_t)a1));
+ dbg ("munlock(%p, %zu)", ptr (void, a0), (size_t)a1);
break;
case SYS_mlockall:
- ret = map (mlockall ((int)a0));
+ ret = map (mlockall (i0));
+ dbg ("mlockall(%d)", i0);
break;
case SYS_munlockall:
ret = map (munlockall ());
+ dbg0 ("munlockall()");
break;
case SYS_mincore:
ret = enosys ("mincore");
break;
case SYS_madvise:
- ret = map (madvise (ptr (void, a0), (size_t)a1, (int)a2));
+ // TODO: MADV_*
+ ret = map (madvise (ptr (void, a0), (size_t)a1, i2));
+ dbg ("madvise(%p, %zu, %d)", ptr (void, a0), (size_t)a1, i2);
break;
case SYS_remap_file_pages:
ret = enosys ("remap_file_pages");
ret = enosys ("kexec_file_load");
break;
case SYS_open:
- tmp = open_flags ((int)a1);
- ret = map (open ((const char *)(size_t)a0, tmp, (int)a2));
+ tmp = open_flags (i1);
+ ret = map (open (str (a0), tmp, i2));
+ dbg ("open(\"%s\", %o, %d)", str (a0), tmp, i2);
break;
case SYS_link:
ret = map (link (str (a0), str (a1)));
+ dbg ("link(\"%s\", \"%s\")", str (a0), str (a1));
break;
case SYS_unlink:
ret = map (unlink (str (a0)));
+ dbg ("unlink(\"%s\")", str (a0));
break;
case SYS_mkdir:
ret = map (mkdir (str (a0), (mode_t)a1));
+ dbg ("mkdir(\"%s\", %o)", str (a0), i1);
break;
case SYS_access:
- ret = map (access (str (a0), (int)a1));
+ // TODO: *_OK
+ tmp = map_access (i1);
+ ret = map (access (str (a0), tmp));
+ dbg ("access(\"%s\", %d)", str (a0), tmp);
break;
case SYS_stat:
ret = map (stat (str (a0), &st));
stat_to_linux_stat (&lst, &st);
memcpy (ptr (void, a1), &lst, sizeof (lst));
+ dbg ("stat(\"%s\", %p)", str (a0), ptr (void, a1));
break;
case SYS_lstat:
ret = map (lstat (str (a0), &st));
stat_to_linux_stat (&lst, &st);
memcpy (ptr (void, a1), &lst, sizeof (lst));
+ dbg ("lstat(\"%s\", %p)", str (a0), ptr (void, a1));
break;
case SYS_time:
ret = enosys ("time");
blob - bfafe890605229b56f681ae7470de4cf224f94fe
blob + cb238ae4659091f4c53a5e07cf31b2bb9ecc5897
--- src/exec.c
+++ src/exec.c
int my_execve (const char *path, char **argv, char **envp)
{
-
Elf64_Ehdr ehdr;
char buffer[256], *nl, *s;
int fd;
fd = open (path, O_RDONLY);
if (fd < 0)
return -1;
+
memset (buffer, 0, sizeof (buffer));
read (fd, buffer, 2);
close (fd);
if (is_executable (&ehdr)) {
+ // TODO: otherwise the emulator can't find the executable
+ argv[0] = strdup (path);
#if defined(__FreeBSD__)
- extern char **environ;
char **old_env;
int st;
blob - 61c6296fb607bcc75bf8caf387157710c9e5b6f3
blob + 71aa357d88b64ae841025838798dd4c7ccb427ad
--- src/linurv.c
+++ src/linurv.c
#include <errno.h>
#include "linurv.h"
-static const char *levelstr[] = {
+const char *levelstr[] = {
[LOG_SILENT] = "FATAL",
[LOG_ERROR] = "ERROR",
[LOG_WARN] = "WARN ",
return 1;
}
-int main (int argc, char *argv[], char *envp[])
+static void set_loglevel(enum log_level level)
+{
+ curlevel = level;
+ setenv ("LINURV_LOGLEVEL", levelstr[level], 1);
+}
+
+static void parse_loglevel (const char *s)
+{
+ for (int i = 0; i <= LOG_VDEBUG; ++i) {
+ if (strcasecmp (s, levelstr[i]) == 0) {
+ set_loglevel (i);
+ return;
+ }
+ }
+ errx (1, "invalid loglevel: %s", s);
+}
+
+static void parse_env (void)
+{
+ char *s = getenv ("LINURV_LOGLEVEL");
+
+ if (s != NULL) {
+ parse_loglevel (s);
+ } else {
+ set_loglevel (LOG_WARN);
+ }
+}
+
+int main (int argc, char *argv[])
{
const char *filename;
struct rlimit rl;
char *base;
int option;
- curlevel = LOG_WARN;
+ parse_env ();
base = basename (argv[0]);
+ printf ("progname: %s\n", getprogname ());
+
if (strcmp (base, "linurv") == 0) {
while ((option = getopt (argc, argv, "vl:")) != -1) {
switch (option) {
case 'l':
- for (int i = 0; i <= LOG_VDEBUG; ++i) {
- if (strcmp (optarg, levelstr[i]) == 0) {
- curlevel = i;
- break;
- }
- }
+ parse_loglevel (optarg);
break;
case 'v':
if (curlevel < LOG_DEBUG) {
- curlevel = LOG_DEBUG;
+ set_loglevel (LOG_DEBUG);
} else if (curlevel == LOG_DEBUG) {
- curlevel = LOG_VDEBUG;
+ set_loglevel (LOG_VDEBUG);
}
break;
default:
argc -= optind;
}
+
if (argc < 1)
return usage ();
stack_size = 1 << 20;
}
- for (envc = 0; envp[envc] != NULL; ++envc);
+ for (envc = 0; environ[envc] != NULL; ++envc);
- setup_stack (stack_size, argc, argv, envc, envp);
+ setup_stack (stack_size, argc, argv, envc, environ);
while (1) {
const u32 instr = cpu_fetch ();
blob - 9d4d706388fd3ee14b387733af2623db578b5fc2
blob + e139c889771a6f6a503315250cf80acbad06cd75
--- src/linurv.h
+++ src/linurv.h
extern u64 pc;
extern u64 brkval;
extern const char *interpreter;
+extern const char *levelstr[];
extern enum log_level curlevel;
+extern char **environ;
u32 cpu_fetch (void);
u64 cpu_get (size_t reg);