diff -Nur linux-2.4.24.orig/arch/i386/kernel/entry.S linux-2.4.24-elf/arch/i386/kernel/entry.S --- linux-2.4.24.orig/arch/i386/kernel/entry.S 2003-06-13 16:51:29.000000000 +0200 +++ linux-2.4.24-elf/arch/i386/kernel/entry.S 2004-02-03 10:41:05.000000000 +0100 @@ -203,6 +203,13 @@ pushl %eax # save orig_eax SAVE_ALL GET_CURRENT(%ebx) +#if 0 + bt $15,flags(%ebx) # PF_TRANSEX + jnc .cont + call SYMBOL_NAME(syscall_trans) + movl ORIG_EAX(%esp),%eax +.cont: +#endif testb $0x02,tsk_ptrace(%ebx) # PT_TRACESYS jne tracesys cmpl $(NR_syscalls),%eax diff -Nur linux-2.4.24.orig/arch/i386/lib/usercopy.c linux-2.4.24-elf/arch/i386/lib/usercopy.c --- linux-2.4.24.orig/arch/i386/lib/usercopy.c 2003-06-13 16:51:29.000000000 +0200 +++ linux-2.4.24-elf/arch/i386/lib/usercopy.c 2004-02-03 11:11:19.000000000 +0100 @@ -70,6 +70,9 @@ #define __do_strncpy_from_user(dst,src,count,res) \ do { \ int __d0, __d1, __d2; \ + __typeof__(*(src)) *__src = (src); \ + __src = trans_address(__src); \ + __print_name("__do_strncpy_from_user"); \ __asm__ __volatile__( \ " testl %1,%1\n" \ " jz 2f\n" \ @@ -91,7 +94,7 @@ ".previous" \ : "=d"(res), "=c"(count), "=&a" (__d0), "=&S" (__d1), \ "=&D" (__d2) \ - : "i"(-EFAULT), "0"(count), "1"(count), "3"(src), "4"(dst) \ + : "i"(-EFAULT), "0"(count), "1"(count), "3"(__src), "4"(dst) \ : "memory"); \ } while (0) @@ -158,6 +161,9 @@ #define __do_clear_user(addr,size) \ do { \ int __d0; \ + __typeof__(*(addr)) *__addr = (addr); \ + __addr = trans_address(__addr); \ + __print_name("__do_clear_user"); \ __asm__ __volatile__( \ "0: rep; stosl\n" \ " movl %2,%0\n" \ @@ -173,7 +179,7 @@ " .long 1b,2b\n" \ ".previous" \ : "=&c"(size), "=&D" (__d0) \ - : "r"(size & 3), "0"(size / 4), "1"(addr), "a"(0)); \ + : "r"(size & 3), "0"(size / 4), "1"(__addr), "a"(0)); \ } while (0) /** @@ -225,9 +231,12 @@ */ long strnlen_user(const char *s, long n) { - unsigned long mask = -__addr_ok(s); + unsigned long mask; unsigned long res, tmp; + mask = -__addr_ok(s); // __addr_ok translates on its own + s = trans_address(s); + __print_name("strnlen_user"); __asm__ __volatile__( " testl %0, %0\n" " jz 3f\n" diff -Nur linux-2.4.24.orig/arch/i386/mm/fault.c linux-2.4.24-elf/arch/i386/mm/fault.c --- linux-2.4.24.orig/arch/i386/mm/fault.c 2002-11-29 00:53:09.000000000 +0100 +++ linux-2.4.24-elf/arch/i386/mm/fault.c 2004-01-23 14:47:57.000000000 +0100 @@ -33,7 +33,10 @@ int __verify_write(const void * addr, unsigned long size) { struct vm_area_struct * vma; - unsigned long start = (unsigned long) addr; + void *__addr = addr; + unsigned long start; + __addr = trans_address(__addr); + start = (unsigned long) __addr; if (!size) return 1; diff -Nur linux-2.4.24.orig/fs/binfmt_elf.c linux-2.4.24-elf/fs/binfmt_elf.c --- linux-2.4.24.orig/fs/binfmt_elf.c 2003-11-28 19:26:21.000000000 +0100 +++ linux-2.4.24-elf/fs/binfmt_elf.c 2004-02-03 10:42:51.000000000 +0100 @@ -33,6 +33,7 @@ #include #include #include +#include #include #include @@ -424,6 +425,60 @@ #define INTERPRETER_ELF 2 +struct reverse_trans_table_entry { + unsigned long old_start; + unsigned long old_end; + unsigned long new_start; + unsigned long padding; +} __attribute__((packed)); + +static inline void handle_reverse_trans_table(struct file *file, struct elf_shdr *elf_srtt) { + unsigned long offset; + unsigned long size; + struct reverse_trans_table_entry *rtte, *rtt; + struct address_trans_struct *address_trans; + int retval, i, n; + + offset = elf_srtt->sh_offset; + size = elf_srtt->sh_size; + + rtt = (struct reverse_trans_table_entry *)vmalloc(size); + if (!rtt) { + printk(KERN_WARNING "Could not allocate the reverse trans table\n"); + return; + } + + retval = kernel_read(file, offset, (char *) rtt, size); + if (retval < 0) + goto out_rtt; + + n = rtt->old_start; + address_trans = (struct address_trans_struct *)vmalloc(n * sizeof(struct address_trans_struct)); + if (!address_trans) { + printk(KERN_WARNING "Could not allocate the address trans table\n"); + goto out_rtt; + } + + current->mm->address_trans = address_trans; + + rtte = rtt + 1; // skip the first entry + for (i = 0; i < n; i++) { + address_trans->begin = rtte->old_start; + address_trans->end = rtte->old_end; + address_trans->offset = rtte->new_start - rtte->old_start; + rtte++; + address_trans++; + } + + current->mm->address_trans_count = n; + current->mm->count_trans = 0; + current->mm->do_trans_addr = (unsigned long *)elf_srtt->sh_addr; + current->mm->do_trans_addr++; +out_rtt: + vfree(rtt); +} + + static int load_elf_binary(struct linux_binprm * bprm, struct pt_regs * regs) { struct file *interpreter = NULL; /* to shut gcc up */ @@ -434,6 +489,8 @@ unsigned char ibcs2_interpreter = 0; unsigned long error; struct elf_phdr * elf_ppnt, *elf_phdata; + struct elf_shdr *elf_shdata, *elf_spnt, *elf_srtt; + char *shstrtab; unsigned long elf_bss, k, elf_brk; int elf_exec_fileno; int retval, i; @@ -477,10 +534,47 @@ retval = kernel_read(bprm->file, elf_ex.e_phoff, (char *) elf_phdata, size); if (retval < 0) goto out_free_ph; - + + /* Read in the section information */ + retval = -ENOMEM; + if (elf_ex.e_shentsize != sizeof(struct elf_shdr)) + goto out_free_ph; + if (elf_ex.e_shnum > 65536U / sizeof(struct elf_shdr)) + goto out_free_ph; + size = elf_ex.e_shnum * sizeof(struct elf_shdr); + elf_shdata = (struct elf_shdr *) kmalloc(size, GFP_KERNEL); + if (!elf_shdata) + goto out_free_ph; + + retval = kernel_read(bprm->file, elf_ex.e_shoff, (char *)elf_shdata, size); + + if (retval < 0) + goto out_free_sh; + + /* Read in the shstrtab: section header string table */ + retval = -ENOMEM; + size = elf_shdata[elf_ex.e_shstrndx].sh_size; + shstrtab = kmalloc(size, GFP_KERNEL); + if (!shstrtab) + goto out_free_sh; + + retval = kernel_read(bprm->file, elf_shdata[elf_ex.e_shstrndx].sh_offset, shstrtab, size); + + if (retval < 0) + goto out_free_stab; + + /* Find the sections we're interested in */ + elf_spnt = elf_shdata; + elf_srtt = NULL; + for (i = 0; i < elf_ex.e_shnum; i++) { + if (!strcmp(shstrtab + elf_spnt->sh_name, "ReverseTransTableSec")) + elf_srtt = elf_spnt; + elf_spnt++; + } + files = current->files; /* Refcounted so ok */ if(unshare_files() < 0) - goto out_free_ph; + goto out_free_stab; if (files == current->files) { put_files_struct(files); files = NULL; @@ -606,6 +700,15 @@ if (retval) goto out_free_dentry; + /* Handle our sections */ + current->flags &= ~PF_TRANSEX; + if (elf_srtt) { +#if 0 + printk(KERN_INFO "elf: ReverseTransTableSec section found.\n"); +#endif + handle_reverse_trans_table(bprm->file, elf_srtt); + } + /* Discard our unneeded old files struct */ if (files) { steal_locks(files); @@ -735,7 +838,9 @@ fput(interpreter); kfree(elf_interpreter); } - + + kfree(shstrtab); + kfree(elf_shdata); kfree(elf_phdata); if (interpreter_type != INTERPRETER_AOUT) @@ -809,6 +914,10 @@ start_thread(regs, elf_entry, bprm->p); if (current->ptrace & PT_PTRACED) send_sig(SIGTRAP, current, 0); + + if (current->mm->address_trans) + current->flags |= PF_TRANSEX; // kick in + retval = 0; out: return retval; @@ -827,6 +936,10 @@ put_files_struct(current->files); current->files = files; } +out_free_stab: + kfree(shstrtab); +out_free_sh: + kfree(elf_shdata); out_free_ph: kfree(elf_phdata); goto out; diff -Nur linux-2.4.24.orig/fs/namei.c linux-2.4.24-elf/fs/namei.c --- linux-2.4.24.orig/fs/namei.c 2003-08-25 13:44:43.000000000 +0200 +++ linux-2.4.24-elf/fs/namei.c 2004-01-23 14:47:57.000000000 +0100 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -105,12 +106,15 @@ { int retval; unsigned long len = PATH_MAX; + char *__filename = filename; - if ((unsigned long) filename >= TASK_SIZE) { + __filename = trans_address(__filename); + + if ((unsigned long) __filename >= TASK_SIZE) { if (!segment_eq(get_fs(), KERNEL_DS)) return -EFAULT; - } else if (TASK_SIZE - (unsigned long) filename < PATH_MAX) - len = TASK_SIZE - (unsigned long) filename; + } else if (TASK_SIZE - (unsigned long) __filename < PATH_MAX) + len = TASK_SIZE - (unsigned long) __filename; retval = strncpy_from_user((char *)page, filename, len); if (retval > 0) { diff -Nur linux-2.4.24.orig/include/asm-i386/uaccess.h linux-2.4.24-elf/include/asm-i386/uaccess.h --- linux-2.4.24.orig/include/asm-i386/uaccess.h 2003-06-13 16:51:38.000000000 +0200 +++ linux-2.4.24-elf/include/asm-i386/uaccess.h 2004-02-03 11:10:53.000000000 +0100 @@ -34,7 +34,12 @@ extern int __verify_write(const void *, unsigned long); -#define __addr_ok(addr) ((unsigned long)(addr) < (current->addr_limit.seg)) +#define __addr_ok(addr) ({ \ + __typeof__(*(addr)) *__addr = (addr); \ + __addr = trans_address(__addr); \ + __print_name("__addr_ok"); \ + (unsigned long)__addr < current->addr_limit.seg; \ +}) /* * Test whether a block of memory is a valid user space address. @@ -47,9 +52,12 @@ */ #define __range_ok(addr,size) ({ \ unsigned long flag,sum; \ + __typeof__(*(addr)) *__addr = (addr); \ + __addr = trans_address(__addr); \ + __print_name("__range_ok"); \ asm("addl %3,%1 ; sbbl %0,%0; cmpl %1,%4; sbbl $0,%0" \ :"=&r" (flag), "=r" (sum) \ - :"1" (addr),"g" ((int)(size)),"g" (current->addr_limit.seg)); \ + :"1" (__addr),"g" ((int)(size)),"g" (current->addr_limit.seg)); \ flag; }) #ifdef CONFIG_X86_WP_WORKS_OK @@ -174,13 +182,16 @@ */ #define get_user(x,ptr) \ ({ int __ret_gu,__val_gu; \ - switch(sizeof (*(ptr))) { \ - case 1: __get_user_x(1,__ret_gu,__val_gu,ptr); break; \ - case 2: __get_user_x(2,__ret_gu,__val_gu,ptr); break; \ - case 4: __get_user_x(4,__ret_gu,__val_gu,ptr); break; \ - default: __get_user_x(X,__ret_gu,__val_gu,ptr); break; \ + __typeof__(*(ptr)) *__ptr = (ptr); \ + __ptr = trans_address(__ptr); \ + __print_name("get_user"); \ + switch(sizeof (*(__ptr))) { \ + case 1: __get_user_x(1,__ret_gu,__val_gu,__ptr); break; \ + case 2: __get_user_x(2,__ret_gu,__val_gu,__ptr); break; \ + case 4: __get_user_x(4,__ret_gu,__val_gu,__ptr); break; \ + default: __get_user_x(X,__ret_gu,__val_gu,__ptr); break; \ } \ - (x) = (__typeof__(*(ptr)))__val_gu; \ + (x) = (__typeof__(*(__ptr)))__val_gu; \ __ret_gu; \ }) @@ -276,6 +287,10 @@ }) #define __put_user_u64(x, addr, err) \ +do { \ + __typeof__(*(addr)) *__addr = (addr); \ + __addr = trans_address(__addr); \ + __print_name("__put_user_u64"); \ __asm__ __volatile__( \ "1: movl %%eax,0(%2)\n" \ "2: movl %%edx,4(%2)\n" \ @@ -290,7 +305,8 @@ " .long 2b,4b\n" \ ".previous" \ : "=r"(err) \ - : "A" (x), "r" (addr), "i"(-EFAULT), "0"(err)) + : "A" (x), "r" (__addr), "i"(-EFAULT), "0"(err));\ +} while (0) #define __put_user_size(x,ptr,size,retval) \ do { \ @@ -313,6 +329,10 @@ * aliasing issues. */ #define __put_user_asm(x, addr, err, itype, rtype, ltype) \ +do { \ + __typeof__(*(addr)) *__addr = (addr); \ + __addr = trans_address(__addr); \ + __print_name("__put_user_asm"); \ __asm__ __volatile__( \ "1: mov"itype" %"rtype"1,%2\n" \ "2:\n" \ @@ -325,7 +345,8 @@ " .long 1b,3b\n" \ ".previous" \ : "=r"(err) \ - : ltype (x), "m"(__m(addr)), "i"(-EFAULT), "0"(err)) + : ltype (x), "m"(__m(__addr)), "i"(-EFAULT), "0"(err)); \ +} while(0) #define __get_user_nocheck(x,ptr,size) \ @@ -350,6 +371,10 @@ } while (0) #define __get_user_asm(x, addr, err, itype, rtype, ltype) \ +do { \ + __typeof__(*(addr)) *__addr = (addr); \ + __addr = trans_address(__addr); \ + __print_name("__get_user_asm"); \ __asm__ __volatile__( \ "1: mov"itype" %2,%"rtype"1\n" \ "2:\n" \ @@ -363,7 +388,35 @@ " .long 1b,3b\n" \ ".previous" \ : "=r"(err), ltype (x) \ - : "m"(__m(addr)), "i"(-EFAULT), "0"(err)) + : "m"(__m(__addr)), "i"(-EFAULT), "0"(err)); \ +} while (0) + + +/* + * This macro reads a 32-bit word from user space without any + * address checking and without any address translation. + * We need this to access the loaded ReverseTransTableSec section + * at run-time. + */ +#define __get_user_asm_notrans(x, addr) \ +({ \ + long __err = 0; \ + __asm__ __volatile__( \ + "1: movl %2,%1\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: movl %3,%0\n" \ + " xorl %1,%1\n" \ + " jmp 2b\n" \ + ".previous\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 4\n" \ + " .long 1b,3b\n" \ + ".previous" \ + : "=r"(__err), "=r" (x) \ + : "m"(__m(addr)), "i"(-EFAULT), "0"(__err)); \ + __err; \ +}) /* @@ -374,6 +427,9 @@ #define __copy_user(to,from,size) \ do { \ int __d0, __d1; \ + __typeof__(*(to)) *__to = (to); \ + __to = trans_address(__to); \ + __print_name("__copy_user"); \ __asm__ __volatile__( \ "0: rep; movsl\n" \ " movl %3,%0\n" \ @@ -389,13 +445,16 @@ " .long 1b,2b\n" \ ".previous" \ : "=&c"(size), "=&D" (__d0), "=&S" (__d1) \ - : "r"(size & 3), "0"(size / 4), "1"(to), "2"(from) \ + : "r"(size & 3), "0"(size / 4), "1"(__to), "2"(from) \ : "memory"); \ } while (0) #define __copy_user_zeroing(to,from,size) \ do { \ int __d0, __d1; \ + __typeof__(*(from)) *__from = (from); \ + __from = trans_address(__from); \ + __print_name("__copy_user_zeroing"); \ __asm__ __volatile__( \ "0: rep; movsl\n" \ " movl %3,%0\n" \ @@ -417,7 +476,7 @@ " .long 1b,4b\n" \ ".previous" \ : "=&c"(size), "=&D" (__d0), "=&S" (__d1) \ - : "r"(size & 3), "0"(size / 4), "1"(to), "2"(from) \ + : "r"(size & 3), "0"(size / 4), "1"(to), "2"(__from) \ : "memory"); \ } while (0) @@ -443,6 +502,9 @@ #define __constant_copy_user(to, from, size) \ do { \ int __d0, __d1; \ + __typeof__(*(to)) *__to = (to); \ + __to = trans_address(__to); \ + __print_name("__constant_copy_user"); \ switch (size & 3) { \ default: \ __asm__ __volatile__( \ @@ -457,7 +519,7 @@ " .long 0b,2b\n" \ ".previous" \ : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ - : "1"(from), "2"(to), "0"(size/4) \ + : "1"(from), "2"(__to), "0"(size/4) \ : "memory"); \ break; \ case 1: \ @@ -476,7 +538,7 @@ " .long 1b,4b\n" \ ".previous" \ : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ - : "1"(from), "2"(to), "0"(size/4) \ + : "1"(from), "2"(__to), "0"(size/4) \ : "memory"); \ break; \ case 2: \ @@ -495,7 +557,7 @@ " .long 1b,4b\n" \ ".previous" \ : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ - : "1"(from), "2"(to), "0"(size/4) \ + : "1"(from), "2"(__to), "0"(size/4) \ : "memory"); \ break; \ case 3: \ @@ -517,7 +579,7 @@ " .long 2b,6b\n" \ ".previous" \ : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ - : "1"(from), "2"(to), "0"(size/4) \ + : "1"(from), "2"(__to), "0"(size/4) \ : "memory"); \ break; \ } \ @@ -527,6 +589,9 @@ #define __constant_copy_user_zeroing(to, from, size) \ do { \ int __d0, __d1; \ + __typeof__(*(from)) *__from = (from); \ + __from = trans_address(__from); \ + __print_name("__constant_copy_user_zeroing"); \ switch (size & 3) { \ default: \ __asm__ __volatile__( \ @@ -547,7 +612,7 @@ " .long 0b,2b\n" \ ".previous" \ : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ - : "1"(from), "2"(to), "0"(size/4) \ + : "1"(__from), "2"(to), "0"(size/4) \ : "memory"); \ break; \ case 1: \ @@ -579,7 +644,7 @@ " .long 1b,4b\n" \ ".previous" \ : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ - : "1"(from), "2"(to), "0"(size/4) \ + : "1"(__from), "2"(to), "0"(size/4) \ : "memory"); \ break; \ case 2: \ @@ -611,7 +676,7 @@ " .long 1b,4b\n" \ ".previous" \ : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ - : "1"(from), "2"(to), "0"(size/4) \ + : "1"(__from), "2"(to), "0"(size/4) \ : "memory"); \ break; \ case 3: \ @@ -653,7 +718,7 @@ " .long 2b,6b\n" \ ".previous" \ : "=c"(size), "=&S" (__d0), "=&D" (__d1)\ - : "1"(from), "2"(to), "0"(size/4) \ + : "1"(__from), "2"(to), "0"(size/4) \ : "memory"); \ break; \ } \ diff -Nur linux-2.4.24.orig/include/linux/elf.h linux-2.4.24-elf/include/linux/elf.h --- linux-2.4.24.orig/include/linux/elf.h 2002-11-29 00:53:15.000000000 +0100 +++ linux-2.4.24-elf/include/linux/elf.h 2004-01-28 11:23:29.000000000 +0100 @@ -515,7 +515,7 @@ #define SHN_HIRESERVE 0xffff #define SHN_MIPS_ACCOMON 0xff00 -typedef struct { +typedef struct elf32_shdr { Elf32_Word sh_name; Elf32_Word sh_type; Elf32_Word sh_flags; @@ -596,6 +596,7 @@ extern Elf32_Dyn _DYNAMIC []; #define elfhdr elf32_hdr #define elf_phdr elf32_phdr +#define elf_shdr elf32_shdr #define elf_note elf32_note #else @@ -603,6 +604,7 @@ extern Elf64_Dyn _DYNAMIC []; #define elfhdr elf64_hdr #define elf_phdr elf64_phdr +#define elf_shdr elf64_shdr #define elf_note elf64_note #endif diff -Nur linux-2.4.24.orig/include/linux/sched.h linux-2.4.24-elf/include/linux/sched.h --- linux-2.4.24.orig/include/linux/sched.h 2003-11-28 19:26:21.000000000 +0100 +++ linux-2.4.24-elf/include/linux/sched.h 2004-02-03 11:09:42.000000000 +0100 @@ -198,6 +198,8 @@ fd_array: { NULL, } \ } +struct address_trans_struct; + /* Maximum number of active map areas.. This is a random (large) number */ #define DEFAULT_MAX_MAP_COUNT (65536) @@ -229,6 +231,11 @@ unsigned dumpable:1; + struct address_trans_struct *address_trans; + int address_trans_count; // number of entries in the address_trans table + int count_trans; // number of performed address translations + unsigned long *do_trans_addr; + /* Architecture-specific MM context */ mm_context_t context; }; @@ -246,6 +253,35 @@ mmlist: LIST_HEAD_INIT(name.mmlist), \ } +struct address_trans_struct { + unsigned long begin; + unsigned long end; + long offset; +}; + +extern void *__trans_address(void *address); + +/* + * We are allowed to calculate with addresss because it already has been + * localised by the caller + */ +#define trans_address(address) \ +({ \ + if (unlikely(current->flags & PF_TRANSEX)) \ + address = (__typeof__(*address) *)__trans_address((void *)address); \ + address; \ +}) + +#if 0 +#define __print_name(name) \ +do { \ + if (unlikely(current->flags & PF_TRANSEX)) \ + printk(KERN_INFO name "\n"); \ +} while (0) +#else +#define __print_name(name) do { } while (0) +#endif + struct signal_struct { atomic_t count; struct k_sigaction action[_NSIG]; @@ -431,6 +467,7 @@ #define PF_MEMALLOC 0x00000800 /* Allocating memory */ #define PF_FREE_PAGES 0x00002000 /* per process page freeing */ #define PF_NOIO 0x00004000 /* avoid generating further I/O */ +#define PF_TRANSEX 0x00008000 /* address translation extensions */ #define PF_USEDFPU 0x00100000 /* task used FPU this quantum (SMP) */ diff -Nur linux-2.4.24.orig/kernel/fork.c linux-2.4.24-elf/kernel/fork.c --- linux-2.4.24.orig/kernel/fork.c 2003-11-28 19:26:21.000000000 +0100 +++ linux-2.4.24-elf/kernel/fork.c 2004-02-03 10:57:20.000000000 +0100 @@ -235,6 +235,10 @@ mm->page_table_lock = SPIN_LOCK_UNLOCKED; mm->pgd = pgd_alloc(mm); mm->def_flags = 0; + mm->address_trans = NULL; + mm->address_trans_count = 0; + mm->count_trans = 0; + mm->do_trans_addr = NULL; if (mm->pgd) return mm; free_mm(mm); @@ -265,6 +269,13 @@ inline void __mmdrop(struct mm_struct *mm) { BUG_ON(mm == &init_mm); + if (mm->address_trans) { +#if 0 + printk(KERN_INFO "Freeing the address_trans struct.\n"); + printk(KERN_INFO "Number of performed translations: %d\n", mm->count_trans); +#endif + vfree(mm->address_trans); + } pgd_free(mm->pgd); check_pgt_cache(); destroy_context(mm); diff -Nur linux-2.4.24.orig/kernel/ksyms.c linux-2.4.24-elf/kernel/ksyms.c --- linux-2.4.24.orig/kernel/ksyms.c 2003-11-28 19:26:21.000000000 +0100 +++ linux-2.4.24-elf/kernel/ksyms.c 2004-01-23 14:47:57.000000000 +0100 @@ -518,6 +518,7 @@ EXPORT_SYMBOL(single_open); EXPORT_SYMBOL(single_release); EXPORT_SYMBOL(seq_release_private); +EXPORT_SYMBOL_NOVERS(__trans_address); /* Program loader interfaces */ EXPORT_SYMBOL(setup_arg_pages); diff -Nur linux-2.4.24.orig/Makefile linux-2.4.24-elf/Makefile --- linux-2.4.24.orig/Makefile 2004-01-05 14:53:56.000000000 +0100 +++ linux-2.4.24-elf/Makefile 2004-01-28 11:17:23.000000000 +0100 @@ -1,7 +1,7 @@ VERSION = 2 PATCHLEVEL = 4 SUBLEVEL = 24 -EXTRAVERSION = +EXTRAVERSION = -elf KERNELRELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) diff -Nur linux-2.4.24.orig/mm/memory.c linux-2.4.24-elf/mm/memory.c --- linux-2.4.24.orig/mm/memory.c 2003-11-28 19:26:21.000000000 +0100 +++ linux-2.4.24-elf/mm/memory.c 2004-02-03 10:42:05.000000000 +0100 @@ -1497,3 +1497,84 @@ } return page; } + + +void *__trans_address(void * address) { + struct address_trans_struct *address_trans = current->mm->address_trans; + int i1, i2, i, max_i; + unsigned long do_trans; + current->mm->count_trans++; + max_i = current->mm->address_trans_count - 1; + + __get_user_asm_notrans(do_trans, current->mm->do_trans_addr); + if (!do_trans) { // user space can ask us to skip the translation +#if 0 + printk(KERN_INFO "tr %d: skipping\n", current->mm->count_trans); +#endif + return address; + } + + /* we never want any pointer oops */ + if (!address_trans) { + printk(KERN_WARNING "tr %d: No address_trans!\n", current->mm->count_trans); + return address; // be as nice as possible + } + + /* first check the upper bound: skip stack addresses */ + if ((unsigned long)address >= address_trans[max_i].end) { +#if 0 + printk(KERN_INFO "tr %d: upper skip\n", current->mm->count_trans); +#endif + return address; + } + + if ((unsigned long)address < address_trans->begin) { +#if 0 + printk(KERN_INFO "tr %d: lower skip\n", current->mm->count_trans); +#endif + return address; + } + + /* binary search for our address_trans_struct entry */ + i1 = 0; + i2 = max_i; + while (i2 - i1 > 1) { + i = (i1 + i2) / 2; + if (address_trans[i].end > (unsigned long)address) + i2 = i; + else + i1 = i; + } + + + if (address_trans[i2].begin > (unsigned long)address) { +#if 0 + printk(KERN_INFO "tr %d: begin > address\n", current->mm->count_trans); +#endif + return address; + } + + if (address_trans[i2].end <= (unsigned long)address) { +#if 0 + printk(KERN_INFO "tr %d: end < address\n", current->mm->count_trans); +#endif + return address; + } + + address = (void *)((long)address + address_trans[i2].offset); + +#if 0 + printk(KERN_INFO "tr %d: %i\n", current->mm->count_trans, (int)address_trans[i2].offset); +#endif + + return address; +} + + +/* + * This can be called from within entry.S to visualise a system call + */ +__attribute__((regparm(1))) void syscall_trans(int syscall) +{ + printk(KERN_INFO "sc: %d\n", syscall); +} diff -Nur linux-2.4.24.orig/mm/mmap.c linux-2.4.24-elf/mm/mmap.c --- linux-2.4.24.orig/mm/mmap.c 2003-11-28 19:26:21.000000000 +0100 +++ linux-2.4.24-elf/mm/mmap.c 2004-01-23 14:47:57.000000000 +0100 @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -148,10 +149,15 @@ { unsigned long rlim, retval; unsigned long newbrk, oldbrk; + long offset = 0; struct mm_struct *mm = current->mm; down_write(&mm->mmap_sem); + if (current->flags & PF_TRANSEX) + offset = __trans_address(mm->brk) - (long)mm->brk; + brk += offset; + if (brk < mm->end_code) goto out; newbrk = PAGE_ALIGN(brk); @@ -187,7 +193,7 @@ out: retval = mm->brk; up_write(&mm->mmap_sem); - return retval; + return retval - offset; } /* Combine the mmap "prot" and "flags" argument into one "vm_flags" used