X-Git-Url: https://git.zerfleddert.de/cgi-bin/gitweb.cgi/usb-driver/blobdiff_plain/b05f6dfed563db7c6d89e60d0fcf4d5bf8c03867..HEAD:/usb-driver.c diff --git a/usb-driver.c b/usb-driver.c index ff47ae3..3b8b51d 100644 --- a/usb-driver.c +++ b/usb-driver.c @@ -41,6 +41,7 @@ #include #include #include +#include #include #include #include "usb-driver.h" @@ -61,13 +62,15 @@ static int modules_read = 0; #define NO_WINDRVR 1 void hexdump(unsigned char *buf, int len, char *prefix) { - int i; + int i = 0; - fprintf(stderr, "%s ", prefix); - for(i=0; isi_addr); + errno = 0; + newmem = mmap(info->si_addr, 1, PROT_READ, MAP_PRIVATE|MAP_ANONYMOUS|MAP_FIXED, -1, 0); + if (newmem != info->si_addr) { + perror("libusb-driver.so: Can't map memory, crashing now"); + exit(EXIT_FAILURE); + } +} + +/* XilCommNS::CPortResources::Instance() */ +void* _ZN9XilCommNS14CPortResources8InstanceEv() { + static void* (*func) (void) = NULL; + char *filename = NULL; + void *ret; + int i; + + if (!func) { + struct sigaction act, oldact; + int sighand_installed = 0; + + func = (void* (*) (void)) dlsym(RTLD_NEXT, "_ZN9XilCommNS14CPortResources8InstanceEv"); + + DPRINTF("Installing signal-handler for SIGSEGV\n"); + bzero(&act, sizeof(struct sigaction)); + act.sa_sigaction = cpr_segv_handler; + act.sa_flags = SA_SIGINFO; + if (sigaction(SIGSEGV, &act, &oldact) == 0) { + sighand_installed = 1; + } + + DPRINTF("Searching for filename starting at %p\n", func); + for(i = 0; i < 32768; i++) { + if (!strcmp(((char*)func)+i, "/proc/sys/dev/parport/%s/base-addr")) { + filename = ((char*)func)+i; + DPRINTF("Filename found at offset %p\n", (void*)(filename - ((char*)func))); + break; + } + } + if (sighand_installed) { + DPRINTF("Restoring signal-handler for SIGSEGV\n"); + sigaction(SIGSEGV, &oldact, NULL); + } + if (!filename) + fprintf(stderr, "libusb-driver.so: Can't find memory to patch, parallel cables will probably not work!\n"); + } + + if (filename) { + long pagesize; + size_t protectlen; + void *start; + int len = strlen(filename) + 1; + int ret; + + pagesize = sysconf(_SC_PAGE_SIZE); + DPRINTF("You have %lu bytes sized pages!\n", pagesize); + + start = (void*)((long)filename & (~(pagesize-1))); + + protectlen = pagesize; + if ((long)(filename + len) > (long)(start + protectlen)) + protectlen += pagesize; + + DPRINTF("Unprotecting %zd bytes starting at %p\n", protectlen, start); + ret = mprotect(start, protectlen, PROT_READ|PROT_WRITE); + if (ret == -1) + perror("mprotect"); + + DPRINTF("Replacing %s with /dev/zero\n", filename); + strcpy(filename, "/dev/zero"); + + DPRINTF("Reprotecting %zd bytes starting at %p\n", protectlen, start); + ret = mprotect(start, protectlen, PROT_READ|PROT_EXEC); + if (ret == -1) + perror("mprotect"); + } + + DPRINTF("-> XilCommNS::CPortResources::Instance()\n"); + + ret = func(); + + DPRINTF("<- XilCommNS::CPortResources::Instance()\n"); + + return ret; +} + static void __attribute__ ((constructor)) libusbdriver_init(void) { int i; char buf[256]; @@ -689,14 +780,16 @@ static void __attribute__ ((constructor)) libusbdriver_init(void) { setenv("XIL_IMPACT_USE_WINDRIVER", "1", 1); #if __WORDSIZE == 32 - struct utsname un; - int ret; + { + struct utsname un; + int ret; - ret = uname(&un); + ret = uname(&un); - if (ret == 0 && (!strcmp(un.machine, "x86_64"))) { - DPRINTF("setting 32bit personality\n"); - (long)syscall(SYS_personality, PER_LINUX32); + if (ret == 0 && (!strcmp(un.machine, "x86_64"))) { + DPRINTF("setting 32bit personality\n"); + (long)syscall(SYS_personality, PER_LINUX32); + } } #endif }