AS = $(CROSS_COMPILE)as
CFLAGS += -Wall -ggdb -DLOADER
LDFLAGS += -ggdb
+#LDFLAGS += -nodefaultlibs # NYET
ifndef DEBUG
CFLAGS += -O2 -fno-strict-aliasing
LDFLAGS += -O2
&& wait_ret != -ETIMEDOUT)
{
err("fb_thread: futex error: %d\n", wait_ret);
- g_sleep(1);
+ sleep(1);
goto check_keys;
}
if (fb_sync_thread_paused) {
#ifdef PND
if (geteuid() == 0) {
- fprintf(stderr, "don't try to run as root, device registers or memory "
- "might get trashed crashing the OS or even damaging the device.\n");
+ err("don't try to run as root, device registers or memory "
+ "might get trashed crashing the OS or even damaging the device.\n");
exit(1);
}
#endif
sigaction(SIGSEGV, &segv_action, NULL);
}
-int emu_read_gpiodev(void *buf, int count)
+long emu_read_gpiodev(void *buf, int count)
{
if (count <= 0) {
err("gpiodev read %d?\n", count);
- return -1;
+ return -EINVAL;
}
if (count > 4)
count = 4;
return count;
}
-static void *emu_mmap_dev(unsigned int length, int prot, int flags, unsigned int offset)
+static long emu_mmap_dev(unsigned int length, int prot, int flags, unsigned int offset)
{
u8 *umem, *umem_end;
// SoC regs
if ((offset & ~0x1ffff) == 0xc0000000) {
- return mmap((void *)0x7f000000, length, PROT_NONE,
+ return g_mmap2_raw((void *)0x7f000000, length, PROT_NONE,
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED|MAP_NORESERVE, -1, 0);
}
// MMSP2 blitter
if ((offset & ~0xffff) == 0xe0020000) {
- return mmap((void *)0x7f100000, length, PROT_NONE,
+ return g_mmap2_raw((void *)0x7f100000, length, PROT_NONE,
MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED|MAP_NORESERVE, -1, 0);
}
// upper mem
if ((offset & 0xfe000000) != 0x02000000) {
err("unexpected devmem mmap @ %08x\n", offset);
- errno = EINVAL;
- return MAP_FAILED;
+ return -EINVAL;
}
umem = uppermem_lookup(offset, &umem_end);
offset, umem + length - umem_end);
dbg("upper mem @ %08x %x = %p\n", offset, length, umem);
- return umem;
+ return (long)umem;
}
-void *emu_do_mmap(unsigned int length, int prot, int flags, int fd, unsigned int offset)
+long emu_do_mmap(unsigned int length, int prot, int flags, int fd,
+ unsigned int offset)
{
if (fd == FAKEDEV_MEM)
return emu_mmap_dev(length, prot, flags, offset);
return emu_mmap_dev(length, prot, flags, offset + 0x03381000);
err("bad/ni mmap(?, %d, %x, %x, %d, %08x)\n", length, prot, flags, fd, offset);
- errno = EINVAL;
- return MAP_FAILED;
+ return -EINVAL;
}
-int emu_do_munmap(void *addr, unsigned int length)
+long emu_do_munmap(void *addr, unsigned int length)
{
u8 *p = addr;
// set default buffer size to 16 * 1K
frag = (16<<16) | 10; // 16K
- ret = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag);
- if (ret != 0) {
- err("snd ioctl SETFRAGMENT %08x: ", frag);
- perror(NULL);
- }
+ ret = g_ioctl_raw(fd, SNDCTL_DSP_SETFRAGMENT, &frag);
+ if (ret != 0)
+ err("snd ioctl SETFRAGMENT %08x: %d\n", frag, ret);
#endif
}
-static int emu_sound_ioctl(int fd, int request, void *argp)
+static long emu_sound_ioctl(int fd, int request, void *argp)
{
int *arg = argp;
* Catch this and set to something that works. */
switch(request) {
case SNDCTL_DSP_SETFRAGMENT: {
- int ret, bsize, frag, frag_cnt;
+ int bsize, frag, frag_cnt;
+ long ret;
+
if (arg == NULL)
break;
}
frag |= frag_cnt << 16;
- ret = ioctl(fd, SNDCTL_DSP_SETFRAGMENT, &frag);
- if (ret != 0) {
- err("snd ioctl SETFRAGMENT %08x: ", frag);
- perror(NULL);
- }
+ ret = g_ioctl_raw(fd, SNDCTL_DSP_SETFRAGMENT, &frag);
+ if (ret != 0)
+ err("snd ioctl SETFRAGMENT %08x: %ld\n", frag, ret);
// indicate success even if we fail (because of ALSA mostly),
// things like MikMod will bail out otherwise.
return 0;
break;
}
- return ioctl(fd, request, argp);
+ return g_ioctl_raw(fd, request, argp);
}
-int emu_do_ioctl(int fd, int request, void *argp)
+long emu_do_ioctl(int fd, int request, void *argp)
{
if (fd == emu_interesting_fds[IFD_SOUND].fd)
return emu_sound_ioctl(fd, request, argp);
fail:
err("bad/ni ioctl(%d, %08x, %p)\n", fd, request, argp);
- errno = EINVAL;
- return -1;
+ return -EINVAL;
}
struct dev_fd_t emu_interesting_fds[] = {
void emu_init(void *map_bottom);
void emu_call_handle_op(struct op_context *op_ctx);
-void *emu_do_mmap(unsigned int length, int prot, int flags, int fd, unsigned int offset);
-int emu_do_munmap(void *addr, unsigned int length);
-int emu_do_ioctl(int fd, int request, void *argp);
-int emu_read_gpiodev(void *buf, int count);
+long emu_do_mmap(unsigned int length, int prot, int flags, int fd, unsigned int offset);
+long emu_do_munmap(void *addr, unsigned int length);
+long emu_do_ioctl(int fd, int request, void *argp);
+long emu_read_gpiodev(void *buf, int count);
void *emu_do_fopen(const char *path, const char *mode);
int emu_do_system(const char *command);
int emu_do_execve(const char *filename, char *const argv[], char *const envp[]);
g_write_raw(fd, buf, d - buf);
}
-void g_sleep(unsigned int seconds)
-{
- struct timespec ts = { seconds, 0 };
- g_nanosleep_raw(&ts, NULL);
-}
-
// vim:shiftwidth=2:expandtab
#define g_printf(fmt, ...) \
g_fprintf(1, fmt, ##__VA_ARGS__)
-
-void g_sleep(unsigned int seconds);
/*
* GINGE - GINGE Is Not Gp2x Emulator
- * (C) notaz, 2010-2011
+ * (C) notaz, 2010-2011,2016
*
* This work is licensed under the MAME license, see COPYING file for details.
*/
#include <errno.h>
#include "realfuncs.h"
+#include "syscalls.h"
+#include "llibc.h"
#include "header.h"
#if (DBG & 1)
-#define strace printf
+#define strace g_printf
#else
#define strace(...)
#endif
#endif
};
-static int w_open(const char *pathname, int flags, mode_t mode)
+static long w_open_raw(const char *pathname, int flags, mode_t mode)
{
- int i, ret;
+ long ret;
+ int i;
for (i = 0; i < ARRAY_SIZE(takeover_devs); i++) {
const char *p, *oname;
}
if (i == ARRAY_SIZE(takeover_devs))
- ret = open(pathname, flags, mode);
+ ret = g_open_raw(pathname, flags, mode);
if (ret >= 0) {
for (i = 0; emu_interesting_fds[i].name != NULL; i++) {
}
}
- strace("open(%s) = %d\n", pathname, ret);
+ strace("open(%s) = %ld\n", pathname, ret);
return ret;
}
-static void *w_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
+static int w_open(const char *pathname, int flags, mode_t mode)
+{
+ long ret = w_open_raw(pathname, flags, mode);
+ return g_syscall_error(ret);
+}
+
+static long w_mmap_raw(void *addr, size_t length, int prot, int flags,
+ int fd, off_t offset)
{
- void *ret;
+ long ret;
+
if (FAKEDEV_MEM <= fd && fd < FAKEDEV_FD_BOUNDARY)
ret = emu_do_mmap(length, prot, flags, fd, offset);
else
- ret = mmap(addr, length, prot, flags, fd, offset);
+ ret = g_mmap2_raw(addr, length, prot, flags, fd, offset >> 12);
- // threads are using heap before they mmap their stack
- // printf needs valid stack for pthread/errno
- if (((long)&ret & 0xf0000000) == 0xb0000000)
- strace("mmap(%p, %x, %x, %x, %d, %lx) = %p\n", addr, length, prot, flags, fd, (long)offset, ret);
+ strace("mmap(%p, %x, %x, %x, %d, %lx) = %lx\n",
+ addr, length, prot, flags, fd, (long)offset, ret);
return ret;
}
+
+static long w_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
+{
+ long ret = w_mmap_raw(addr, length, prot, flags, fd, offset);
+ return g_syscall_error(ret);
+}
#define w_mmap2 w_mmap
-static int w_munmap(void *addr, size_t length)
+static long w_munmap_raw(void *addr, size_t length)
{
- int ret;
+ long ret;
+
ret = emu_do_munmap(addr, length);
if (ret == -EAGAIN)
- ret = munmap(addr, length);
+ ret = g_munmap_raw(addr, length);
- if (((long)&ret & 0xf0000000) == 0xb0000000)
- strace("munmap(%p, %x) = %d\n", addr, length, ret);
+ strace("munmap(%p, %x) = %ld\n", addr, length, ret);
return ret;
}
-static ssize_t w_read(int fd, void *buf, size_t count)
+static int w_munmap(void *addr, size_t length)
+{
+ long ret = w_munmap_raw(addr, length);
+ return g_syscall_error(ret);
+}
+
+long w_read_raw(int fd, void *buf, size_t count)
{
- ssize_t ret;
+ long ret;
+
if (fd == FAKEDEV_GPIO)
ret = emu_read_gpiodev(buf, count);
else
- ret = read(fd, buf, count);
+ ret = g_read_raw(fd, buf, count);
- //strace("read(%d, %p, %d) = %d\n", fd, buf, count, ret);
+ //strace("read(%d, %p, %ld) = %ld\n", fd, buf, count, ret);
return ret;
}
-static int w_ioctl(int fd, int request, void *argp)
+static ssize_t w_read(int fd, void *buf, size_t count)
{
- int ret;
+ long ret = w_read_raw(fd, buf, count);
+ return g_syscall_error(ret);
+}
+
+long w_ioctl_raw(int fd, int request, void *argp)
+{
+ long ret;
if ((FAKEDEV_MEM <= fd && fd < FAKEDEV_FD_BOUNDARY) ||
fd == emu_interesting_fds[IFD_SOUND].fd)
ret = emu_do_ioctl(fd, request, argp);
else
- ret = ioctl(fd, request, argp);
+ ret = g_ioctl_raw(fd, request, argp);
- strace("ioctl(%d, %08x, %p) = %d\n", fd, request, argp, ret);
+ strace("ioctl(%d, %08x, %p) = %ld\n", fd, request, argp, ret);
return ret;
}
+static int w_ioctl(int fd, int request, void *argp)
+{
+ long ret = w_ioctl_raw(fd, request, argp);
+ return g_syscall_error(ret);
+}
+
static int w_sigaction(int signum, const void *act, void *oldact)
{
strace("sigaction(%d, %p, %p) = %d\n", signum, act, oldact, 0);
static int w_chdir(const char *path)
{
- int ret;
+ long ret;
+
if (path != NULL && strstr(path, "/usr/gp2x") != NULL)
ret = 0;
else
- ret = chdir(path);
+ ret = g_chdir_raw(path);
strace("chdir(%s) = %d\n", path, ret);
- return ret;
+ return g_syscall_error(ret);
}
#undef open
#undef munmap
#undef read
#undef ioctl
+#undef close
#undef sigaction
#undef tcgetattr
#undef tcsetattr
static typeof(sym) *p_real_##sym
// note: update symver too
-MAKE_WRAP_SYM(open);
+MAKE_WRAP_SYM_N(open);
MAKE_WRAP_SYM(fopen);
-MAKE_WRAP_SYM(mmap);
-MAKE_WRAP_SYM(munmap);
-MAKE_WRAP_SYM(read);
-MAKE_WRAP_SYM(ioctl);
+MAKE_WRAP_SYM_N(mmap);
+MAKE_WRAP_SYM_N(munmap);
+MAKE_WRAP_SYM_N(read);
+MAKE_WRAP_SYM_N(ioctl);
MAKE_WRAP_SYM(sigaction);
MAKE_WRAP_SYM(tcgetattr);
MAKE_WRAP_SYM(tcsetattr);
MAKE_WRAP_SYM_N(execv);
MAKE_WRAP_SYM_N(execvp);
MAKE_WRAP_SYM(execve);
-MAKE_WRAP_SYM(chdir);
+MAKE_WRAP_SYM_N(chdir);
typeof(mmap) mmap2 __attribute__((alias("w_mmap")));
#define REAL_FUNC_NP(name) \
const char *name;
void **func_ptr;
} real_funcs_np[] = {
- REAL_FUNC_NP(open),
+ //REAL_FUNC_NP(open),
REAL_FUNC_NP(fopen),
- REAL_FUNC_NP(mmap),
- REAL_FUNC_NP(munmap),
- REAL_FUNC_NP(read),
- REAL_FUNC_NP(ioctl),
+ //REAL_FUNC_NP(mmap),
+ //REAL_FUNC_NP(munmap),
+ //REAL_FUNC_NP(read),
+ //REAL_FUNC_NP(ioctl),
REAL_FUNC_NP(sigaction),
REAL_FUNC_NP(tcgetattr),
REAL_FUNC_NP(tcsetattr),
REAL_FUNC_NP(system),
// exec* - skipped
REAL_FUNC_NP(execve),
- REAL_FUNC_NP(chdir),
+ //REAL_FUNC_NP(chdir),
};
-#define open p_real_open
+//#define open p_real_open
#define fopen p_real_fopen
-#define mmap p_real_mmap
-#define munmap p_real_munmap
-#define read p_real_read
-#define ioctl p_real_ioctl
+//#define mmap p_real_mmap
+//#define munmap p_real_munmap
+//#define read p_real_read
+//#define ioctl p_real_ioctl
#define sigaction p_real_sigaction
#define tcgetattr p_real_tcgetattr
#define tcsetattr p_real_tcsetattr
#define system p_real_system
#define execve p_real_execve
-#define chdir p_real_chdir
+//#define chdir p_real_chdir
#undef MAKE_WRAP_SYM
#undef REAL_FUNC_NP
{
va_list ap;
mode_t mode;
+ long ret;
va_start(ap, flags);
mode = va_arg(ap, mode_t);
va_end(ap);
- return open(pathname, flags, mode);
+ ret = g_open_raw(pathname, flags, mode);
+ return g_syscall_error(ret);
}
FILE *real_fopen(const char *path, const char *mode)
return fopen(path, mode);
}
-void *real_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
+void *real_mmap(void *addr, size_t length, int prot, int flags,
+ int fd, off_t offset)
{
- return mmap(addr, length, prot, flags, fd, offset);
+ long ret = g_mmap2_raw(addr, length, prot, flags, fd, offset >> 12);
+ return (void *)g_syscall_error(ret);
}
int real_munmap(void *addr, size_t length)
{
- return munmap(addr, length);
+ return g_syscall_error(g_munmap_raw(addr, length));
}
int real_read(int fd, void *buf, size_t count)
{
- return read(fd, buf, count);
+ long ret = g_read_raw(fd, buf, count);
+ return g_syscall_error(ret);
}
-int real_ioctl(int d, int request, void *argp)
+int real_ioctl(int fd, int request, void *argp)
{
- return ioctl(d, request, argp);
+ long ret = g_ioctl_raw(fd, request, argp);
+ return g_syscall_error(ret);
+}
+
+int real_close(int fd)
+{
+ long ret = g_close_raw(fd);
+ return g_syscall_error(ret);
}
int real_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact)
int real_chdir(const char *path)
{
- return chdir(path);
+ long ret = g_chdir_raw(path);
+ return g_syscall_error(ret);
+}
+
+void real_sleep(unsigned int seconds)
+{
+ struct timespec ts = { seconds, 0 };
+ g_nanosleep_raw(&ts, NULL);
+}
+
+void real_usleep(unsigned int usec)
+{
+ struct timespec ts = { usec / 1000000, usec % 1000000 };
+ g_nanosleep_raw(&ts, NULL);
+}
+
+void real_exit(int status)
+{
+ g_exit_group_raw(status);
}
// vim:shiftwidth=2:expandtab
" ldmfd sp!, {r1-r3,r12,lr,pc}\n" \
);
-SVC_CMN_R0_MOV_R4_WRAPPER(hw_read, w_read)
-SVC_CMN_R0_MOV_R4_WRAPPER(hw_ioctl, w_ioctl)
+SVC_CMN_R0_MOV_R4_WRAPPER(hw_read, w_read_raw)
+SVC_CMN_R0_MOV_R4_WRAPPER(hw_ioctl, w_ioctl_raw)
#define PATCH_(p, f, t) { sig_##p, sig_mask_##p, ARRAY_SIZE(sig_##p), t, f, #p }
#define PATCH(f) PATCH_(f, w_##f, 0)
#include <signal.h>
#include <termios.h>
+#include "llibc.h"
+
+#define printf(fmt, ...) \
+ g_fprintf(1, fmt, ##__VA_ARGS__)
int real_open(const char *pathname, int flags, ...);
FILE *real_fopen(const char *path, const char *mode);
int real_munmap(void *addr, size_t length);
int real_read(int fd, void *buf, size_t count);
int real_ioctl(int fd, int request, void *argp);
+int real_close(int fd);
int real_sigaction(int signum, const struct sigaction *act, struct sigaction *oldact);
typedef struct sigaction sigaction_t;
int real_tcgetattr(int fd, struct termios *termios_p);
// exec* - skipped
int real_execve(const char *filename, char *const argv[], char *const envp[]);
int real_chdir(const char *path);
+void real_sleep(unsigned int seconds);
+void real_usleep(unsigned int usec);
+void __attribute__((noreturn))
+ real_exit(int status);
#define open real_open
#define fopen real_fopen
#define munmap real_munmap
#define read real_read
#define ioctl real_ioctl
+#define close real_close
#define sigaction real_sigaction
#define tcgetattr real_tcgetattr
#define tcsetattr real_tcsetattr
#define execvp real_execvp
#define execve real_execve
#define chdir real_chdir
+#define sleep real_sleep
+#define usleep real_usleep
+#define exit real_exit
stmfd sp!, {r4, r5, r6, lr}
ldmia r12, {r4, r5, r6}
swi \nr
- stmfd sp!, {r4, r5, r6, pc}
+ ldmfd sp!, {r4, r5, r6, pc}
.endm
raw_syscall_easy g_open_raw, __NR_open
raw_syscall_easy g_read_raw, __NR_read
raw_syscall_easy g_write_raw, __NR_write
+raw_syscall g_mmap2_raw, __NR_mmap2
+raw_syscall_easy g_munmap_raw, __NR_munmap
+raw_syscall_easy g_ioctl_raw, __NR_ioctl
+raw_syscall_easy g_close_raw, __NR_close
+raw_syscall_easy g_chdir_raw, __NR_chdir
raw_syscall_easy g_futex_raw, __NR_futex
raw_syscall_easy g_nanosleep_raw, __NR_nanosleep
raw_syscall_easy g_clock_gettime_raw, __NR_clock_gettime
raw_syscall_easy g_rt_sigprocmask_raw, __NR_rt_sigprocmask
-
+raw_syscall_easy g_exit_group_raw, __NR_exit_group
// arg6 is func ptr, for convenience
long g_clone(unsigned long flags, void *child_stack, ...);
-int g_syscall_error(long kret);
+long g_syscall_error(long kret);
// raw - no errno handling
long g_open_raw(const char *pathname, int flags, ...);
long g_read_raw(int fd, void *buf, size_t count);
long g_write_raw(int fd, const void *buf, size_t count);
+long g_mmap2_raw(void *addr, size_t length, int prot, int flags,
+ int fd, off_t offset);
+long g_munmap_raw(void *addr, size_t length);
+long g_ioctl_raw(int fd, unsigned long request, ...);
+long g_close_raw(int fd);
+long g_chdir_raw(const char *path);
long g_futex_raw(int *uaddr, int op, int val,
const struct timespec *timeout);
long g_nanosleep_raw(const struct timespec *req, struct timespec *rem);
long g_clock_gettime_raw(int clk_id, const struct timespec *tp);
long g_rt_sigprocmask_raw(int how, const void *set, void *oldset,
- size_t sigsetsize);
+ size_t sigsetsize);
+long __attribute__((noreturn))
+ g_exit_group_raw(int status);
+