diff -urN linux.wrk.orig/Makefile linux.wrk/Makefile --- linux.wrk.orig/Makefile Mon Jan 21 15:13:15 2002 +++ linux.wrk/Makefile Mon Jan 21 15:17:06 2002 @@ -236,7 +236,7 @@ drivers/sound/pndsperm.c \ drivers/sound/pndspini.c \ drivers/atm/fore200e_*_fw.c drivers/atm/.fore200e_*.fw \ - .version .config* config.in config.old \ + .uniquebytes .version .config* config.in config.old \ scripts/tkparse scripts/kconfig.tk scripts/kconfig.tmp \ scripts/lxdialog/*.o scripts/lxdialog/lxdialog \ .menuconfig.log \ @@ -283,6 +283,7 @@ vmlinux: include/linux/version.h $(CONFIGURATION) init/main.o init/version.o linuxsubdirs @$(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" kallsyms + @$(MAKE) -C ulib .PHONY: kallsyms @@ -332,14 +333,17 @@ linuxsubdirs: $(patsubst %, _dir_%, $(SUBDIRS)) -$(patsubst %, _dir_%, $(SUBDIRS)) : dummy include/linux/version.h include/config/MARKER +$(patsubst %, _dir_%, $(SUBDIRS)) : dummy include/linux/compile.h include/config/MARKER $(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" -C $(patsubst _dir_%, %, $@) $(TOPDIR)/include/linux/version.h: include/linux/version.h $(TOPDIR)/include/linux/compile.h: include/linux/compile.h newversion: - . scripts/mkversion > .version + . scripts/mkversion > .tmpversion + @mv -f .tmpversion .version + rm -f .uniquebytes + dd if=/dev/urandom of=.uniquebytes bs=1 count=16 include/linux/compile.h: $(CONFIGURATION) include/linux/version.h newversion @echo -n \#define UTS_VERSION \"\#`cat .version` > .ver @@ -357,9 +361,12 @@ echo \#define LINUX_COMPILE_DOMAIN ; \ fi >> .ver @echo \#define LINUX_COMPILER \"`$(CC) $(CFLAGS) -v 2>&1 | tail -1`\" >> .ver + @echo -n \#"define LINUX_UNIQUE_BYTES " >>.ver + @hexdump -v -e '1/1 "0x%02x, "' .uniquebytes | sed -e 's/, $$//g' >>.ver + @echo "" >>.ver @mv -f .ver $@ -include/linux/version.h: ./Makefile include/linux/autoconf.h +include/linux/version.h: ./Makefile include/linux/autoconf.h @echo \#define UTS_RELEASE \"$(KERNELRELEASE)\" > .ver @echo \#define LINUX_VERSION_CODE `expr $(VERSION) \\* 65536 + $(PATCHLEVEL) \\* 256 + $(SUBLEVEL)` >> .ver @echo '#define KERNEL_VERSION(a,b,c) (((a) << 16) + ((b) << 8) + (c))' >>.ver @@ -453,6 +460,7 @@ rm -f $(CLEAN_FILES) rm -rf $(CLEAN_DIRS) $(MAKE) -C Documentation/DocBook clean + $(MAKE) -C ulib clean mrproper: clean archmrproper find . \( -size 0 -o -name .depend \) -type f -print | xargs rm -f diff -urN linux.wrk.orig/arch/i386/Makefile linux.wrk/arch/i386/Makefile --- linux.wrk.orig/arch/i386/Makefile Mon Jan 21 15:13:15 2002 +++ linux.wrk/arch/i386/Makefile Mon Jan 21 15:17:06 2002 @@ -98,7 +98,7 @@ DRIVERS += arch/i386/math-emu/math.o endif -arch/i386/kernel: dummy +arch/i386/kernel: dummy include/linux/compile.h $(MAKE) linuxsubdirs SUBDIRS=arch/i386/kernel arch/i386/mm: dummy diff -urN linux.wrk.orig/arch/i386/kernel/Makefile linux.wrk/arch/i386/kernel/Makefile --- linux.wrk.orig/arch/i386/kernel/Makefile Mon Jan 21 15:13:14 2002 +++ linux.wrk/arch/i386/kernel/Makefile Mon Jan 21 15:17:06 2002 @@ -23,8 +23,9 @@ obj-y := process.o semaphore.o signal.o entry.o traps.o irq.o vm86.o \ ptrace.o i8259.o ioport.o ldt.o setup.o time.o sys_i386.o \ pci-dma.o i386_ksyms.o i387.o bluesmoke.o dmi_scan.o \ - bootflag.o + bootflag.o vsysdata.o vunique.o dynamic_syscall.o +vunique.o: $(TOPDIR)/include/linux/compile.h ifdef CONFIG_PCI obj-y += pci-i386.o diff -urN linux.wrk.orig/arch/i386/kernel/dynamic_syscall.c linux.wrk/arch/i386/kernel/dynamic_syscall.c --- linux.wrk.orig/arch/i386/kernel/dynamic_syscall.c Wed Dec 31 19:00:00 1969 +++ linux.wrk/arch/i386/kernel/dynamic_syscall.c Mon Jan 21 15:17:06 2002 @@ -0,0 +1,69 @@ +/* arch/i386/kernel/dynamic_syscall.c + * Entry code for dynamic syscalls on i386. + */ +#include +#include +#include +#include +#include +#include + +struct dummy_args { + long data[8]; +}; + +extern struct vsyscall_entry { + long eip; + long (*call)(struct dummy_args args); +} vsyscall_list_begin, vsyscall_list_end; + +long sys_dynamic_syscall(struct pt_regs regs) __attribute__((regparm(0))); + +long sys_dynamic_syscall(struct pt_regs regs) +{ + struct dummy_args dummy_args; + struct vsyscall_entry *ent = (void *)regs.edx; + void *args = (void *)regs.ecx; + long ret; + + pr_debug("ent = %p args = %p\n", ent, args); + pr_debug("eip = 0x%08lx\n", regs.eip); + + if (unlikely(!current->mm->vsys_mapped)) + goto err; + + /* The pointer must be aligned in the table. */ + if (unlikely((long)ent & (sizeof(*ent) - 1))) { + pr_debug("unaligned\n"); + goto err; + } + + /* Bounds checking... */ + if (unlikely(ent < &vsyscall_list_begin) || + unlikely(ent >= &vsyscall_list_end)) { + pr_debug("out of range %p <= %p < %p\n", + &vsyscall_list_begin, ent, + &vsyscall_list_end); + goto err; + } + /* The entry should be valid now. Verify that the caller's eip + * is correct. + */ + if (unlikely(ent->eip != regs.eip)) { + pr_debug("eip mismatch (0x%lx vs 0x%lx)\n", ent->eip, regs.eip); + goto err; + } + + pr_debug("ent->call = %p\n", ent->call); + + if (unlikely(copy_from_user(&dummy_args, args, sizeof(dummy_args)))) + return -EFAULT; + + ret = ent->call(dummy_args); + + pr_debug("ret = 0x%08lx\n", ret); + + return ret; +err: + return -ENOSYS; +} diff -urN linux.wrk.orig/arch/i386/kernel/entry.S linux.wrk/arch/i386/kernel/entry.S --- linux.wrk.orig/arch/i386/kernel/entry.S Mon Jan 21 15:13:11 2002 +++ linux.wrk/arch/i386/kernel/entry.S Mon Jan 21 15:18:55 2002 @@ -46,6 +46,7 @@ #include #define ASSEMBLY #include +#include EBX = 0x00 ECX = 0x04 @@ -635,6 +636,11 @@ # endif #endif + .rept __NR_sys_dynamic_syscall-(.-sys_call_table)/4 + .long SYMBOL_NAME(sys_ni_syscall) + .endr + .long SYMBOL_NAME(sys_dynamic_syscall) + .rept NR_syscalls-(.-sys_call_table)/4 .long SYMBOL_NAME(sys_ni_syscall) .endr diff -urN linux.wrk.orig/arch/i386/kernel/vsysdata.c linux.wrk/arch/i386/kernel/vsysdata.c --- linux.wrk.orig/arch/i386/kernel/vsysdata.c Wed Dec 31 19:00:00 1969 +++ linux.wrk/arch/i386/kernel/vsysdata.c Mon Jan 21 15:17:06 2002 @@ -0,0 +1,11 @@ +/* vsysdata.c - declarations for variables shared with the kernel + * + * Items placed in .data.vsyscall have a kernel virtual address + * and are read/write from kernel space only. The copy placed + * in .vsyscall_data are linked at a userspace address and are + * read only accessible from userland. + */ +#include + +union vsys_union user_vsys_cpudata[256] __attribute__((section(".vsyscall_data"))); +//asm(".globl vsys_cpudata ; bobbob = user_vsys_cpudata - vsyscall_text_begin ; vsys_cpudata = bobbob + VSYSCALL_text"); diff -urN linux.wrk.orig/arch/i386/kernel/vunique.S linux.wrk/arch/i386/kernel/vunique.S --- linux.wrk.orig/arch/i386/kernel/vunique.S Wed Dec 31 19:00:00 1969 +++ linux.wrk/arch/i386/kernel/vunique.S Mon Jan 21 15:17:06 2002 @@ -0,0 +1,7 @@ +#include + + .section .first_vsyscall_text,"xa" + .globl signature +signature: + .byte LINUX_UNIQUE_BYTES + .size signature,.-signature diff -urN linux.wrk.orig/arch/i386/vmlinux.lds linux.wrk/arch/i386/vmlinux.lds --- linux.wrk.orig/arch/i386/vmlinux.lds Mon Jan 21 15:13:11 2002 +++ linux.wrk/arch/i386/vmlinux.lds Mon Jan 21 15:17:06 2002 @@ -13,6 +13,26 @@ *(.fixup) *(.gnu.warning) } = 0x9090 + /* Note: most of these declarations are in kernel/vsysdata.c,vsyscall.S. + * We use two segments for the data liked at a kernel virtual address + * (.data.vsyscall) and user virtual address (.vsyscall_data). + * .vsyscall_text is linked at a kernel virtual address + */ + . = ALIGN(4096); + VSYSCALL_text = .; + VSYSCALL 0xbfff0000 : AT ( VSYSCALL_text ) { + vsyscall_text_begin = .; + *(.first_vsyscall_text) + *(.vsyscall_text) + . = ALIGN(4096); + vsyscall_text_end = .; + *(.vsyscall_data) + . = ALIGN(4096); + vsyscall_data_end = .; + } + vsys_cpudata = user_vsys_cpudata - vsyscall_text_begin + VSYSCALL_text; + . = VSYSCALL_text + SIZEOF(VSYSCALL); + VSYSCALL_text_end = .; .text.lock : { *(.text.lock) } /* out-of-line lock text */ .rodata : { *(.rodata) } .kstrtab : { *(.kstrtab) } @@ -23,12 +43,21 @@ __start___ksymtab = .; /* Kernel symbol table */ __ksymtab : { *(__ksymtab) } __stop___ksymtab = .; - __start___kallsyms = .; /* All kernel symbols */ + __start___kallsyms = .; /* All kernel symbols */ __kallsyms : { *(__kallsyms) } __stop___kallsyms = .; _etext = .; /* End of text section */ .data : { /* Data */ *(.data) + . = ALIGN(8); + vsyscall_list_begin = .; + *(.data.vsyscall_list) + vsyscall_list_end = .; + . = ALIGN(4096); + kernel_vsyscall_data_begin = .; + *(.data.vsyscall) + . = ALIGN(4096); + kernel_vsyscall_data_end = .; CONSTRUCTORS } _edata = .; /* End of data section */ @@ -70,4 +99,15 @@ .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } .comment 0 : { *(.comment) } +/* +# VSYSCALL : { +# / * vsyscall area *i / +# __vsyscall_begin = .; +# *(vsyscall_text) +# . = ALIGN(4096); +# *(.data.vsyscall) +# . = ALIGN(4096); +# __vsyscall_end = .; +# } >vsyscall_area +*/ } diff -urN linux.wrk.orig/arch/i386/vmlinux.lds.S linux.wrk/arch/i386/vmlinux.lds.S --- linux.wrk.orig/arch/i386/vmlinux.lds.S Mon Jan 21 15:13:11 2002 +++ linux.wrk/arch/i386/vmlinux.lds.S Mon Jan 21 15:17:06 2002 @@ -13,6 +13,28 @@ *(.fixup) *(.gnu.warning) } = 0x9090 + + /* Note: most of these declarations are in kernel/vsysdata.c,vsyscall.S. + * We use two segments for the data liked at a kernel virtual address + * (.data.vsyscall) and user virtual address (.vsyscall_data). + * .vsyscall_text is linked at a kernel virtual address + */ + . = ALIGN(4096); + VSYSCALL_text = .; + VSYSCALL 0xbfff0000 : AT ( VSYSCALL_text ) { + vsyscall_text_begin = .; + *(.first_vsyscall_text) + *(.vsyscall_text) + . = ALIGN(4096); + vsyscall_text_end = .; + *(.vsyscall_data) + . = ALIGN(4096); + vsyscall_data_end = .; + } + vsys_cpudata = user_vsys_cpudata - vsyscall_text_begin + VSYSCALL_text; + . = VSYSCALL_text + SIZEOF(VSYSCALL); + VSYSCALL_text_end = .; + .text.lock : { *(.text.lock) } /* out-of-line lock text */ .rodata : { *(.rodata) } .kstrtab : { *(.kstrtab) } @@ -34,6 +56,18 @@ .data : { /* Data */ *(.data) + + . = ALIGN(8); + vsyscall_list_begin = .; + *(.data.vsyscall_list) + vsyscall_list_end = .; + + . = ALIGN(4096); + kernel_vsyscall_data_begin = .; + *(.data.vsyscall) + . = ALIGN(4096); + kernel_vsyscall_data_end = .; + CONSTRUCTORS } @@ -83,4 +117,16 @@ .stab.index 0 : { *(.stab.index) } .stab.indexstr 0 : { *(.stab.indexstr) } .comment 0 : { *(.comment) } + +/* +# VSYSCALL : { +# / * vsyscall area *i / +# __vsyscall_begin = .; +# *(vsyscall_text) +# . = ALIGN(4096); +# *(.data.vsyscall) +# . = ALIGN(4096); +# __vsyscall_end = .; +# } >vsyscall_area +*/ } diff -urN linux.wrk.orig/drivers/char/mem.c linux.wrk/drivers/char/mem.c --- linux.wrk.orig/drivers/char/mem.c Mon Jan 21 15:13:11 2002 +++ linux.wrk/drivers/char/mem.c Mon Jan 21 15:17:06 2002 @@ -25,6 +25,7 @@ #include #include #include +#include #ifdef CONFIG_SENSORS extern void sensors_init_all(void); @@ -539,6 +540,87 @@ write: write_full, }; +void vsys_mmap_close(struct vm_area_struct *area) +{ + area->vm_mm->vsys_mapped = 0; +} + +static struct vm_operations_struct vsys_mmap_ops = { + close: vsys_mmap_close, +}; + +int vsys_mmap(struct file *file, struct vm_area_struct *vma) +{ + extern unsigned char vsyscall_text_begin, vsyscall_text_end, VSYSCALL_text[]; + unsigned long offset = vma->vm_pgoff << PAGE_SHIFT; + unsigned long len = vma->vm_end - vma->vm_start; + unsigned long actual_len = &vsyscall_text_end - &vsyscall_text_begin; + + if ((offset + len) > actual_len) + len = actual_len - offset; + + pr_debug("len = 0x%lx, actual_len = 0x%lx\n", len, actual_len); + + vma->vm_start = (unsigned long)&vsyscall_text_begin + offset; + vma->vm_end = vma->vm_start + len; + vma->vm_flags |= VM_RESERVED; + + pr_debug("vm_start = 0x%lx, vm_end = 0x%lx\n", + vma->vm_start, vma->vm_end); + pr_debug("va=%p pa=0x%lx\n", + VSYSCALL_text + offset, + __pa(VSYSCALL_text) + offset); + + if (vma->vm_start < (unsigned long)&vsyscall_text_begin) { + pr_debug("vsys_mmap: start < begin\n"); + return -EINVAL; + } + + if (vma->vm_end < (unsigned long)&vsyscall_text_begin) { + pr_debug("vsys_mmap: end < begin\n"); + return -EINVAL; + } + + if (vma->vm_end > (unsigned long)&vsyscall_text_end) { + pr_debug("vsys_mmap: end(%lx) > text_end(%p)\n", + vma->vm_end, &vsyscall_text_end); + return -EINVAL; + } + + if (vma->vm_start >= vma->vm_end) { + pr_debug("vsys_mmap: end\n"); + return -EINVAL; + } + + if (find_vma_intersection(current->mm, vma->vm_start, vma->vm_end)) { + pr_debug("vsyscall: mapping collision\n"); + return -EINVAL; + } + + if ((vma->vm_flags & (VM_SHARED | VM_WRITE)) == (VM_SHARED | VM_WRITE)) { + pr_debug("vsyscall: attempt to write to mapping\n"); + return -EPERM; + } + + if (remap_page_range(vma->vm_start, + __pa(VSYSCALL_text) + offset, + vma->vm_end-vma->vm_start, + vma->vm_page_prot)) + return -EAGAIN; + + pr_debug("VSYSCALL_text(%p): %02x %02x %02x %02x\n", + VSYSCALL_text, + VSYSCALL_text[0], VSYSCALL_text[1], + VSYSCALL_text[2], VSYSCALL_text[3]); + + current->mm->vsys_mapped = 1; + return 0; +} + +static struct file_operations vsys_fops = { + mmap: vsys_mmap, +}; + static int memory_open(struct inode * inode, struct file * filp) { switch (MINOR(inode->i_rdev)) { @@ -568,6 +650,9 @@ case 9: filp->f_op = &urandom_fops; break; + case 10: + filp->f_op = &vsys_fops; + break; default: return -ENXIO; } @@ -592,7 +677,8 @@ {5, "zero", S_IRUGO | S_IWUGO, &zero_fops}, {7, "full", S_IRUGO | S_IWUGO, &full_fops}, {8, "random", S_IRUGO | S_IWUSR, &random_fops}, - {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops} + {9, "urandom", S_IRUGO | S_IWUSR, &urandom_fops}, + {10,"vsys", S_IRUGO, &vsys_fops}, }; int i; diff -urN linux.wrk.orig/fs/aio.c linux.wrk/fs/aio.c --- linux.wrk.orig/fs/aio.c Mon Jan 21 15:13:17 2002 +++ linux.wrk/fs/aio.c Mon Jan 21 15:17:06 2002 @@ -39,6 +39,7 @@ #include #include +#include #define static /**/ #define inline /**/ @@ -897,3 +898,10 @@ } __initcall(aio_setup); + +add_dynamic_syscall(sys_io_setup); +add_dynamic_syscall(sys_io_destroy); +add_dynamic_syscall(sys_io_submit); +add_dynamic_syscall(sys_io_cancel); +add_dynamic_syscall(sys_io_wait); +add_dynamic_syscall(sys_io_getevents); --- linux/fs/aio.c~ Sun Feb 3 11:11:00 2002 +++ linux/fs/aio.c Sun Feb 3 11:11:41 2002 @@ -972,3 +972,8 @@ add_dynamic_syscall(sys_io_cancel); add_dynamic_syscall(sys_io_wait); add_dynamic_syscall(sys_io_getevents); +EXPORT_SYMBOL_GPL(generic_file_kvec_read); +EXPORT_SYMBOL_GPL(generic_file_aio_read); +EXPORT_SYMBOL_GPL(generic_file_kvec_write); +EXPORT_SYMBOL_GPL(generic_file_aio_write); +EXPORT_SYMBOL_GPL(generic_file_new_read); diff -urN linux.wrk.orig/include/asm-i386/a.out.h linux.wrk/include/asm-i386/a.out.h --- linux.wrk.orig/include/asm-i386/a.out.h Fri Jun 16 14:33:06 1995 +++ linux.wrk/include/asm-i386/a.out.h Mon Jan 21 15:17:06 2002 @@ -19,7 +19,9 @@ #ifdef __KERNEL__ -#define STACK_TOP TASK_SIZE +#define VSYSCALL_SIZE 0x10000 /* 64KB for vsyscalls */ +#define STACK_GUARD_SIZE 0x02000 /* 8KB guard area */ +#define STACK_TOP (TASK_SIZE - VSYSCALL_SIZE - STACK_GUARD_SIZE) #endif diff -urN linux.wrk.orig/include/asm-i386/unistd.h linux.wrk/include/asm-i386/unistd.h --- linux.wrk.orig/include/asm-i386/unistd.h Fri Aug 11 17:39:23 2000 +++ linux.wrk/include/asm-i386/unistd.h Mon Jan 21 15:18:01 2002 @@ -228,6 +228,8 @@ #define __NR_getdents64 220 #define __NR_fcntl64 221 +#define __NR_sys_dynamic_syscall 230 + /* user-visible error numbers are in the range -1 - -124: see */ #define __syscall_return(type, res) \ diff -urN linux.wrk.orig/include/asm-i386/vsyscall.h linux.wrk/include/asm-i386/vsyscall.h --- linux.wrk.orig/include/asm-i386/vsyscall.h Wed Dec 31 19:00:00 1969 +++ linux.wrk/include/asm-i386/vsyscall.h Mon Jan 21 15:17:06 2002 @@ -0,0 +1,41 @@ +#ifndef __ASM__VSYSCALL_H +#define __ASM__VSYSCALL_H +/* include/asm-i386/vsyscall.h + * Copyright 2002 Red Hat, Inc. + */ +#include +#include + +/* We call sys_dynamic_syscall(long nr, void *args) using regparm(2) + * convention. The .text.vsyscall section is mapped into userspace, + * whereas .data.vsyscall_list is a kernel-only array of the vsyscalls + * and the valid userspace address to call them from. All vsyscalls + * are called with C calling convention (ie args on the stack for x86). + * + * Note: the layout of .data.vsyscall_list must match the entries in + * dynamic_syscall.c. + */ +#define STRINGIFYa(x) #x +#define STRINGIFY(x) STRINGIFYa(x) +#define NR_dyn_sys STRINGIFY(__NR_sys_dynamic_syscall) +#define add_dynamic_syscall(name) \ + __asm__(" \n\ + .section .vsyscall_text, \"xa\" \n\ + .globl v" #name " \n\ + v" #name ": \n\ + push %ecx \n\ + push %edx \n\ + movl $" NR_dyn_sys ",%eax \n\ + movl $2f,%edx \n\ + leal 12(%esp),%ecx \n\ + int $0x80 \n\ + 1: \n\ + popl %edx \n\ + popl %ecx \n\ + ret \n\ + .size v" #name ",.-v" #name " \n\ + .section .data.vsyscall_list,\"a\" \n\ + 2: .long 1b," #name " \n\ + .previous") + +#endif diff -urN linux.wrk.orig/include/linux/sched.h linux.wrk/include/linux/sched.h --- linux.wrk.orig/include/linux/sched.h Mon Jan 21 15:13:17 2002 +++ linux.wrk/include/linux/sched.h Mon Jan 21 15:17:06 2002 @@ -238,6 +238,7 @@ struct kioctx *ioctx_list; unsigned long new_ioctx_id; + int vsys_mapped; }; extern int mmlist_nr; @@ -253,6 +254,7 @@ map_count: 1, \ mmap_sem: __RWSEM_INITIALIZER(name.mmap_sem), \ page_table_lock: SPIN_LOCK_UNLOCKED, \ + vsys_mapped: 0, \ mmlist: LIST_HEAD_INIT(name.mmlist), \ } diff -urN linux.wrk.orig/include/linux/vsyscall.h linux.wrk/include/linux/vsyscall.h --- linux.wrk.orig/include/linux/vsyscall.h Wed Dec 31 19:00:00 1969 +++ linux.wrk/include/linux/vsyscall.h Mon Jan 21 15:17:06 2002 @@ -0,0 +1,20 @@ +#ifndef _LINUX__VSYSCALL_H +#define _LINUX__VSYSCALL_H + +struct vsys_cpudata { + unsigned long context_switches; + unsigned long tv_sec; + unsigned long tsc_low, tsc_high; + unsigned long cycles_per_sec; +}; + +union vsys_union { + struct vsys_cpudata data; + char pad[128]; +}; + +extern union vsys_union vsys_cpudata[256] __attribute__((section(".data.vsyscall"))); + +#define vsys_data(cpu) (&vsys_cpudata[cpu].data) + +#endif /*ndef _LINUX__VSYSCALL_H*/ diff -urN linux.wrk.orig/ulib/Makefile linux.wrk/ulib/Makefile --- linux.wrk.orig/ulib/Makefile Wed Dec 31 19:00:00 1969 +++ linux.wrk/ulib/Makefile Mon Jan 21 15:17:06 2002 @@ -0,0 +1,30 @@ +all: libredhat-kernel.so + +ASFLAGS=-D__KERNEL__ -D__ASSEMBLY__ -I../include -nostdlib -nostartfiles +CFLAGS=-D__KERNEL__ -I../include -nostdlib -nostartfiles + +so_objs=vsysaddr.o kso_init.o + +vsysaddr.S: ../System.map stub.S Makefile + rm -f vsysaddr.S + echo '#include "stub.S"' >vsysaddr.S + awk -- "/^bfff.* vsys_/ { print \"dynamic_syscall(\"\$$3 \",0x\" \$$1 \")\"; }" <../System.map >>vsysaddr.S + +vsysaddr.o: vsysaddr.S + +kso_init.o: ../include/linux/compile.h + +libredhat-kernel.so.1: $(so_objs) libredhat-kernel.map + gcc -nostdlib -nostartfiles -shared -Wl,--version-script=libredhat-kernel.map -Wl,-soname=libredhat-kernel.so.1 -o $@ $(so_objs) + cp $@ $@.save + strip $@ + +libredhat-kernel.so: libredhat-kernel.so.1 + ln -sf $< $@ + +clean: + rm -f *.o libredhat-kernel.so myln libredhat-kernel.so.1 vsysaddr.S libredhat-kernel.so.1.save + +# test app +myln: myln.c libredhat-kernel.so Makefile + cc -g -o myln myln.c -L. -lredhat-kernel diff -urN linux.wrk.orig/ulib/kso_init.c linux.wrk/ulib/kso_init.c --- linux.wrk.orig/ulib/kso_init.c Wed Dec 31 19:00:00 1969 +++ linux.wrk/ulib/kso_init.c Mon Jan 21 15:17:06 2002 @@ -0,0 +1,48 @@ +#include +#include +#include +#include +#include +#include + +char libredhat_kernel_enosys = 1; /* the asm in stub.S depends on this */ + +long _init(void) +{ + static char unique[] = { LINUX_UNIQUE_BYTES }; + int errno; + long addr; + int fd; + int i; + + _syscall6(int, mmap2, unsigned long, addr, unsigned long, len, + unsigned long, prot, unsigned long, flags, + unsigned long, fd, unsigned long, pgoff) + _syscall2(long, munmap, unsigned long, addr, size_t, len) + _syscall2(int, open, const char *, name, int, flags) + _syscall1(int, close, int, fd) + + if (sizeof(unique) != 16) + return -1; + + fd = open("/dev/vsys", O_RDONLY); + if (-1 == fd) + return -1; + + addr = mmap2(0, VSYSCALL_SIZE, PROT_READ | PROT_EXEC, MAP_SHARED, fd, 0); + if (-1 == addr) + return -1; + + close(fd); + + for (i=0; i +#include +#include +#include +#include + +int main () +{ + long ctx = 0; + extern long vsys_io_setup(long, long *); + unsigned char *bob = (void*)&vsys_io_setup; + long ret; + int i; + printf("%p\n", bob); + //printf("%p\n", mmap(0, 65536, PROT_READ | PROT_EXEC, MAP_SHARED, + // open("/dev/vsys", O_RDONLY), 0)); + //for (i=0; i<16; i++) + // printf(" %02x\n", bob[i]); + //printf("\n"); + + ret = vsys_io_setup(100, &ctx); + + printf("ret=%ld, ctx=0x%lx\n", ret, ctx); + return 0; +} diff -urN linux.wrk.orig/ulib/stub.S linux.wrk/ulib/stub.S --- linux.wrk.orig/ulib/stub.S Wed Dec 31 19:00:00 1969 +++ linux.wrk/ulib/stub.S Mon Jan 21 15:17:06 2002 @@ -0,0 +1,19 @@ +/* stub.S */ +#include +#include + + .text + +#define dynamic_syscall(x,a) \ + .globl x ;\ + .type x, @function ;\ + .align 16 ;\ + x: ;\ + cmpb $0,libredhat_kernel_enosys ;\ + jne 1f ;\ + ljmp $__USER_CS, $a ;\ + 1: ;\ + movl $-ENOSYS,%eax ;\ + ret ;\ + .size x,.-x + --- linux/fs/aio.c~ Sun Feb 3 11:50:04 2002 +++ linux/fs/aio.c Sun Feb 3 11:55:27 2002 @@ -37,6 +37,7 @@ #include #include #include +#include #include #include