wip, some dynamic stuff works
authornotaz <notaz@pixelinis>
Tue, 27 Jul 2010 15:20:56 +0000 (18:20 +0300)
committernotaz <notaz@pixelinis>
Wed, 28 Jul 2010 13:16:56 +0000 (16:16 +0300)
loader/Makefile
loader/dl.c [new file with mode: 0644]
loader/emu.c
loader/ginge_dyn.sh [new file with mode: 0755]
loader/header.h
loader/host_pnd.c
loader/loader.c
loader/override.c [new file with mode: 0644]
loader/patches.c
loader/realfuncs.h [new file with mode: 0644]
loader/tools/static.c

index d50bcd5..423e541 100644 (file)
@@ -2,12 +2,15 @@ ARCH ?= arm
 CROSS_COMPILE ?= arm-linux-
 CC = $(CROSS_COMPILE)gcc
 AS = $(CROSS_COMPILE)as
 CROSS_COMPILE ?= arm-linux-
 CC = $(CROSS_COMPILE)gcc
 AS = $(CROSS_COMPILE)as
-CFLAGS += -Wall -ggdb
-LDFLAGS += -static -ggdb -lpthread -lrt
+CFLAGS += -Wall -ggdb -DLOADER
+LDFLAGS += -ggdb -lpthread -lrt
 ifndef DEBUG
 CFLAGS += -O2 -fno-strict-aliasing
 LDFLAGS += -s -O2
 endif
 ifndef DEBUG
 CFLAGS += -O2 -fno-strict-aliasing
 LDFLAGS += -s -O2
 endif
+ifdef DBG
+CFLAGS += -DDBG=$(DBG)
+endif
 
 ifeq "$(ARCH)" "ia32"
 ARCH = ia32
 
 ifeq "$(ARCH)" "ia32"
 ARCH = ia32
@@ -22,13 +25,28 @@ endif
 
 vpath %.c = ../common/
 
 
 vpath %.c = ../common/
 
-TARGET = ginge_sloader
-OBJ += loader.o loader_$(ARCH).o patches.o emu.o host_fb.o host_pnd.o
+TARGET_S = ginge_sloader
+TARGET_D = ginge_dyn
+
+OBJ += emu.o host_fb.o host_pnd.o cmn.o
+OBJ_S += $(OBJ) loader.o loader_$(ARCH).o patches.o
+OBJ_D += $(OBJ) dl.o
+
+all: $(TARGET_S) $(TARGET_D)
 
 
-$(TARGET): LDFLAGS += -Wl,-T script_$(ARCH).lds
+$(TARGET_S): LDFLAGS += -Wl,-T script_$(ARCH).lds
+$(TARGET_D): LDFLAGS += -ldl
 
 
-$(TARGET): $(OBJ)
-       $(CC) -o $@ $^ $(LDFLAGS)
+$(TARGET_S): $(OBJ_S)
+       $(CC) -o $@ $^ -static $(LDFLAGS)
+
+$(TARGET_D): $(OBJ_D)
+       $(CC) -o $@ $^ -shared $(LDFLAGS)
 
 clean:
 
 clean:
-       $(RM) $(TARGET) $(OBJ)
+       $(RM) $(TARGET_S) $(TARGET_D) $(OBJ_S) $(OBJ_D)
+
+# basic deps
+dl.o patches.o: override.c
+*.o: header.h
+
diff --git a/loader/dl.c b/loader/dl.c
new file mode 100644 (file)
index 0000000..154e012
--- /dev/null
@@ -0,0 +1,67 @@
+// vim:shiftwidth=2:expandtab
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/mman.h>
+#include <dlfcn.h>
+#include "header.h"
+
+#define DL
+#include "override.c"
+
+__attribute__((constructor))
+static void ginge_init(void)
+{
+  unsigned int lowest_segment = (unsigned int)-1;
+  unsigned int start, end;
+  int i, ret;
+  FILE *f;
+
+  for (i = 0; i < ARRAY_SIZE(real_funcs_np); i++) {
+    *real_funcs_np[i].func_ptr = dlsym(RTLD_NEXT, real_funcs_np[i].name);
+    if (*real_funcs_np[i].func_ptr == NULL) {
+      fprintf(stderr, "dlsym %s: %s\n", real_funcs_np[i].name, dlerror());
+      exit(1);
+    }
+    // dbg("%p %s\n", *real_funcs_np[i].func_ptr, real_funcs_np[i].name);
+  }
+
+  f = fopen("/proc/self/maps", "r");
+  if (f == NULL) {
+    perror("open /proc/self/maps");
+    exit(1);
+  }
+
+  ret = fscanf(f, "%x-%x %*s %*s %*s %*s %*s\n", &start, &end);
+  if (ret != 2) {
+    perror("parse maps");
+    exit(1);
+  }
+  lowest_segment = start;
+
+  // assume first entry lists program's text section.
+  // unprotect it in case we need some patching.
+  ret = mprotect((void *)start, end - start, PROT_READ|PROT_WRITE|PROT_EXEC);
+  if (ret != 0)
+    perror("warning: mprotect");
+
+  while (1) {
+    ret = fscanf(f, "%x-%*s %*s %*s %*s %*s %*s\n", &start);
+    if (ret <= 0)
+      break;
+
+    if (start < lowest_segment)
+      lowest_segment = start;
+  }
+
+#if 0
+  rewind(f);
+  char buff[256];
+  while (fgets(buff, sizeof(buff), f))
+    fputs(buff, stdout);
+#endif
+  fclose(f);
+
+  emu_init((void *)lowest_segment);
+}
+
index 3db8053..0d908d7 100644 (file)
 #include <errno.h>
 #include <time.h>
 #include <sys/resource.h>
 #include <errno.h>
 #include <time.h>
 #include <sys/resource.h>
+#include <sys/ioctl.h>
+#include <linux/soundcard.h>
+#include <linux/fb.h>
 
 #include "header.h"
 
 #include "header.h"
+#include "../common/host_fb.h"
+#include "../common/cmn.h"
 #include "sys_cacheflush.h"
 #include "sys_cacheflush.h"
+#include "realfuncs.h"
 
 
-//#define LOG_IO
-//#define LOG_IO_UNK
+#if (dbg & 2)
+#define LOG_IO_UNK
+#endif
+#if (dbg & 4)
+#define LOG_IO
+#endif
 //#define LOG_SEGV
 
 #ifdef LOG_IO
 //#define LOG_SEGV
 
 #ifdef LOG_IO
@@ -754,7 +764,7 @@ static void segv_sigaction(int num, siginfo_t *info, void *ctx)
   u32 *regs = (u32 *)&context->uc_mcontext.arm_r0;
   u32 *pc = (u32 *)regs[15];
   struct op_context *op_ctx;
   u32 *regs = (u32 *)&context->uc_mcontext.arm_r0;
   u32 *pc = (u32 *)regs[15];
   struct op_context *op_ctx;
-  int lp_size;
+  int i, lp_size;
 
   if (((regs[15] ^ (u32)&segv_sigaction) & 0xff000000) == 0 ||         // PC is in our segment or
       (((regs[15] ^ (u32)g_linkpage) & ~(LINKPAGE_ALLOC - 1)) == 0) || // .. in linkpage
 
   if (((regs[15] ^ (u32)&segv_sigaction) & 0xff000000) == 0 ||         // PC is in our segment or
       (((regs[15] ^ (u32)g_linkpage) & ~(LINKPAGE_ALLOC - 1)) == 0) || // .. in linkpage
@@ -762,6 +772,8 @@ static void segv_sigaction(int num, siginfo_t *info, void *ctx)
   {
     // real crash - time to die
     err("segv %d %p @ %08x\n", info->si_code, info->si_addr, regs[15]);
   {
     // real crash - time to die
     err("segv %d %p @ %08x\n", info->si_code, info->si_addr, regs[15]);
+    for (i = 0; i < 8; i++)
+      err(" r%d=%08x r%2d=%08x\n", i, regs[i], i+8, regs[i+8]);
     signal(num, SIG_DFL);
     raise(num);
     return;
     signal(num, SIG_DFL);
     raise(num);
     return;
@@ -808,7 +820,7 @@ static void segv_sigaction(int num, siginfo_t *info, void *ctx)
 
 void emu_init(void *map_bottom)
 {
 
 void emu_init(void *map_bottom)
 {
-  struct sigaction segv_action = {
+  sigaction_t segv_action = {
     .sa_sigaction = segv_sigaction,
     .sa_flags = SA_SIGINFO,
   };
     .sa_sigaction = segv_sigaction,
     .sa_flags = SA_SIGINFO,
   };
@@ -822,7 +834,8 @@ void emu_init(void *map_bottom)
   *((char *)g_handler_stack_end - 4096) = 1;
 
   g_linkpage = (void *)(((u32)map_bottom - LINKPAGE_ALLOC) & ~0xfff);
   *((char *)g_handler_stack_end - 4096) = 1;
 
   g_linkpage = (void *)(((u32)map_bottom - LINKPAGE_ALLOC) & ~0xfff);
-  pret = mmap(g_linkpage, LINKPAGE_ALLOC, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
+  pret = mmap(g_linkpage, LINKPAGE_ALLOC, PROT_READ|PROT_WRITE,
+              MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
   if (pret != g_linkpage) {
     perror(PFX "mmap linkpage");
     exit(1);
   if (pret != g_linkpage) {
     perror(PFX "mmap linkpage");
     exit(1);
@@ -833,7 +846,7 @@ void emu_init(void *map_bottom)
   // host stuff
   ret = host_video_init(&host_stride, 0);
   if (ret != 0) {
   // host stuff
   ret = host_video_init(&host_stride, 0);
   if (ret != 0) {
-    err("can't alloc screen\n");
+    err("can't init video\n");
     exit(1);
   }
   host_screen = host_video_flip();
     exit(1);
   }
   host_screen = host_video_flip();
@@ -847,6 +860,7 @@ void emu_init(void *map_bottom)
 
   // mmsp2 defaults
   mmsp2.mlc_stl_adr = 0x03101000; // fb2 is at 0x03381000
 
   // mmsp2 defaults
   mmsp2.mlc_stl_adr = 0x03101000; // fb2 is at 0x03381000
+  mmsp2.mlc_stl_cntl = 0x4ab; // 16bpp, region 1 active
 
   sigemptyset(&segv_action.sa_mask);
   sigaction(SIGSEGV, &segv_action, NULL);
 
   sigemptyset(&segv_action.sa_mask);
   sigaction(SIGSEGV, &segv_action, NULL);
@@ -937,14 +951,11 @@ void *emu_do_mmap(unsigned int length, int prot, int flags, int fd, unsigned int
   if (fd == FAKEDEV_FB1)
     return emu_mmap_dev(length, prot, flags, offset + 0x03381000);
 
   if (fd == FAKEDEV_FB1)
     return emu_mmap_dev(length, prot, flags, offset + 0x03381000);
 
-  err("bad/ni mmap(?, %d, %x, %x, %d, %08x)", length, prot, flags, fd, offset);
+  err("bad/ni mmap(?, %d, %x, %x, %d, %08x)\n", length, prot, flags, fd, offset);
   errno = EINVAL;
   return MAP_FAILED;
 }
 
   errno = EINVAL;
   return MAP_FAILED;
 }
 
-#include <sys/ioctl.h>
-#include <linux/soundcard.h>
-
 static int emu_sound_ioctl(int fd, int request, void *argp)
 {
   int *arg = argp;
 static int emu_sound_ioctl(int fd, int request, void *argp)
 {
   int *arg = argp;
@@ -981,17 +992,18 @@ static int emu_sound_ioctl(int fd, int request, void *argp)
   return ioctl(fd, request, argp);
 }
 
   return ioctl(fd, request, argp);
 }
 
-#include <linux/fb.h>
-
 int emu_do_ioctl(int fd, int request, void *argp)
 {
   if (fd == emu_interesting_fds[IFD_SOUND].fd)
     return emu_sound_ioctl(fd, request, argp);
 
 int emu_do_ioctl(int fd, int request, void *argp)
 {
   if (fd == emu_interesting_fds[IFD_SOUND].fd)
     return emu_sound_ioctl(fd, request, argp);
 
-  if (argp == NULL)
-    goto fail;
+  switch (fd) {
+  /* *********************** */
+  case FAKEDEV_FB0:
+  case FAKEDEV_FB1:
+    if (argp == NULL)
+      goto fail;
 
 
-  if (fd == FAKEDEV_FB0 || fd == FAKEDEV_FB1) {
     switch (request) {
       case FBIOGET_FSCREENINFO: {
         struct fb_fix_screeninfo *fix = argp;
     switch (request) {
       case FBIOGET_FSCREENINFO: {
         struct fb_fix_screeninfo *fix = argp;
@@ -1000,15 +1012,17 @@ int emu_do_ioctl(int fd, int request, void *argp)
         strcpy(fix->id, "mmsp2_RGB0");
         fix->type         = FB_TYPE_PACKED_PIXELS;
         fix->accel        = FB_ACCEL_NONE;
         strcpy(fix->id, "mmsp2_RGB0");
         fix->type         = FB_TYPE_PACKED_PIXELS;
         fix->accel        = FB_ACCEL_NONE;
+        fix->visual       = FB_VISUAL_TRUECOLOR;
+        fix->line_length  = 320*2;
         fix->smem_start   = (fd == FAKEDEV_FB0) ? 0x03101000 : 0x03381000;
         fix->smem_len     = 320*240*2;
         return 0;
       }
       case FBIOGET_VSCREENINFO: {
         struct fb_var_screeninfo *var = argp;
         fix->smem_start   = (fd == FAKEDEV_FB0) ? 0x03101000 : 0x03381000;
         fix->smem_len     = 320*240*2;
         return 0;
       }
       case FBIOGET_VSCREENINFO: {
         struct fb_var_screeninfo *var = argp;
-        static const struct fb_bitfield fbb_red   = { offset: 0,  length: 4, };
-        static const struct fb_bitfield fbb_green = { offset: 0,  length: 4, };
-        static const struct fb_bitfield fbb_blue  = { offset: 0,  length: 4, };
+        static const struct fb_bitfield fbb_red   = { offset: 11, length: 5, };
+        static const struct fb_bitfield fbb_green = { offset:  5, length: 6, };
+        static const struct fb_bitfield fbb_blue  = { offset:  0, length: 5, };
 
         memset(var, 0, sizeof(*var));
         var->activate     = FB_ACTIVATE_NOW;
 
         memset(var, 0, sizeof(*var));
         var->activate     = FB_ACTIVATE_NOW;
@@ -1025,12 +1039,79 @@ int emu_do_ioctl(int fd, int request, void *argp)
         var->blue         = fbb_blue;
         return 0;
       }
         var->blue         = fbb_blue;
         return 0;
       }
+      case FBIOPUT_VSCREENINFO: {
+        struct fb_var_screeninfo *var = argp;
+        dbg(" put vscreen: %dx%d@%d\n", var->xres, var->yres, var->bits_per_pixel);
+        if (var->xres != 320 || var->yres != 240 || var->bits_per_pixel != 16)
+          return -1;
+        return 0;
+      }
     }
     }
+
+  /* *********************** */
+  case FAKEDEV_TTY0:
+    // fake tty0 to make GPH SDL happy
+    if (request == 0x4b46) // KDGKBENT
+      return -1;
+    return 0;
   }
 
 fail:
   }
 
 fail:
-  err("bad/ni ioctl(%d, %08x, %p)", fd, request, argp);
+  err("bad/ni ioctl(%d, %08x, %p)\n", fd, request, argp);
   errno = EINVAL;
   return -1;
 }
 
   errno = EINVAL;
   return -1;
 }
 
+static const struct {
+  const char *from;
+  const char *to;
+} path_map[] = {
+  { "/mnt/tmp/", "/tmp/" },
+};
+
+// FIXME: threads..
+static const char *wrap_path(const char *path)
+{
+  static char tmp_path[512];
+  int i, len;
+
+  // do only path mapping for now
+  for (i = 0; i < ARRAY_SIZE(path_map); i++) {
+    len = strlen(path_map[i].from);
+    if (strncmp(path, path_map[i].from, len) == 0) {
+      snprintf(tmp_path, sizeof(tmp_path), "%s%s", path_map[i].to, path + len);
+      dbg("mapped path \"%s\" -> \"%s\"\n", path, tmp_path);
+      return tmp_path;
+    }
+  }
+
+  return path;
+}
+
+void *emu_do_fopen(const char *path, const char *mode)
+{
+  return fopen(wrap_path(path), mode);
+}
+
+int emu_do_system(const char *command)
+{
+  static char tmp_path[512];
+  char *p, *p2;
+
+  if (command == NULL)
+    return -1;
+
+  // pass through stuff in PATH
+  p = strchr(command, ' ');
+  p2 = strchr(command, '/');
+  if (p2 == NULL || (p != NULL && p2 > p))
+    return system(command);
+
+  make_local_path(tmp_path, sizeof(tmp_path), "ginge_prep");
+  p = tmp_path + strlen(tmp_path);
+
+  snprintf(p, sizeof(tmp_path) - (p - tmp_path), " %s", wrap_path(command));
+  dbg("system: \"%s\"\n", tmp_path);
+  return system(tmp_path);
+}
+
diff --git a/loader/ginge_dyn.sh b/loader/ginge_dyn.sh
new file mode 100755 (executable)
index 0000000..32c12f8
--- /dev/null
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+root=$1
+shift
+
+loader="${root}lib/ld-linux.so.2"
+export LD_LIBRARY_PATH="$LD_LIBRARY_PATH:${root}lib"
+export LD_PRELOAD="${root}ginge_dyn"
+
+export GINGE_ROOT="${root}"
+
+exec "${loader}" "$@"
index f2f6a45..8da398e 100644 (file)
@@ -1,9 +1,10 @@
-#include "../common/host_fb.h"
+#ifndef INCLUDE_sQt5fY5eUJn5tKV0IBTDxK0zqQutTqTp
+#define INCLUDE_sQt5fY5eUJn5tKV0IBTDxK0zqQutTqTp 1
 
 #define PFX "ginge: "
 #define err(f, ...) fprintf(stderr, PFX f, ##__VA_ARGS__)
 #define log(f, ...) fprintf(stdout, PFX f, ##__VA_ARGS__)
 
 #define PFX "ginge: "
 #define err(f, ...) fprintf(stderr, PFX f, ##__VA_ARGS__)
 #define log(f, ...) fprintf(stdout, PFX f, ##__VA_ARGS__)
-#if 1
+#ifdef DBG
 #define dbg log
 #define dbg_c printf
 #else
 #define dbg log
 #define dbg_c printf
 #else
@@ -22,12 +23,14 @@ enum {
        IFD_SOUND = 0,
 };
 
        IFD_SOUND = 0,
 };
 
+// note: __FD_SETSIZE is 1024, fd_set stuff will crash if made larger
 enum {
 enum {
-  FAKEDEV_MEM = 10001,
+  FAKEDEV_MEM = 1001,
   FAKEDEV_GPIO,
   FAKEDEV_FB0,
   FAKEDEV_FB1,
   FAKEDEV_MMUHACK,
   FAKEDEV_GPIO,
   FAKEDEV_FB0,
   FAKEDEV_FB1,
   FAKEDEV_MMUHACK,
+  FAKEDEV_TTY0,
   FAKEDEV_FD_BOUNDARY,
 };
 
   FAKEDEV_FD_BOUNDARY,
 };
 
@@ -37,6 +40,8 @@ void  emu_init(void *map_bottom);
 void *emu_do_mmap(unsigned int length, int prot, int flags, int fd, unsigned int offset);
 int   emu_do_ioctl(int fd, int request, void *argp);
 int   emu_read_gpiodev(void *buf, int count);
 void *emu_do_mmap(unsigned int length, int prot, int flags, int fd, unsigned int offset);
 int   emu_do_ioctl(int fd, int request, void *argp);
 int   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   host_read_btns(void);
 
 
 int   host_read_btns(void);
 
@@ -47,3 +52,4 @@ enum  { GP2X_UP = 0,      GP2X_LEFT = 2,      GP2X_DOWN = 4,  GP2X_RIGHT = 6,
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
 
 
 #define ARRAY_SIZE(x) (sizeof(x) / sizeof(x[0]))
 
+#endif /* INCLUDE_sQt5fY5eUJn5tKV0IBTDxK0zqQutTqTp */
index a3d4215..5c79b91 100644 (file)
@@ -11,6 +11,7 @@
 #include <linux/input.h>
 
 #include "header.h"
 #include <linux/input.h>
 
 #include "header.h"
+#include "realfuncs.h"
 
 static int ifds[2] = { -1, -1 };
 static int init_done;
 
 static int ifds[2] = { -1, -1 };
 static int init_done;
@@ -23,7 +24,7 @@ static void init(void)
 
   for (ifd = -1, i = 0; ifds[0] == -1 || ifds[1] == -1; i++) {
     snprintf(buff, sizeof(buff), "/dev/input/event%i", i);
 
   for (ifd = -1, i = 0; ifds[0] == -1 || ifds[1] == -1; i++) {
     snprintf(buff, sizeof(buff), "/dev/input/event%i", i);
-    ifd = open(buff, O_RDONLY | O_NONBLOCK);
+    ifd = open(buff, O_RDONLY | O_NONBLOCK, 0);
     if (ifd == -1)
       break;
 
     if (ifd == -1)
       break;
 
index df50542..28bdf8e 100644 (file)
@@ -6,6 +6,7 @@
 #include <sys/mman.h>
 
 #include "header.h"
 #include <sys/mman.h>
 
 #include "header.h"
+#include "realfuncs.h"
 
 #define CHECK_(val, fail_operator, expect, err_msg) \
   if (val fail_operator expect) { \
 
 #define CHECK_(val, fail_operator, expect, err_msg) \
   if (val fail_operator expect) { \
@@ -73,7 +74,7 @@ int main(int argc, char *argv[])
 
   for (i = 0; i < ARRAY_SIZE(maps); i++) {
     ret = fscanf(fi, "%lx-%lx %*s %*s %*s %*s %*s\n", &maps[i].start, &maps[i].end);
 
   for (i = 0; i < ARRAY_SIZE(maps); i++) {
     ret = fscanf(fi, "%lx-%lx %*s %*s %*s %*s %*s\n", &maps[i].start, &maps[i].end);
-    if (ret == 0)
+    if (ret <= 0)
       break;
     CHECK_EQ(ret, 2, "maps parse error");
   }
       break;
     CHECK_EQ(ret, 2, "maps parse error");
   }
diff --git a/loader/override.c b/loader/override.c
new file mode 100644 (file)
index 0000000..5a10193
--- /dev/null
@@ -0,0 +1,259 @@
+// vim:shiftwidth=2:expandtab
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <termios.h>
+
+#include "realfuncs.h"
+#include "header.h"
+
+#if (DBG & 1)
+#define strace printf
+#else
+#define strace(...)
+#endif
+
+#define UNUSED __attribute__((unused))
+
+static const struct dev_fd_t takeover_devs[] = {
+  { "/dev/mem",     FAKEDEV_MEM },
+  { "/dev/GPIO",    FAKEDEV_GPIO },
+  { "/dev/fb0",     FAKEDEV_FB0 },
+  { "/dev/fb/0",    FAKEDEV_FB0 },
+  { "/dev/fb1",     FAKEDEV_FB1 },
+  { "/dev/fb/1",    FAKEDEV_FB1 },
+  { "/dev/mmuhack", FAKEDEV_MMUHACK },
+  { "/dev/tty",     -1 }, // XXX hmh..
+  { "/dev/tty0",    FAKEDEV_TTY0 },
+};
+
+static int w_open(const char *pathname, int flags, mode_t mode)
+{
+  int i, ret;
+
+  for (i = 0; i < ARRAY_SIZE(takeover_devs); i++) {
+    if (strcmp(pathname, takeover_devs[i].name) == 0) {
+      ret = takeover_devs[i].fd;
+      break;
+    }
+  }
+
+  if (i == ARRAY_SIZE(takeover_devs))
+    ret = open(pathname, flags, mode);
+
+  if (ret >= 0) {
+    for (i = 0; emu_interesting_fds[i].name != NULL; i++) {
+      if (strcmp(pathname, emu_interesting_fds[i].name) == 0) {
+        emu_interesting_fds[i].fd = ret;
+        break;
+      }
+    }
+  }
+
+  strace("open(%s) = %d\n", pathname, ret);
+  return ret;
+}
+
+static void *w_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
+{
+  void *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);
+
+  // 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);
+  return ret;
+}
+#define w_mmap2 w_mmap
+
+static ssize_t w_read(int fd, void *buf, size_t count)
+{
+  ssize_t ret;
+  if (fd == FAKEDEV_GPIO)
+    ret = emu_read_gpiodev(buf, count);
+  else
+    ret = read(fd, buf, count);
+
+  //strace("read(%d, %p, %d) = %d\n", fd, buf, count, ret);
+  return ret;
+}
+
+static int w_ioctl(int fd, int request, void *argp)
+{
+  int 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);
+
+  strace("ioctl(%d, %08x, %p) = %d\n", fd, request, argp, ret);
+  return ret;
+}
+
+static int w_sigaction(int signum, const void *act, void *oldact)
+{
+  strace("sigaction(%d, %p, %p) = %d\n", signum, act, oldact, 0);
+  return 0;
+}
+
+/* dynamic only */
+static UNUSED int w_tcgetattr(int fd, struct termios *termios_p)
+{
+  int ret;
+  if (fd != FAKEDEV_TTY0)
+    ret = tcgetattr(fd, termios_p);
+  else
+    ret = 0;
+
+  strace("tcgetattr(%d, %p) = %d\n", fd, termios_p, ret);
+  return ret;
+}
+
+static UNUSED int w_tcsetattr(int fd, int optional_actions,
+                       const struct termios *termios_p)
+{
+  int ret;
+  if (fd != FAKEDEV_TTY0)
+    ret = tcsetattr(fd, optional_actions, termios_p);
+  else
+    ret = 0;
+
+  strace("tcsetattr(%d, %x, %p) = %d\n", fd, optional_actions, termios_p, ret);
+  return ret;
+}
+
+static UNUSED FILE *w_fopen(const char *path, const char *mode)
+{
+  FILE *ret = emu_do_fopen(path, mode);
+  strace("fopen(%s, %s) = %p\n", path, mode, ret);
+  return ret;
+}
+
+static UNUSED int w_system(const char *command)
+{
+  int ret = emu_do_system(command);
+  strace("system(%s) = %d\n", command, ret);
+  return ret;
+}
+
+#undef open
+#undef fopen
+#undef mmap
+#undef read
+#undef ioctl
+#undef sigaction
+#undef tcgetattr
+#undef tcsetattr
+#undef system
+
+#ifdef DL
+
+#define MAKE_WRAP_SYM(sym) \
+  /* alias wrap symbols to real names */ \
+  typeof(sym) sym __attribute__((alias("w_" #sym))); \
+  /* wrapper to real functions, to be set up on load */ \
+  static typeof(sym) *p_real_##sym
+
+MAKE_WRAP_SYM(open);
+MAKE_WRAP_SYM(fopen);
+MAKE_WRAP_SYM(mmap);
+MAKE_WRAP_SYM(read);
+MAKE_WRAP_SYM(ioctl);
+MAKE_WRAP_SYM(sigaction);
+MAKE_WRAP_SYM(tcgetattr);
+MAKE_WRAP_SYM(tcsetattr);
+MAKE_WRAP_SYM(system);
+typeof(mmap) mmap2 __attribute__((alias("w_mmap")));
+
+#define REAL_FUNC_NP(name) \
+  { #name, (void **)&p_real_##name }
+
+static const struct {
+  const char *name;
+  void **func_ptr;
+} real_funcs_np[] = {
+  REAL_FUNC_NP(open),
+  REAL_FUNC_NP(fopen),
+  REAL_FUNC_NP(mmap),
+  REAL_FUNC_NP(read),
+  REAL_FUNC_NP(ioctl),
+  REAL_FUNC_NP(sigaction),
+  REAL_FUNC_NP(tcgetattr),
+  REAL_FUNC_NP(tcsetattr),
+  REAL_FUNC_NP(system),
+};
+
+#define open p_real_open
+#define fopen p_real_fopen
+#define mmap p_real_mmap
+#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
+
+#undef MAKE_WRAP_SYM
+#undef REAL_FUNC_NP
+
+#endif
+
+// just call real funcs for static, pointer for dynamic
+int real_open(const char *pathname, int flags, mode_t mode)
+{
+  return open(pathname, flags, mode);
+}
+
+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)
+{
+  return mmap(addr, length, prot, flags, fd, offset);
+}
+
+int real_read(int fd, void *buf, size_t count)
+{
+  return read(fd, buf, count);
+}
+
+int real_ioctl(int d, int request, void *argp)
+{
+  return ioctl(d, request, argp);
+}
+
+int real_sigaction(int signum, const sigaction_t *act, sigaction_t *oldact)
+{
+  return sigaction(signum, act, oldact);
+}
+
+int real_tcgetattr(int fd, struct termios *termios_p)
+{
+  return tcgetattr(fd, termios_p);
+}
+
+int real_tcsetattr(int fd, int optional_actions,
+                       const struct termios *termios_p)
+{
+  return tcsetattr(fd, optional_actions, termios_p);
+}
+
+int real_system(const char *command)
+{
+  return system(command);
+}
index f7e0b11..7d8cf97 100644 (file)
@@ -1,21 +1,10 @@
 // vim:shiftwidth=2:expandtab
 #include <stdio.h>
 // vim:shiftwidth=2:expandtab
 #include <stdio.h>
-#include <string.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/mman.h>
-#include <unistd.h>
-#include <sys/ioctl.h>
 
 #include "header.h"
 #include "sys_cacheflush.h"
 
 
 #include "header.h"
 #include "sys_cacheflush.h"
 
-#if 0
-#define strace printf
-#else
-#define strace(...)
-#endif
+#include "override.c"
 
 // note: first mask must be always full for search algo
 static const unsigned int sig_mask_all[] = {
 
 // note: first mask must be always full for search algo
 static const unsigned int sig_mask_all[] = {
@@ -33,11 +22,11 @@ static const unsigned int sig_mmap[] = {
 };
 #define sig_mask_mmap sig_mask_all
 
 };
 #define sig_mask_mmap sig_mask_all
 
-static const unsigned int sig_mmap_[] = {
+static const unsigned int sig_mmap2[] = {
   0xe52d5004, 0xe59d5008, 0xe52d4004, 0xe59d4008,
   0xe1b0ca05, 0x1a000006, 0xe1a05625, 0xef9000c0
 };
   0xe52d5004, 0xe59d5008, 0xe52d4004, 0xe59d4008,
   0xe1b0ca05, 0x1a000006, 0xe1a05625, 0xef9000c0
 };
-#define sig_mask_mmap_ sig_mask_all
+#define sig_mask_mmap2 sig_mask_all
 
 static const unsigned int sig_read[] = {
   0xe59fc080, 0xe59cc000, 0xe33c0000, 0x1a000003, 0xef900003
 
 static const unsigned int sig_read[] = {
   0xe59fc080, 0xe59cc000, 0xe33c0000, 0x1a000003, 0xef900003
@@ -56,89 +45,6 @@ static const unsigned int sig_mask_sigaction[] = {
   0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000
 };
 
   0xffffffff, 0xffffffff, 0xffffffff, 0xff000000, 0xff000000
 };
 
-static const struct dev_fd_t takeover_devs[] = {
-  { "/dev/mem",     FAKEDEV_MEM },
-  { "/dev/GPIO",    FAKEDEV_GPIO },
-  { "/dev/fb0",     FAKEDEV_FB0 },
-  { "/dev/fb/0",    FAKEDEV_FB0 },
-  { "/dev/fb1",     FAKEDEV_FB1 },
-  { "/dev/fb/1",    FAKEDEV_FB1 },
-  { "/dev/mmuhack", FAKEDEV_MMUHACK },
-};
-
-static int w_open(const char *pathname, int flags, mode_t mode)
-{
-  int i, ret;
-
-  for (i = 0; i < ARRAY_SIZE(takeover_devs); i++) {
-    if (strcmp(pathname, takeover_devs[i].name) == 0) {
-      ret = takeover_devs[i].fd;
-      break;
-    }
-  }
-
-  if (i == ARRAY_SIZE(takeover_devs))
-    ret = open(pathname, flags, mode);
-
-  if (ret >= 0) {
-    for (i = 0; emu_interesting_fds[i].name != NULL; i++) {
-      if (strcmp(pathname, emu_interesting_fds[i].name) == 0) {
-        emu_interesting_fds[i].fd = ret;
-        break;
-      }
-    }
-  }
-
-  strace("open(%s) = %d\n", pathname, ret);
-  return ret;
-}
-
-static void *w_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset)
-{
-  void *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);
-
-  // threads are using heap before they mmap their stack
-  // printf needs valid stack for pthtead/errno
-  if (((long)&ret & 0xf0000000) == 0xb0000000)
-    strace("mmap(%p, %x, %x, %x, %d, %lx) = %p\n", addr, length, prot, flags, fd, (long)offset, ret);
-  return ret;
-}
-#define w_mmap_ w_mmap
-
-static ssize_t w_read(int fd, void *buf, size_t count)
-{
-  ssize_t ret;
-  if (fd != FAKEDEV_GPIO)
-    return read(fd, buf, count);
-
-  ret = emu_read_gpiodev(buf, count);
-  //strace("read(%d, %p, %d) = %d\n", fd, buf, count, ret);
-  return ret;
-}
-
-static int w_ioctl(int fd, int request, void *argp)
-{
-  int 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);
-
-  strace("ioctl(%d, %08x, %p) = %d\n", fd, request, argp, ret);
-  return ret;
-}
-
-static int w_sigaction(int signum, const void *act, void *oldact)
-{
-  strace("sigaction(%d, %p, %p) = %d\n", signum, act, oldact, 0);
-  return 0;
-}
 
 #define PATCH(f) { sig_##f, sig_mask_##f, ARRAY_SIZE(sig_##f), w_##f }
 
 
 #define PATCH(f) { sig_##f, sig_mask_##f, ARRAY_SIZE(sig_##f), w_##f }
 
@@ -150,7 +56,7 @@ static const struct {
 } patches[] = {
   PATCH(open),
   PATCH(mmap),
 } patches[] = {
   PATCH(open),
   PATCH(mmap),
-  PATCH(mmap_), // mmap using mmap2 syscall
+  PATCH(mmap2), // mmap2 syscall
   PATCH(read),
   PATCH(ioctl),
   PATCH(sigaction),
   PATCH(read),
   PATCH(ioctl),
   PATCH(sigaction),
diff --git a/loader/realfuncs.h b/loader/realfuncs.h
new file mode 100644 (file)
index 0000000..4bca950
--- /dev/null
@@ -0,0 +1,33 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <sys/ioctl.h>
+#include <signal.h>
+#include <termios.h>
+
+
+int   real_open(const char *pathname, int flags, mode_t mode);
+FILE *real_fopen(const char *path, const char *mode);
+void *real_mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
+int   real_read(int fd, void *buf, size_t count);
+int   real_ioctl(int fd, int request, void *argp);
+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);
+int   real_tcsetattr(int fd, int optional_actions, const struct termios *termios_p);
+int   real_system(const char *command);
+
+#define open real_open
+#define fopen real_fopen
+#define mmap real_mmap
+#define read real_read
+#define ioctl real_ioctl
+#define sigaction real_sigaction
+#define tcgetattr real_tcgetattr
+#define tcsetattr real_tcsetattr
+#define system real_system
+
index 50013c7..257a147 100644 (file)
@@ -1,16 +1,31 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <stdio.h>
 #include <stdlib.h>
+#include <string.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <sys/mman.h>
 #include <sys/ioctl.h>
 #include <signal.h>
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <fcntl.h>
 #include <sys/mman.h>
 #include <sys/ioctl.h>
 #include <signal.h>
+#include <termios.h>
+
+static int open_(const char *name)
+{
+       int fd = open(name, O_RDWR);
+       if (fd < 0) {
+               fprintf(stderr, "%s: ", name);
+               perror("open");
+               return 1;
+       }
+
+       return fd;
+}
 
 int main(int argc, char *argv[])
 {
        volatile void *memregs;
 
 int main(int argc, char *argv[])
 {
        volatile void *memregs;
-       int memdev;
+       void *fbmem;
+       int memdev, fbdev;
        int i;
 
        printf("hi, home=%s\n", getenv("HOME"));
        int i;
 
        printf("hi, home=%s\n", getenv("HOME"));
@@ -18,21 +33,25 @@ int main(int argc, char *argv[])
        for (i = 0; i < argc; i++)
                printf("%d \"%s\"\n", i, argv[i]);
 
        for (i = 0; i < argc; i++)
                printf("%d \"%s\"\n", i, argv[i]);
 
-       memdev = open("/dev/mem", O_RDWR);
-       if (memdev < 0) {
-               perror("open");
-               return 1;
-       }
+       memdev = open_("/dev/mem");
+       fbdev = open_("/dev/fb0");
 
        memregs = mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0xc0000000);
 
        memregs = mmap(NULL, 0x10000, PROT_READ|PROT_WRITE, MAP_SHARED, memdev, 0xc0000000);
+       fbmem = mmap(NULL, 320*240*2, PROT_READ|PROT_WRITE, MAP_SHARED, fbdev, 0);
+
        ioctl(-1, 0);
        signal(7, SIG_DFL);
        ioctl(-1, 0);
        signal(7, SIG_DFL);
+//     tcgetattr(-1, NULL);
+//     tcsetattr(-1, 0, NULL);
 
 
+#if 1
        for (i = 0; i < 2; i++)
                printf("%02x %04x %08x\n", ((char *)memregs)[0x2011],
                        ((short *)memregs)[0x1198/2], ((int *)memregs)[0xbcdc/4]);
        for (i = 0; i < 2; i++)
                printf("%02x %04x %08x\n", ((char *)memregs)[0x2011],
                        ((short *)memregs)[0x1198/2], ((int *)memregs)[0xbcdc/4]);
+#endif
+       memset(fbmem, 0xff, 320*240*2);
 
 
-       //sleep(1000);
+       sleep(10);
 
        return 0;
 }
 
        return 0;
 }