summaryrefslogtreecommitdiff
path: root/kernel
diff options
context:
space:
mode:
Diffstat (limited to 'kernel')
-rw-r--r--kernel/ChangeLog14
-rw-r--r--kernel/sysctl/patch-2.2.181
-rw-r--r--kernel/table.h188
-rw-r--r--kernel/table20/Makefile13
-rw-r--r--kernel/table20/README21
-rw-r--r--kernel/table20/entry-i386.S706
-rw-r--r--kernel/table20/kernel.patch51
-rw-r--r--kernel/table20/main.c468
-rw-r--r--kernel/table20/unistd-i386.h324
-rw-r--r--kernel/table20/version.h1
-rw-r--r--kernel/table21/.cvsignore4
-rw-r--r--kernel/table21/Makefile16
-rw-r--r--kernel/table21/README21
-rw-r--r--kernel/table21/entry-i386.S571
-rw-r--r--kernel/table21/main.c61
-rw-r--r--kernel/table21/module.c607
-rw-r--r--kernel/table21/unistd-i386.h344
-rw-r--r--kernel/table21/version.h1
-rw-r--r--kernel/version.h1
19 files changed, 3493 insertions, 0 deletions
diff --git a/kernel/ChangeLog b/kernel/ChangeLog
new file mode 100644
index 00000000..a3efd8d7
--- /dev/null
+++ b/kernel/ChangeLog
@@ -0,0 +1,14 @@
+1998-07-21 Martin Baulig <martin@home-of-linux.org>
+
+ * table20: New directory for 2.0.xx kernels.
+
+ * table21: New directory for 2.1.xx kernels.
+
+ * *: Moved into `table20' and `table21'.
+
+1998-06-14 Martin Baulig <baulig@taurus.uni-trier.de>
+
+ * README: Added README.
+
+ * kernel.patch: Patch for the Linux kernel to add the
+ new system call.
diff --git a/kernel/sysctl/patch-2.2.1 b/kernel/sysctl/patch-2.2.1
new file mode 100644
index 00000000..1781b921
--- /dev/null
+++ b/kernel/sysctl/patch-2.2.1
@@ -0,0 +1,81 @@
+diff -ru linux-2.2.1/Makefile hacker/Makefile
+--- linux-2.2.1/Makefile Sun Jan 31 22:45:42 1999
++++ hacker/Makefile Sun Mar 21 16:10:41 1999
+@@ -109,6 +109,7 @@
+ DRIVERS =drivers/block/block.a \
+ drivers/char/char.a \
+ drivers/misc/misc.a
++EXTRAS =
+ LIBS =$(TOPDIR)/lib/lib.a
+ SUBDIRS =kernel drivers mm fs net ipc lib
+
+@@ -186,6 +187,11 @@
+ DRIVERS := $(DRIVERS) drivers/net/irda/irda_drivers.a
+ endif
+
++ifdef CONFIG_LIBGTOP
++SUBDIRS := $(SUBDIRS) libgtop
++EXTRAS := $(EXTRAS) libgtop/kernel.o
++endif
++
+ include arch/$(ARCH)/Makefile
+
+ .S.s:
+@@ -206,6 +212,7 @@
+ $(FILESYSTEMS) \
+ $(NETWORKS) \
+ $(DRIVERS) \
++ $(EXTRAS) \
+ $(LIBS) \
+ --end-group \
+ -o vmlinux
+diff -ru linux-2.2.1/arch/i386/config.in hacker/arch/i386/config.in
+--- linux-2.2.1/arch/i386/config.in Sun Jan 31 22:25:25 1999
++++ hacker/arch/i386/config.in Sat Mar 20 18:26:18 1999
+@@ -84,6 +84,9 @@
+ bool 'System V IPC' CONFIG_SYSVIPC
+ bool 'BSD Process Accounting' CONFIG_BSD_PROCESS_ACCT
+ bool 'Sysctl support' CONFIG_SYSCTL
++if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then
++ tristate 'LibGTop support' CONFIG_LIBGTOP
++fi
+ tristate 'Kernel support for a.out binaries' CONFIG_BINFMT_AOUT
+ tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF
+ tristate 'Kernel support for MISC binaries' CONFIG_BINFMT_MISC
+diff -ru linux-2.2.1/include/linux/sysctl.h hacker/include/linux/sysctl.h
+--- linux-2.2.1/include/linux/sysctl.h Sun Jan 31 22:24:14 1999
++++ hacker/include/linux/sysctl.h Sat Mar 20 19:12:54 1999
+@@ -56,7 +56,8 @@
+ CTL_PROC=4, /* Process info */
+ CTL_FS=5, /* Filesystems */
+ CTL_DEBUG=6, /* Debugging */
+- CTL_DEV=7 /* Devices */
++ CTL_DEV=7, /* Devices */
++ CTL_LIBGTOP=408 /* LibGTop */
+ };
+
+
+diff -ru linux-2.2.1/kernel/sysctl.c hacker/kernel/sysctl.c
+--- linux-2.2.1/kernel/sysctl.c Sun Jan 31 22:24:43 1999
++++ hacker/kernel/sysctl.c Sat Mar 20 19:24:34 1999
+@@ -82,7 +82,9 @@
+ static ctl_table fs_table[];
+ static ctl_table debug_table[];
+ static ctl_table dev_table[];
+-
++#ifdef CONFIG_LIBGTOP
++extern ctl_table libgtop_table[];
++#endif
+
+ /* /proc declarations: */
+
+@@ -148,6 +150,9 @@
+ {CTL_FS, "fs", NULL, 0, 0555, fs_table},
+ {CTL_DEBUG, "debug", NULL, 0, 0555, debug_table},
+ {CTL_DEV, "dev", NULL, 0, 0555, dev_table},
++#ifdef CONFIG_LIBGTOP
++ {CTL_LIBGTOP, "libgtop", NULL, 0, 0555, libgtop_table},
++#endif
+ {0}
+ };
+
diff --git a/kernel/table.h b/kernel/table.h
new file mode 100644
index 00000000..d4959370
--- /dev/null
+++ b/kernel/table.h
@@ -0,0 +1,188 @@
+#ifndef _LINUX_TABLE_H
+#define _LINUX_TABLE_H
+
+#ifdef _KERNEL
+#include <linux/types.h>
+#else
+#define NR_TASKS 512
+#endif
+
+#define TABLE_KERN_PROC_ALL 0 /* all processes */
+#define TABLE_KERN_PROC_PID 1
+#define TABLE_KERN_PROC_PGRP 2
+#define TABLE_KERN_PROC_SESSION 3
+#define TABLE_KERN_PROC_TTY 4
+#define TABLE_KERN_PROC_UID 5
+#define TABLE_KERN_PROC_RUID 6
+
+#define TABLE_KERN_PROC_MASK 15
+
+#define TABLE_EXCLUDE_IDLE 0x1000
+#define TABLE_EXCLUDE_SYSTEM 0x2000
+#define TABLE_EXCLUDE_NOTTY 0x4000
+
+#define TABLE_VERSION 0
+#define TABLE_CPU 1
+#define TABLE_MEM 2
+#define TABLE_SWAP 3
+#define TABLE_LOADAVG 4
+#define TABLE_UPTIME 5
+#define TABLE_PROCLIST 6
+#define TABLE_PROC_UID 7
+#define TABLE_PROC_MEM 8
+#define TABLE_PROC_SEGMENT 9
+#define TABLE_PROC_TIME 10
+#define TABLE_PROC_STATE 11
+#define TABLE_PROC_SIGNAL 12
+#define TABLE_PROC_KERNEL 13
+
+/* CPU Usage (in jiffies = 1/100th seconds) */
+
+struct table_cpu
+{
+ unsigned long total; /* Total CPU Time */
+ unsigned long user; /* CPU Time in User Mode */
+ unsigned long nice; /* CPU Time in User Mode (nice) */
+ unsigned long sys; /* CPU Time in System Mode */
+ unsigned long idle; /* CPU Time in the Idle Task */
+ unsigned long frequency; /* Tick frequency */
+};
+
+/* Memory Usage (in bytes) */
+
+struct table_mem
+{
+ unsigned long total; /* Total physical memory */
+ unsigned long used; /* Used memory size */
+ unsigned long free; /* Free memory size */
+ unsigned long shared; /* Shared memory size */
+ unsigned long buffer; /* Size of buffers */
+ unsigned long cached; /* Size of cached memory */
+};
+
+/* Swap Space (in bytes) */
+
+struct table_swap
+{
+ unsigned long total; /* Total swap space */
+ unsigned long used; /* Used swap space */
+ unsigned long free; /* Free swap space */
+ unsigned long pagein; /* Total # of pages swapped in */
+ unsigned long pageout; /* Total # of pages swapped out */
+};
+
+/* Load average */
+
+struct table_loadavg
+{
+ double loadavg [3];
+ unsigned nr_running;
+ unsigned nr_tasks;
+ unsigned last_pid;
+};
+
+/* Uptime */
+
+struct table_uptime
+{
+ unsigned long uptime;
+ unsigned long idle;
+};
+
+/* Process list. */
+
+struct proclist_args
+{
+ int which, arg;
+};
+
+struct table_proclist
+{
+ int nr_running, nr_tasks, last_pid;
+ unsigned pids [NR_TASKS];
+};
+
+/* Information about processes. */
+
+struct table_proc_state
+{
+ long state;
+ unsigned long flags;
+ char comm[16];
+ int uid, gid;
+};
+
+struct table_proc_uid
+{
+ int uid, euid, suid, fsuid;
+ int gid, egid, sgid, fsgid;
+ int pid, pgrp, ppid;
+ int session;
+ unsigned int tty;
+ int tpgid;
+ long priority;
+ long counter;
+ long def_priority;
+};
+
+struct table_proc_mem
+{
+ unsigned long context;
+ unsigned long start_code, end_code, start_data, end_data;
+ unsigned long start_brk, brk, start_stack, start_mmap;
+ unsigned long arg_start, arg_end, env_start, env_end;
+ unsigned long rss, rlim, total_vm, locked_vm;
+};
+
+struct table_proc_segment
+{
+ unsigned long vsize;
+ unsigned long size, resident, shared;
+ unsigned long trs, lrs, drs, srs, dt;
+};
+
+struct table_proc_time
+{
+ long utime, stime, cutime, cstime, start_time;
+ unsigned long timeout, policy, rt_priority;
+ unsigned long it_real_value, it_prof_value, it_virt_value;
+ unsigned long it_real_incr, it_prof_incr, it_virt_incr;
+};
+
+struct table_proc_signal
+{
+ unsigned long long signal,
+ blocked, /* bitmap of masked signals */
+ ignored, /* mask of ignored signals */
+ caught; /* mask of caught signals */
+};
+
+struct table_proc_kernel
+{
+ unsigned long keip, kesp, wchan;
+ unsigned long min_flt, maj_flt, cmin_flt, cmaj_flt;
+ unsigned long nswap, cnswap;
+};
+
+/* Union */
+
+union table
+{
+ struct table_cpu cpu;
+ struct table_mem mem;
+ struct table_swap swap;
+ struct table_loadavg loadavg;
+ struct table_uptime uptime;
+ struct table_proclist proclist;
+ struct table_proc_uid proc_uid;
+ struct table_proc_mem proc_mem;
+ struct table_proc_segment proc_segment;
+ struct table_proc_time proc_time;
+ struct table_proc_state proc_state;
+ struct table_proc_signal proc_signal;
+ struct table_proc_kernel proc_kernel;
+};
+
+#endif /* _LINUX_IPC_H */
+
+
diff --git a/kernel/table20/Makefile b/kernel/table20/Makefile
new file mode 100644
index 00000000..d24e3ba8
--- /dev/null
+++ b/kernel/table20/Makefile
@@ -0,0 +1,13 @@
+#
+# Makefile for the linux system information tables.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET := table.o
+O_OBJS := main.o
+
+include $(TOPDIR)/Rules.make
diff --git a/kernel/table20/README b/kernel/table20/README
new file mode 100644
index 00000000..88d26bec
--- /dev/null
+++ b/kernel/table20/README
@@ -0,0 +1,21 @@
+This is a new system call `table ()' for the Linux table. It is faster
+than reading from /proc and can be used to fetch all information required
+for libgtop until whe have some other function (extended sysctl, ...) in
+standard kernels.
+
+I didn't want to change sysctl or some other function myself cause this may
+cause other applications relying upon those function to fail. This is
+something for the ``real'' kernel gurus ...
+
+To use this new system call for libgtop, do the following:
+
+* Copy this directory to /usr/src/linux/table
+* Make /usr/src/linux/include/linux/table.h symlink to /usr/src/linux/table/table.h
+* Apply the patch `kernel.patch' to the kernel, compile, install and reboot
+* Recompile libgtop (remove `config.cache' and run the `autogen.sh' again).
+
+If you want to change and/or add something - feel free to do so !
+
+Have fun,
+
+Martin
diff --git a/kernel/table20/entry-i386.S b/kernel/table20/entry-i386.S
new file mode 100644
index 00000000..994fe27c
--- /dev/null
+++ b/kernel/table20/entry-i386.S
@@ -0,0 +1,706 @@
+/*
+ * linux/arch/i386/entry.S
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ */
+
+/*
+ * entry.S contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all interrupts
+ * and faults that can result in a task-switch.
+ *
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ *
+ * I changed all the .align's to 4 (16 byte alignment), as that's faster
+ * on a 486.
+ *
+ * Stack layout in 'ret_from_system_call':
+ * ptrace needs to have all regs on the stack.
+ * if the order here is changed, it needs to be
+ * updated in fork.c:copy_process, signal.c:do_signal,
+ * ptrace.c and ptrace.h
+ *
+ * 0(%esp) - %ebx
+ * 4(%esp) - %ecx
+ * 8(%esp) - %edx
+ * C(%esp) - %esi
+ * 10(%esp) - %edi
+ * 14(%esp) - %ebp
+ * 18(%esp) - %eax
+ * 1C(%esp) - %ds
+ * 20(%esp) - %es
+ * 24(%esp) - %fs
+ * 28(%esp) - %gs
+ * 2C(%esp) - orig_eax
+ * 30(%esp) - %eip
+ * 34(%esp) - %cs
+ * 38(%esp) - %eflags
+ * 3C(%esp) - %oldesp
+ * 40(%esp) - %oldss
+ */
+
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/segment.h>
+#define ASSEMBLY
+#include <asm/smp.h>
+
+EBX = 0x00
+ECX = 0x04
+EDX = 0x08
+ESI = 0x0C
+EDI = 0x10
+EBP = 0x14
+EAX = 0x18
+DS = 0x1C
+ES = 0x20
+FS = 0x24
+GS = 0x28
+ORIG_EAX = 0x2C
+EIP = 0x30
+CS = 0x34
+EFLAGS = 0x38
+OLDESP = 0x3C
+OLDSS = 0x40
+
+CF_MASK = 0x00000001
+IF_MASK = 0x00000200
+NT_MASK = 0x00004000
+VM_MASK = 0x00020000
+
+/*
+ * these are offsets into the task-struct.
+ */
+state = 0
+counter = 4
+priority = 8
+signal = 12
+blocked = 16
+flags = 20
+dbgreg6 = 52
+dbgreg7 = 56
+exec_domain = 60
+
+ENOSYS = 38
+
+#define SAVE_ALL \
+ cld; \
+ push %gs; \
+ push %fs; \
+ push %es; \
+ push %ds; \
+ pushl %eax; \
+ pushl %ebp; \
+ pushl %edi; \
+ pushl %esi; \
+ pushl %edx; \
+ pushl %ecx; \
+ pushl %ebx; \
+ movl $(KERNEL_DS),%edx; \
+ mov %dx,%ds; \
+ mov %dx,%es; \
+ movl $(USER_DS),%edx; \
+ mov %dx,%fs;
+
+#ifdef __SMP__
+
+#define GET_PROCESSOR_ID \
+ movl SYMBOL_NAME(apic_reg), %edx; \
+ movl 32(%edx), %eax;\
+ movl %eax,SYMBOL_NAME(apic_retval); \
+ shrl $24,%eax; \
+ andb $0x0F,%al;
+
+/*
+ * Get the processor ID multiplied by 4
+ */
+
+#define GET_PROCESSOR_OFFSET(x) \
+ movl SYMBOL_NAME(apic_reg), x ; \
+ movl 32( x ), x ; \
+ shrl $22, x ; \
+ andl $0x3C, x ;
+
+/* macro LEAVE_KERNEL decrements kernel_counter and resets kernel_flag and
+ saves processor variables if zero */
+#define LEAVE_KERNEL \
+ pushfl; \
+ cli; \
+ GET_PROCESSOR_ID \
+ btrl $ SMP_FROM_SYSCALL,SYMBOL_NAME(smp_proc_in_lock)(,%eax,4); \
+ decl SYMBOL_NAME(syscall_count); \
+ decl SYMBOL_NAME(kernel_counter); \
+ jnz 1f; \
+ movb SYMBOL_NAME(saved_active_kernel_processor), %al; \
+ movb %al, SYMBOL_NAME(active_kernel_processor); \
+ cmpb $(NO_PROC_ID), %al; \
+ jnz 1f; \
+ lock; \
+ btrl $0, SYMBOL_NAME(kernel_flag); \
+1: popfl;
+
+/* macro ENTER_KERNEL waits for entering the kernel, increments
+ kernel_counter, and reloads the processor variables if necessary
+ uses : %eax, %edx (pushed and popped)
+
+ Note: We go to great pains to minimise the number of locked operations.
+ We want to spin without locking, and lock when we attempt an update.
+ The pentium has a MESI cache so the spin without lock will exit when
+ another CPU write invalidates our cache, and the lock is avoided when
+ possible so we don't play ping-pong games with the cache line.
+
+*/
+
+#ifndef __SMP_PROF__
+
+#define SMP_PROF_A
+#define SMP_PROF_B
+
+#else
+
+#define SMP_PROF_A movl $0,SYMBOL_NAME(smp_spins_syscall_cur)(,%eax,4);
+#define SMP_PROF_B incl SYMBOL_NAME(smp_spins_syscall)(,%eax,4); \
+ incl SYMBOL_NAME(smp_spins_syscall_cur)(,%eax,4);
+#endif
+
+#define ENTER_KERNEL \
+ pushl %eax; \
+ pushl %ebx; \
+ pushl %ecx; \
+ pushl %edx; \
+ pushfl; \
+ cli; \
+ movl $6000, %ebx; \
+ movl SYMBOL_NAME(smp_loops_per_tick), %ecx; \
+ GET_PROCESSOR_ID \
+ btsl $ SMP_FROM_SYSCALL,SYMBOL_NAME(smp_proc_in_lock)(,%eax,4); \
+ SMP_PROF_A \
+1: lock; \
+ btsl $0, SYMBOL_NAME(kernel_flag); \
+ jnc 3f; \
+ cmpb SYMBOL_NAME(active_kernel_processor), %al; \
+ je 4f; \
+2: SMP_PROF_B \
+ btl %eax, SYMBOL_NAME(smp_invalidate_needed); \
+ jnc 5f; \
+ lock; \
+ btrl %eax, SYMBOL_NAME(smp_invalidate_needed); \
+ jnc 5f; \
+ movl %cr3,%edx; \
+ movl %edx,%cr3; \
+5: sti; \
+ decl %ecx; \
+ cli; \
+ jne 7f; \
+ decl %ebx; \
+ jne 6f; \
+ call SYMBOL_NAME(non_irq_deadlock_detected); \
+6: movl SYMBOL_NAME(smp_loops_per_tick), %ecx; \
+ cmpb SYMBOL_NAME(boot_cpu_id), %al; \
+ jne 7f; \
+ incl SYMBOL_NAME(jiffies); \
+7: btl $0, SYMBOL_NAME(kernel_flag); \
+ jc 2b; \
+ jmp 1b; \
+3: movb %al, SYMBOL_NAME(active_kernel_processor); \
+4: incl SYMBOL_NAME(kernel_counter); \
+ incl SYMBOL_NAME(syscall_count); \
+ popfl; \
+ popl %edx; \
+ popl %ecx; \
+ popl %ebx; \
+ popl %eax;
+
+
+#define RESTORE_ALL \
+ cmpw $(KERNEL_CS),CS(%esp); \
+ je 1f; \
+ GET_PROCESSOR_OFFSET(%edx) \
+ movl SYMBOL_NAME(current_set)(,%edx), %eax ; ; \
+ movl dbgreg7(%eax),%ebx; \
+ movl %ebx,%db7; \
+1: LEAVE_KERNEL \
+ popl %ebx; \
+ popl %ecx; \
+ popl %edx; \
+ popl %esi; \
+ popl %edi; \
+ popl %ebp; \
+ popl %eax; \
+ pop %ds; \
+ pop %es; \
+ pop %fs; \
+ pop %gs; \
+ addl $4,%esp; \
+ iret
+
+#else
+
+#define RESTORE_ALL \
+ cmpw $(KERNEL_CS),CS(%esp); \
+ je 1f; \
+ movl SYMBOL_NAME(current_set),%eax; \
+ movl dbgreg7(%eax),%ebx; \
+ movl %ebx,%db7; \
+1: \
+ popl %ebx; \
+ popl %ecx; \
+ popl %edx; \
+ popl %esi; \
+ popl %edi; \
+ popl %ebp; \
+ popl %eax; \
+ pop %ds; \
+ pop %es; \
+ pop %fs; \
+ pop %gs; \
+ addl $4,%esp; \
+ iret
+#endif
+
+ENTRY(lcall7)
+ pushfl # We get a different stack layout with call gates,
+ pushl %eax # which has to be cleaned up later..
+ SAVE_ALL
+#ifdef __SMP__
+ ENTER_KERNEL
+#endif
+ movl EIP(%esp),%eax # due to call gates, this is eflags, not eip..
+ movl CS(%esp),%edx # this is eip..
+ movl EFLAGS(%esp),%ecx # and this is cs..
+ movl %eax,EFLAGS(%esp) #
+ movl %edx,EIP(%esp) # Now we move them to their "normal" places
+ movl %ecx,CS(%esp) #
+ movl %esp,%eax
+#ifdef __SMP__
+ GET_PROCESSOR_OFFSET(%edx) # Processor offset into edx
+ movl SYMBOL_NAME(current_set)(,%edx),%edx
+#else
+ movl SYMBOL_NAME(current_set),%edx
+#endif
+ pushl %eax
+ movl exec_domain(%edx),%edx # Get the execution domain
+ movl 4(%edx),%edx # Get the lcall7 handler for the domain
+ call *%edx
+ popl %eax
+ jmp ret_from_sys_call
+
+ ALIGN
+handle_bottom_half:
+ incl SYMBOL_NAME(intr_count)
+ call SYMBOL_NAME(do_bottom_half)
+ decl SYMBOL_NAME(intr_count)
+ jmp 9f
+ ALIGN
+reschedule:
+ pushl $ret_from_sys_call
+ jmp SYMBOL_NAME(schedule) # test
+
+ENTRY(system_call)
+ pushl %eax # save orig_eax
+ SAVE_ALL
+#ifdef __SMP__
+ ENTER_KERNEL
+#endif
+ movl $-ENOSYS,EAX(%esp)
+ cmpl $(NR_syscalls),%eax
+ jae ret_from_sys_call
+ movl SYMBOL_NAME(sys_call_table)(,%eax,4),%eax
+ testl %eax,%eax
+ je ret_from_sys_call
+#ifdef __SMP__
+ GET_PROCESSOR_OFFSET(%edx)
+ movl SYMBOL_NAME(current_set)(,%edx),%ebx
+#else
+ movl SYMBOL_NAME(current_set),%ebx
+#endif
+ andl $~CF_MASK,EFLAGS(%esp) # clear carry - assume no errors
+ movl %db6,%edx
+ movl %edx,dbgreg6(%ebx) # save current hardware debugging status
+ testb $0x20,flags(%ebx) # PF_TRACESYS
+ jne 1f
+ call *%eax
+ movl %eax,EAX(%esp) # save the return value
+ jmp ret_from_sys_call
+ ALIGN
+1: call SYMBOL_NAME(syscall_trace)
+ movl ORIG_EAX(%esp),%eax
+ call SYMBOL_NAME(sys_call_table)(,%eax,4)
+ movl %eax,EAX(%esp) # save the return value
+#ifdef __SMP__
+ GET_PROCESSOR_OFFSET(%eax)
+ movl SYMBOL_NAME(current_set)(,%eax),%eax
+#else
+ movl SYMBOL_NAME(current_set),%eax
+#endif
+ call SYMBOL_NAME(syscall_trace)
+
+ ALIGN
+ .globl ret_from_sys_call
+ret_from_sys_call:
+ cmpl $0,SYMBOL_NAME(intr_count)
+ jne 2f
+9: movl SYMBOL_NAME(bh_mask),%eax
+ andl SYMBOL_NAME(bh_active),%eax
+ jne handle_bottom_half
+#ifdef __SMP__
+ cmpb $(NO_PROC_ID), SYMBOL_NAME(saved_active_kernel_processor)
+ jne 2f
+#endif
+ movl EFLAGS(%esp),%eax # check VM86 flag: CS/SS are
+ testl $(VM_MASK),%eax # different then
+ jne 1f
+ cmpw $(KERNEL_CS),CS(%esp) # was old code segment supervisor ?
+ je 2f
+1: sti
+ orl $(IF_MASK),%eax # these just try to make sure
+ andl $~NT_MASK,%eax # the program doesn't do anything
+ movl %eax,EFLAGS(%esp) # stupid
+ cmpl $0,SYMBOL_NAME(need_resched)
+ jne reschedule
+#ifdef __SMP__
+ GET_PROCESSOR_OFFSET(%eax)
+ movl SYMBOL_NAME(current_set)(,%eax), %eax
+#else
+ movl SYMBOL_NAME(current_set),%eax
+#endif
+ cmpl SYMBOL_NAME(task),%eax # task[0] cannot have signals
+ je 2f
+ movl blocked(%eax),%ecx
+ movl %ecx,%ebx # save blocked in %ebx for signal handling
+ notl %ecx
+ andl signal(%eax),%ecx
+ jne signal_return
+2: RESTORE_ALL
+ ALIGN
+signal_return:
+ movl %esp,%ecx
+ pushl %ecx
+ testl $(VM_MASK),EFLAGS(%ecx)
+ jne v86_signal_return
+ pushl %ebx
+ call SYMBOL_NAME(do_signal)
+ popl %ebx
+ popl %ebx
+ RESTORE_ALL
+ ALIGN
+v86_signal_return:
+ call SYMBOL_NAME(save_v86_state)
+ movl %eax,%esp
+ pushl %eax
+ pushl %ebx
+ call SYMBOL_NAME(do_signal)
+ popl %ebx
+ popl %ebx
+ RESTORE_ALL
+
+ENTRY(divide_error)
+ pushl $0 # no error code
+ pushl $ SYMBOL_NAME(do_divide_error)
+ ALIGN
+error_code:
+ push %fs
+ push %es
+ push %ds
+ pushl %eax
+ xorl %eax,%eax
+ pushl %ebp
+ pushl %edi
+ pushl %esi
+ pushl %edx
+ decl %eax # eax = -1
+ pushl %ecx
+ pushl %ebx
+ cld
+ xorl %ebx,%ebx # zero ebx
+ xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. )
+ mov %gs,%bx # get the lower order bits of gs
+ movl %esp,%edx
+ xchgl %ebx, GS(%esp) # get the address and save gs.
+ pushl %eax # push the error code
+ pushl %edx
+ movl $(KERNEL_DS),%edx
+ mov %dx,%ds
+ mov %dx,%es
+ movl $(USER_DS),%edx
+ mov %dx,%fs
+#ifdef __SMP__
+ ENTER_KERNEL
+ GET_PROCESSOR_OFFSET(%eax)
+ movl SYMBOL_NAME(current_set)(,%eax), %eax
+#else
+ movl SYMBOL_NAME(current_set),%eax
+#endif
+ movl %db6,%edx
+ movl %edx,dbgreg6(%eax) # save current hardware debugging status
+ call *%ebx
+ addl $8,%esp
+ jmp ret_from_sys_call
+
+ENTRY(coprocessor_error)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_coprocessor_error)
+ jmp error_code
+
+ENTRY(device_not_available)
+ pushl $-1 # mark this as an int
+ SAVE_ALL
+#ifdef __SMP__
+ ENTER_KERNEL
+#endif
+ pushl $ret_from_sys_call
+ movl %cr0,%eax
+ testl $0x4,%eax # EM (math emulation bit)
+ je SYMBOL_NAME(math_state_restore)
+ pushl $0 # temporary storage for ORIG_EIP
+ call SYMBOL_NAME(math_emulate)
+ addl $4,%esp
+ ret
+
+ENTRY(debug)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_debug)
+ jmp error_code
+
+ENTRY(nmi)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_nmi)
+ jmp error_code
+
+ENTRY(int3)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_int3)
+ jmp error_code
+
+ENTRY(overflow)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_overflow)
+ jmp error_code
+
+ENTRY(bounds)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_bounds)
+ jmp error_code
+
+ENTRY(invalid_op)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_invalid_op)
+ jmp error_code
+
+ENTRY(coprocessor_segment_overrun)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_coprocessor_segment_overrun)
+ jmp error_code
+
+ENTRY(reserved)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_reserved)
+ jmp error_code
+
+ENTRY(double_fault)
+ pushl $ SYMBOL_NAME(do_double_fault)
+ jmp error_code
+
+ENTRY(invalid_TSS)
+ pushl $ SYMBOL_NAME(do_invalid_TSS)
+ jmp error_code
+
+ENTRY(segment_not_present)
+ pushl $ SYMBOL_NAME(do_segment_not_present)
+ jmp error_code
+
+ENTRY(stack_segment)
+ pushl $ SYMBOL_NAME(do_stack_segment)
+ jmp error_code
+
+ENTRY(general_protection)
+ pushl $ SYMBOL_NAME(do_general_protection)
+ jmp error_code
+
+ENTRY(alignment_check)
+ pushl $ SYMBOL_NAME(do_alignment_check)
+ jmp error_code
+
+ENTRY(page_fault)
+ pushl $ SYMBOL_NAME(do_page_fault)
+ jmp error_code
+
+ENTRY(spurious_interrupt_bug)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_spurious_interrupt_bug)
+ jmp error_code
+
+.data
+ENTRY(sys_call_table)
+ .long SYMBOL_NAME(sys_setup) /* 0 */
+ .long SYMBOL_NAME(sys_exit)
+ .long SYMBOL_NAME(sys_fork)
+ .long SYMBOL_NAME(sys_read)
+ .long SYMBOL_NAME(sys_write)
+ .long SYMBOL_NAME(sys_open) /* 5 */
+ .long SYMBOL_NAME(sys_close)
+ .long SYMBOL_NAME(sys_waitpid)
+ .long SYMBOL_NAME(sys_creat)
+ .long SYMBOL_NAME(sys_link)
+ .long SYMBOL_NAME(sys_unlink) /* 10 */
+ .long SYMBOL_NAME(sys_execve)
+ .long SYMBOL_NAME(sys_chdir)
+ .long SYMBOL_NAME(sys_time)
+ .long SYMBOL_NAME(sys_mknod)
+ .long SYMBOL_NAME(sys_chmod) /* 15 */
+ .long SYMBOL_NAME(sys_chown)
+ .long SYMBOL_NAME(sys_break)
+ .long SYMBOL_NAME(sys_stat)
+ .long SYMBOL_NAME(sys_lseek)
+ .long SYMBOL_NAME(sys_getpid) /* 20 */
+ .long SYMBOL_NAME(sys_mount)
+ .long SYMBOL_NAME(sys_umount)
+ .long SYMBOL_NAME(sys_setuid)
+ .long SYMBOL_NAME(sys_getuid)
+ .long SYMBOL_NAME(sys_stime) /* 25 */
+ .long SYMBOL_NAME(sys_ptrace)
+ .long SYMBOL_NAME(sys_alarm)
+ .long SYMBOL_NAME(sys_fstat)
+ .long SYMBOL_NAME(sys_pause)
+ .long SYMBOL_NAME(sys_utime) /* 30 */
+ .long SYMBOL_NAME(sys_stty)
+ .long SYMBOL_NAME(sys_gtty)
+ .long SYMBOL_NAME(sys_access)
+ .long SYMBOL_NAME(sys_nice)
+ .long SYMBOL_NAME(sys_ftime) /* 35 */
+ .long SYMBOL_NAME(sys_sync)
+ .long SYMBOL_NAME(sys_kill)
+ .long SYMBOL_NAME(sys_rename)
+ .long SYMBOL_NAME(sys_mkdir)
+ .long SYMBOL_NAME(sys_rmdir) /* 40 */
+ .long SYMBOL_NAME(sys_dup)
+ .long SYMBOL_NAME(sys_pipe)
+ .long SYMBOL_NAME(sys_times)
+ .long SYMBOL_NAME(sys_prof)
+ .long SYMBOL_NAME(sys_brk) /* 45 */
+ .long SYMBOL_NAME(sys_setgid)
+ .long SYMBOL_NAME(sys_getgid)
+ .long SYMBOL_NAME(sys_signal)
+ .long SYMBOL_NAME(sys_geteuid)
+ .long SYMBOL_NAME(sys_getegid) /* 50 */
+ .long SYMBOL_NAME(sys_acct)
+ .long SYMBOL_NAME(sys_phys)
+ .long SYMBOL_NAME(sys_lock)
+ .long SYMBOL_NAME(sys_ioctl)
+ .long SYMBOL_NAME(sys_fcntl) /* 55 */
+ .long SYMBOL_NAME(sys_mpx)
+ .long SYMBOL_NAME(sys_setpgid)
+ .long SYMBOL_NAME(sys_ulimit)
+ .long SYMBOL_NAME(sys_olduname)
+ .long SYMBOL_NAME(sys_umask) /* 60 */
+ .long SYMBOL_NAME(sys_chroot)
+ .long SYMBOL_NAME(sys_ustat)
+ .long SYMBOL_NAME(sys_dup2)
+ .long SYMBOL_NAME(sys_getppid)
+ .long SYMBOL_NAME(sys_getpgrp) /* 65 */
+ .long SYMBOL_NAME(sys_setsid)
+ .long SYMBOL_NAME(sys_sigaction)
+ .long SYMBOL_NAME(sys_sgetmask)
+ .long SYMBOL_NAME(sys_ssetmask)
+ .long SYMBOL_NAME(sys_setreuid) /* 70 */
+ .long SYMBOL_NAME(sys_setregid)
+ .long SYMBOL_NAME(sys_sigsuspend)
+ .long SYMBOL_NAME(sys_sigpending)
+ .long SYMBOL_NAME(sys_sethostname)
+ .long SYMBOL_NAME(sys_setrlimit) /* 75 */
+ .long SYMBOL_NAME(sys_getrlimit)
+ .long SYMBOL_NAME(sys_getrusage)
+ .long SYMBOL_NAME(sys_gettimeofday)
+ .long SYMBOL_NAME(sys_settimeofday)
+ .long SYMBOL_NAME(sys_getgroups) /* 80 */
+ .long SYMBOL_NAME(sys_setgroups)
+ .long SYMBOL_NAME(old_select)
+ .long SYMBOL_NAME(sys_symlink)
+ .long SYMBOL_NAME(sys_lstat)
+ .long SYMBOL_NAME(sys_readlink) /* 85 */
+ .long SYMBOL_NAME(sys_uselib)
+ .long SYMBOL_NAME(sys_swapon)
+ .long SYMBOL_NAME(sys_reboot)
+ .long SYMBOL_NAME(old_readdir)
+ .long SYMBOL_NAME(old_mmap) /* 90 */
+ .long SYMBOL_NAME(sys_munmap)
+ .long SYMBOL_NAME(sys_truncate)
+ .long SYMBOL_NAME(sys_ftruncate)
+ .long SYMBOL_NAME(sys_fchmod)
+ .long SYMBOL_NAME(sys_fchown) /* 95 */
+ .long SYMBOL_NAME(sys_getpriority)
+ .long SYMBOL_NAME(sys_setpriority)
+ .long SYMBOL_NAME(sys_profil)
+ .long SYMBOL_NAME(sys_statfs)
+ .long SYMBOL_NAME(sys_fstatfs) /* 100 */
+ .long SYMBOL_NAME(sys_ioperm)
+ .long SYMBOL_NAME(sys_socketcall)
+ .long SYMBOL_NAME(sys_syslog)
+ .long SYMBOL_NAME(sys_setitimer)
+ .long SYMBOL_NAME(sys_getitimer) /* 105 */
+ .long SYMBOL_NAME(sys_newstat)
+ .long SYMBOL_NAME(sys_newlstat)
+ .long SYMBOL_NAME(sys_newfstat)
+ .long SYMBOL_NAME(sys_uname)
+ .long SYMBOL_NAME(sys_iopl) /* 110 */
+ .long SYMBOL_NAME(sys_vhangup)
+ .long SYMBOL_NAME(sys_idle)
+ .long SYMBOL_NAME(sys_vm86old)
+ .long SYMBOL_NAME(sys_wait4)
+ .long SYMBOL_NAME(sys_swapoff) /* 115 */
+ .long SYMBOL_NAME(sys_sysinfo)
+ .long SYMBOL_NAME(sys_ipc)
+ .long SYMBOL_NAME(sys_fsync)
+ .long SYMBOL_NAME(sys_sigreturn)
+ .long SYMBOL_NAME(sys_clone) /* 120 */
+ .long SYMBOL_NAME(sys_setdomainname)
+ .long SYMBOL_NAME(sys_newuname)
+ .long SYMBOL_NAME(sys_modify_ldt)
+ .long SYMBOL_NAME(sys_adjtimex)
+ .long SYMBOL_NAME(sys_mprotect) /* 125 */
+ .long SYMBOL_NAME(sys_sigprocmask)
+ .long SYMBOL_NAME(sys_create_module)
+ .long SYMBOL_NAME(sys_init_module)
+ .long SYMBOL_NAME(sys_delete_module)
+ .long SYMBOL_NAME(sys_get_kernel_syms) /* 130 */
+ .long SYMBOL_NAME(sys_quotactl)
+ .long SYMBOL_NAME(sys_getpgid)
+ .long SYMBOL_NAME(sys_fchdir)
+ .long SYMBOL_NAME(sys_bdflush)
+ .long SYMBOL_NAME(sys_sysfs) /* 135 */
+ .long SYMBOL_NAME(sys_personality)
+ .long 0 /* for afs_syscall */
+ .long SYMBOL_NAME(sys_setfsuid)
+ .long SYMBOL_NAME(sys_setfsgid)
+ .long SYMBOL_NAME(sys_llseek) /* 140 */
+ .long SYMBOL_NAME(sys_getdents)
+ .long SYMBOL_NAME(sys_select)
+ .long SYMBOL_NAME(sys_flock)
+ .long SYMBOL_NAME(sys_msync)
+ .long SYMBOL_NAME(sys_readv) /* 145 */
+ .long SYMBOL_NAME(sys_writev)
+ .long SYMBOL_NAME(sys_getsid)
+ .long SYMBOL_NAME(sys_fdatasync)
+ .long SYMBOL_NAME(sys_sysctl)
+ .long SYMBOL_NAME(sys_mlock) /* 150 */
+ .long SYMBOL_NAME(sys_munlock)
+ .long SYMBOL_NAME(sys_mlockall)
+ .long SYMBOL_NAME(sys_munlockall)
+ .long SYMBOL_NAME(sys_sched_setparam)
+ .long SYMBOL_NAME(sys_sched_getparam) /* 155 */
+ .long SYMBOL_NAME(sys_sched_setscheduler)
+ .long SYMBOL_NAME(sys_sched_getscheduler)
+ .long SYMBOL_NAME(sys_sched_yield)
+ .long SYMBOL_NAME(sys_sched_get_priority_max)
+ .long SYMBOL_NAME(sys_sched_get_priority_min) /* 160 */
+ .long SYMBOL_NAME(sys_sched_rr_get_interval)
+ .long SYMBOL_NAME(sys_nanosleep)
+ .long SYMBOL_NAME(sys_mremap)
+ .long 0,0
+ .long SYMBOL_NAME(sys_vm86)
+ .long 0,0,0,0 /* 170 */
+ .long 0,0,0,0,0,0,0,0,0,0 /* 180 */
+ .long 0,0,0,0,0,0,0
+ .long SYMBOL_NAME(sys_table)
+ .space (NR_syscalls-188)*4
diff --git a/kernel/table20/kernel.patch b/kernel/table20/kernel.patch
new file mode 100644
index 00000000..37654b3d
--- /dev/null
+++ b/kernel/table20/kernel.patch
@@ -0,0 +1,51 @@
+diff -ur linux-2.0.32/Makefile linux-hacked/Makefile
+--- linux-2.0.32/Makefile Fri Nov 7 19:51:05 1997
++++ linux-hacked/Makefile Thu Jun 11 20:41:12 1998
+@@ -87,7 +87,7 @@
+ # standard CFLAGS
+ #
+
+-CFLAGS = -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strength-reduce
++CFLAGS = -Wall -Wstrict-prototypes -g -O2 -fomit-frame-pointer -fno-strength-reduce
+
+ ifdef CONFIG_CPP
+ CFLAGS := $(CFLAGS) -x c++
+@@ -113,12 +113,12 @@
+ # Include the make variables (CC, etc...)
+ #
+
+-ARCHIVES =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o net/network.a
++ARCHIVES =kernel/kernel.o mm/mm.o fs/fs.o ipc/ipc.o net/network.a table/table.o
+ FILESYSTEMS =fs/filesystems.a
+ DRIVERS =drivers/block/block.a \
+ drivers/char/char.a
+ LIBS =$(TOPDIR)/lib/lib.a
+-SUBDIRS =kernel drivers mm fs net ipc lib
++SUBDIRS =kernel drivers mm fs net ipc lib table
+
+ ifeq ($(CONFIG_ISDN),y)
+ DRIVERS := $(DRIVERS) drivers/isdn/isdn.a
+diff -ur linux-2.0.32/arch/i386/kernel/entry.S linux-hacked/arch/i386/kernel/entry.S
+--- linux-2.0.32/arch/i386/kernel/entry.S Tue Sep 16 23:42:45 1997
++++ linux-hacked/arch/i386/kernel/entry.S Thu Jun 11 21:37:20 1998
+@@ -699,4 +699,8 @@
+ .long SYMBOL_NAME(sys_mremap)
+ .long 0,0
+ .long SYMBOL_NAME(sys_vm86)
+- .space (NR_syscalls-166)*4
++ .long 0,0,0,0 /* 170 */
++ .long 0,0,0,0,0,0,0,0,0,0 /* 180 */
++ .long 0,0,0,0,0,0,0
++ .long SYMBOL_NAME(sys_table)
++ .space (NR_syscalls-188)*4
+diff -ur linux-2.0.32/include/asm-i386/unistd.h linux-hacked/include/asm-i386/unistd.h
+--- linux-2.0.32/include/asm-i386/unistd.h Fri Mar 22 07:34:02 1996
++++ linux-hacked/include/asm-i386/unistd.h Thu Jun 11 21:37:03 1998
+@@ -169,6 +169,7 @@
+ #define __NR_sched_rr_get_interval 161
+ #define __NR_nanosleep 162
+ #define __NR_mremap 163
++#define __NR_table 188
+
+ /* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
+ #define _syscall0(type,name) \
diff --git a/kernel/table20/main.c b/kernel/table20/main.c
new file mode 100644
index 00000000..97950afb
--- /dev/null
+++ b/kernel/table20/main.c
@@ -0,0 +1,468 @@
+/*
+ * linux/table/table_impl.c
+ * Copyright (C) 1998 Martin Baulig
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/kernel_stat.h>
+#include <linux/tty.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/string.h>
+#include <linux/mman.h>
+#include <linux/proc_fs.h>
+#include <linux/ioport.h>
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/swap.h>
+
+#include <asm/segment.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+
+#include <linux/table.h>
+
+#include "version.h"
+
+#if defined(__i386__)
+# define KSTK_EIP(tsk) (((unsigned long *)tsk->kernel_stack_page)[1019])
+# define KSTK_ESP(tsk) (((unsigned long *)tsk->kernel_stack_page)[1022])
+#elif defined(__alpha__)
+ /*
+ * See arch/alpha/kernel/ptrace.c for details.
+ */
+# define PT_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \
+ + (long)&((struct pt_regs *)0)->reg)
+# define KSTK_EIP(tsk) (*(unsigned long *)(tsk->kernel_stack_page + PT_REG(pc)))
+# define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp)
+#elif defined(__sparc__)
+# define PT_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \
+ + (long)&((struct pt_regs *)0)->reg)
+# define KSTK_EIP(tsk) (*(unsigned long *)(tsk->kernel_stack_page + PT_REG(pc)))
+# define KSTK_ESP(tsk) (*(unsigned long *)(tsk->kernel_stack_page + PT_REG(u_regs[UREG_FP])))
+#endif
+
+static struct task_struct *
+get_task (pid_t pid)
+{
+ struct task_struct ** p;
+
+ p = task;
+ while (++p < task+NR_TASKS) {
+ if (*p && (*p)->pid == pid)
+ return *p;
+ }
+
+ return NULL;
+}
+
+static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned long size,
+ int * pages, int * shared, int * dirty, int * total)
+{
+ pte_t * pte;
+ unsigned long end;
+
+ if (pmd_none(*pmd))
+ return;
+ if (pmd_bad(*pmd)) {
+ printk("statm_pte_range: bad pmd (%08lx)\n", pmd_val(*pmd));
+ pmd_clear(pmd);
+ return;
+ }
+ pte = pte_offset(pmd, address);
+ address &= ~PMD_MASK;
+ end = address + size;
+ if (end > PMD_SIZE)
+ end = PMD_SIZE;
+ do {
+ pte_t page = *pte;
+
+ address += PAGE_SIZE;
+ pte++;
+ if (pte_none(page))
+ continue;
+ ++*total;
+ if (!pte_present(page))
+ continue;
+ ++*pages;
+ if (pte_dirty(page))
+ ++*dirty;
+ if (pte_page(page) >= high_memory)
+ continue;
+ if (mem_map[MAP_NR(pte_page(page))].count > 1)
+ ++*shared;
+ } while (address < end);
+}
+
+static inline void statm_pmd_range(pgd_t * pgd, unsigned long address, unsigned long size,
+ int * pages, int * shared, int * dirty, int * total)
+{
+ pmd_t * pmd;
+ unsigned long end;
+
+ if (pgd_none(*pgd))
+ return;
+ if (pgd_bad(*pgd)) {
+ printk("statm_pmd_range: bad pgd (%08lx)\n", pgd_val(*pgd));
+ pgd_clear(pgd);
+ return;
+ }
+ pmd = pmd_offset(pgd, address);
+ address &= ~PGDIR_MASK;
+ end = address + size;
+ if (end > PGDIR_SIZE)
+ end = PGDIR_SIZE;
+ do {
+ statm_pte_range(pmd, address, end - address, pages, shared, dirty, total);
+ address = (address + PMD_SIZE) & PMD_MASK;
+ pmd++;
+ } while (address < end);
+}
+
+static void statm_pgd_range(pgd_t * pgd, unsigned long address, unsigned long end,
+ int * pages, int * shared, int * dirty, int * total)
+{
+ while (address < end) {
+ statm_pmd_range(pgd, address, end - address, pages, shared, dirty, total);
+ address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ pgd++;
+ }
+}
+
+static unsigned long
+get_wchan (struct task_struct *p)
+{
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+#if defined(__i386__)
+ {
+ unsigned long ebp, eip;
+ unsigned long stack_page;
+ int count = 0;
+
+ stack_page = p->kernel_stack_page;
+ if (!stack_page)
+ return 0;
+ ebp = p->tss.ebp;
+ do {
+ if (ebp < stack_page || ebp >= 4092+stack_page)
+ return 0;
+ eip = *(unsigned long *) (ebp+4);
+ if (eip < (unsigned long) interruptible_sleep_on
+ || eip >= (unsigned long) add_timer)
+ return eip;
+ ebp = *(unsigned long *) ebp;
+ } while (count++ < 16);
+ }
+#elif defined(__alpha__)
+ /*
+ * This one depends on the frame size of schedule(). Do a
+ * "disass schedule" in gdb to find the frame size. Also, the
+ * code assumes that sleep_on() follows immediately after
+ * interruptible_sleep_on() and that add_timer() follows
+ * immediately after interruptible_sleep(). Ugly, isn't it?
+ * Maybe adding a wchan field to task_struct would be better,
+ * after all...
+ */
+ {
+ unsigned long schedule_frame;
+ unsigned long pc;
+
+ pc = thread_saved_pc(&p->tss);
+ if (pc >= (unsigned long) interruptible_sleep_on && pc < (unsigned long) add_timer) {
+ schedule_frame = ((unsigned long *)p->tss.ksp)[6];
+ return ((unsigned long *)schedule_frame)[12];
+ }
+ return pc;
+ }
+#endif
+ return 0;
+}
+
+asmlinkage int
+sys_table (int type, union table *buf, const void *param)
+{
+ union table tbl;
+ struct sysinfo i;
+ struct task_struct *tsk = NULL;
+ struct ip_chain *chain;
+ struct ip_fwkernel *rule;
+ char devname [9];
+ int index, err;
+ pid_t pid;
+
+ if (type == TABLE_VERSION)
+ return _TABLE_VERSION;
+
+ if (!buf)
+ return -EFAULT;
+
+ memset (&tbl, 0, sizeof (union table));
+
+ /* For TABLE_PROC_*, read pid and get task_struct */
+
+ switch (type) {
+ case TABLE_PROC_UID:
+ case TABLE_PROC_MEM:
+ case TABLE_PROC_SEGMENT:
+ case TABLE_PROC_TIME:
+ case TABLE_PROC_STATE:
+ case TABLE_PROC_SIGNAL:
+ case TABLE_PROC_KERNEL:
+ err = verify_area (VERIFY_READ, param, sizeof (pid_t));
+ if (err)
+ return err;
+ memcpy_fromfs (&pid, param, sizeof (pid_t));
+
+ tsk = get_task (pid);
+ if (tsk == NULL)
+ return -ESRCH;
+ break;
+ case TABLE_NETACCT:
+ err = verify_area (VERIFY_READ, param, 5);
+ if (err)
+ return err;
+ copy_from_user (devname, param, 5);
+ devname [5] = 0;
+
+ break;
+ }
+
+ /* Main function dispatcher */
+
+ switch (type) {
+ case TABLE_PROCLIST:
+ tsk = task [0];
+ for (index = 0; index < nr_tasks; index++) {
+ tbl.proclist.pids [index] = tsk->pid;
+ tsk = tsk->next_task;
+ }
+ tbl.proclist.nr_running = nr_running;
+ tbl.proclist.nr_tasks = nr_tasks;
+ tbl.proclist.last_pid = last_pid;
+ break;
+ case TABLE_CPU:
+ tbl.cpu.total = jiffies;
+ tbl.cpu.user = kstat.cpu_user;
+ tbl.cpu.nice = kstat.cpu_nice;
+ tbl.cpu.sys = kstat.cpu_system;
+ tbl.cpu.idle = tbl.cpu.total -
+ (tbl.cpu.user + tbl.cpu.nice + tbl.cpu.sys);
+ tbl.cpu.frequency = HZ;
+ break;
+ case TABLE_MEM:
+ si_meminfo (&i);
+ tbl.mem.total = i.totalram;
+ tbl.mem.used = i.totalram - i.freeram;
+ tbl.mem.free = i.freeram;
+ tbl.mem.shared = i.sharedram;
+ tbl.mem.buffer = i.bufferram;
+ tbl.mem.cached = page_cache_size << PAGE_SHIFT;
+ break;
+ case TABLE_SWAP:
+ si_swapinfo (&i);
+ tbl.swap.total = i.totalswap;
+ tbl.swap.used = i.totalswap - i.freeswap;
+ tbl.swap.free = i.freeswap;
+ tbl.swap.pagein = kstat.pswpin;
+ tbl.swap.pageout = kstat.pswpout;
+ break;
+ case TABLE_LOADAVG:
+ tbl.loadavg.loadavg [0] = (double) avenrun [0] / (1 << FSHIFT);
+ tbl.loadavg.loadavg [1] = (double) avenrun [1] / (1 << FSHIFT);
+ tbl.loadavg.loadavg [2] = (double) avenrun [2] / (1 << FSHIFT);
+ tbl.loadavg.nr_running = nr_running;
+ tbl.loadavg.nr_tasks = nr_tasks;
+ tbl.loadavg.last_pid = last_pid;
+ break;
+ case TABLE_UPTIME:
+ tbl.uptime.uptime = jiffies;
+ tbl.uptime.idle = task[0]->utime + task[0]->stime;
+ break;
+ case TABLE_PROC_STATE:
+ tbl.proc_state.state = tsk->state;
+ tbl.proc_state.flags = tsk->flags;
+ memcpy (tbl.proc_state.comm, tsk->comm,
+ sizeof (tbl.proc_state.comm));
+ break;
+ case TABLE_PROC_UID:
+ tbl.proc_uid.uid = tsk->uid;
+ tbl.proc_uid.euid = tsk->euid;
+ tbl.proc_uid.suid = tsk->suid;
+ tbl.proc_uid.fsuid = tsk->fsuid;
+
+ tbl.proc_uid.gid = tsk->gid;
+ tbl.proc_uid.egid = tsk->egid;
+ tbl.proc_uid.sgid = tsk->sgid;
+ tbl.proc_uid.fsgid = tsk->fsgid;
+
+ tbl.proc_uid.pid = tsk->pid;
+ tbl.proc_uid.pgrp = tsk->pgrp;
+ tbl.proc_uid.ppid = tsk->p_pptr->pid;
+
+ tbl.proc_uid.session = tsk->session;
+ tbl.proc_uid.tty = tsk->tty ?
+ kdev_t_to_nr (tsk->tty->device) : 0;
+ tbl.proc_uid.tpgid = tsk->tty ? tsk->tty->pgrp : -1;
+
+ tbl.proc_uid.priority = tsk->priority;
+ tbl.proc_uid.counter = tsk->counter;
+ tbl.proc_uid.def_priority = DEF_PRIORITY;
+ break;
+ case TABLE_PROC_SIGNAL:
+ tbl.proc_signal.signal = tsk->signal;
+ tbl.proc_signal.blocked = tsk->blocked;
+
+ if (tsk->sig) {
+ struct sigaction * action = tsk->sig->action;
+ unsigned long sig_ign = 0, sig_caught = 0;
+ unsigned long bit = 1;
+ int i;
+
+ for (i = 0; i < 32; i++) {
+ switch((unsigned long) action->sa_handler) {
+ case 0:
+ break;
+ case 1:
+ sig_ign |= bit;
+ break;
+ default:
+ sig_caught |= bit;
+ }
+ bit <<= 1;
+ action++;
+ }
+
+ tbl.proc_signal.ignored = sig_ign;
+ tbl.proc_signal.caught = sig_caught;
+ } else {
+ tbl.proc_signal.ignored = 0;
+ tbl.proc_signal.caught = 0;
+ }
+ break;
+ case TABLE_PROC_MEM:
+ if (tsk->mm && tsk->mm != &init_mm) {
+ tbl.proc_mem.context = tsk->mm->context;
+ tbl.proc_mem.start_code = tsk->mm->start_code;
+ tbl.proc_mem.end_code = tsk->mm->end_code;
+ tbl.proc_mem.start_data = tsk->mm-> start_data;
+ tbl.proc_mem.end_data = tsk->mm->end_data;
+ tbl.proc_mem.start_brk = tsk->mm->start_brk;
+ tbl.proc_mem.brk = tsk->mm->brk;
+ tbl.proc_mem.start_stack = tsk->mm->start_stack;
+ tbl.proc_mem.start_mmap = tsk->mm->start_mmap;
+ tbl.proc_mem.arg_start = tsk->mm->arg_start;
+ tbl.proc_mem.arg_end = tsk->mm->arg_end;
+ tbl.proc_mem.env_start = tsk->mm->env_start;
+ tbl.proc_mem.env_end = tsk->mm->env_end;
+ tbl.proc_mem.rss = tsk->mm->rss;
+ tbl.proc_mem.total_vm = tsk->mm->total_vm;
+ tbl.proc_mem.locked_vm = tsk->mm->locked_vm;
+ }
+ tbl.proc_mem.rlim = tsk->rlim ?
+ tsk->rlim[RLIMIT_RSS].rlim_cur : 0;
+ break;
+ case TABLE_PROC_SEGMENT:
+ if (tsk->mm && tsk->mm != &init_mm) {
+ unsigned long vsize = 0;
+ int size = 0, resident = 0, share = 0;
+ int trs = 0, lrs = 0, drs = 0, dt = 0;
+ struct vm_area_struct * vma = tsk->mm->mmap;
+
+ while (vma) {
+ pgd_t *pgd = pgd_offset(tsk->mm, vma->vm_start);
+ int pages = 0, shared = 0, dirty = 0, total = 0;
+
+ vsize += vma->vm_end - vma->vm_start;
+
+ statm_pgd_range (pgd, vma->vm_start, vma->vm_end,
+ &pages, &shared, &dirty, &total);
+ resident += pages;
+ share += shared;
+ dt += dirty;
+ size += total;
+ if (vma->vm_flags & VM_EXECUTABLE)
+ trs += pages; /* text */
+ else if (vma->vm_flags & VM_GROWSDOWN)
+ drs += pages; /* stack */
+ else if (vma->vm_end > 0x60000000)
+ lrs += pages; /* library */
+ else
+ drs += pages;
+ vma = vma->vm_next;
+ }
+
+ tbl.proc_segment.vsize = vsize;
+ tbl.proc_segment.size = size;
+ tbl.proc_segment.resident = resident;
+ tbl.proc_segment.shared = share;
+ tbl.proc_segment.trs = trs;
+ tbl.proc_segment.lrs = lrs;
+ tbl.proc_segment.dt = dt;
+ }
+ break;
+ case TABLE_PROC_TIME:
+ tbl.proc_time.utime = tsk->utime;
+ tbl.proc_time.stime = tsk->stime;
+ tbl.proc_time.cutime = tsk->cutime;
+ tbl.proc_time.cstime = tsk->cstime;
+
+ tbl.proc_time.start_time = tsk->start_time;
+ tbl.proc_time.timeout = tsk->timeout;
+ tbl.proc_time.policy = tsk->policy;
+ tbl.proc_time.rt_priority = tsk->rt_priority;
+
+ tbl.proc_time.it_real_value = tsk->it_real_value;
+ tbl.proc_time.it_prof_value = tsk->it_prof_value;
+ tbl.proc_time.it_virt_value = tsk->it_virt_value;
+ tbl.proc_time.it_real_incr = tsk->it_real_incr;
+ tbl.proc_time.it_prof_incr = tsk->it_prof_incr;
+ tbl.proc_time.it_virt_incr = tsk->it_virt_incr;
+ break;
+ case TABLE_PROC_KERNEL:
+ tbl.proc_kernel.min_flt = tsk->min_flt;
+ tbl.proc_kernel.cmin_flt = tsk->cmin_flt;
+ tbl.proc_kernel.maj_flt = tsk->maj_flt;
+ tbl.proc_kernel.cmaj_flt = tsk->cmaj_flt;
+
+ tbl.proc_kernel.kesp = tsk->kernel_stack_page ? KSTK_EIP(tsk) : 0;
+ tbl.proc_kernel.keip = tsk->kernel_stack_page ? KSTK_ESP(tsk) : 0;
+
+ tbl.proc_kernel.nswap = tsk->nswap;
+ tbl.proc_kernel.cnswap = tsk->cnswap;
+
+ tbl.proc_kernel.wchan = get_wchan (tsk);
+ break;
+ case TABLE_NETACCT:
+ for (chain = ip_fw_chains; chain; chain = chain->next) {
+ for (rule = chain->chain; rule; rule = rule->next) {
+ const char *name = rule->ipfw.fw_vianame;
+ int k;
+
+ if (name [0] && !strncmp (param, name, 5))
+ continue;
+
+ for (k = 0; k < NUM_SLOTS; k++) {
+ tbl.netacct.packets +=
+ rule->counters[k].pcnt;
+ tbl.netacct.bytes +=
+ rule->counters[k].bcnt;
+ }
+ }
+ }
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ err = verify_area (VERIFY_WRITE, buf, sizeof (struct table));
+ if (err)
+ return err;
+
+ memcpy_tofs (buf, &tbl, sizeof (union table));
+ return 0;
+}
diff --git a/kernel/table20/unistd-i386.h b/kernel/table20/unistd-i386.h
new file mode 100644
index 00000000..0d5b4f8b
--- /dev/null
+++ b/kernel/table20/unistd-i386.h
@@ -0,0 +1,324 @@
+#ifndef _ASM_I386_UNISTD_H_
+#define _ASM_I386_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_setup 0 /* used only by init, to get system going */
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_waitpid 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_time 13
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_chown 16
+#define __NR_break 17
+#define __NR_oldstat 18
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount 22
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_oldfstat 28
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_stty 31
+#define __NR_gtty 32
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_ftime 35
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_prof 44
+#define __NR_brk 45
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_signal 48
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_acct 51
+#define __NR_phys 52
+#define __NR_lock 53
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_mpx 56
+#define __NR_setpgid 57
+#define __NR_ulimit 58
+#define __NR_oldolduname 59
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_sigaction 67
+#define __NR_sgetmask 68
+#define __NR_ssetmask 69
+#define __NR_setreuid 70
+#define __NR_setregid 71
+#define __NR_sigsuspend 72
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrlimit 76
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_select 82
+#define __NR_symlink 83
+#define __NR_oldlstat 84
+#define __NR_readlink 85
+#define __NR_uselib 86
+#define __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+#define __NR_mmap 90
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_fchown 95
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+#define __NR_profil 98
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+#define __NR_ioperm 101
+#define __NR_socketcall 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+#define __NR_olduname 109
+#define __NR_iopl 110
+#define __NR_vhangup 111
+#define __NR_idle 112
+#define __NR_vm86 113
+#define __NR_wait4 114
+#define __NR_swapoff 115
+#define __NR_sysinfo 116
+#define __NR_ipc 117
+#define __NR_fsync 118
+#define __NR_sigreturn 119
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+#define __NR_modify_ldt 123
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+#define __NR_sigprocmask 126
+#define __NR_create_module 127
+#define __NR_init_module 128
+#define __NR_delete_module 129
+#define __NR_get_kernel_syms 130
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+#define __NR_sysfs 135
+#define __NR_personality 136
+#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
+#define __NR_setfsuid 138
+#define __NR_setfsgid 139
+#define __NR__llseek 140
+#define __NR_getdents 141
+#define __NR__newselect 142
+#define __NR_flock 143
+#define __NR_msync 144
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+#define __NR_mlock 150
+#define __NR_munlock 151
+#define __NR_mlockall 152
+#define __NR_munlockall 153
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+#define __NR_mremap 163
+#define __NR_table 188
+
+/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+ : "=a" (__res) \
+ : "0" (__NR_##name)); \
+if (__res >= 0) \
+ return (type) __res; \
+errno = -__res; \
+return -1; \
+}
+
+#define _syscall1(type,name,type1,arg1) \
+type name(type1 arg1) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"b" ((long)(arg1))); \
+if (__res >= 0) \
+ return (type) __res; \
+errno = -__res; \
+return -1; \
+}
+
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1,type2 arg2) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \
+if (__res >= 0) \
+ return (type) __res; \
+errno = -__res; \
+return -1; \
+}
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name(type1 arg1,type2 arg2,type3 arg3) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+ "d" ((long)(arg3))); \
+if (__res>=0) \
+ return (type) __res; \
+errno=-__res; \
+return -1; \
+}
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+ "d" ((long)(arg3)),"S" ((long)(arg4))); \
+if (__res>=0) \
+ return (type) __res; \
+errno=-__res; \
+return -1; \
+}
+
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+ "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \
+if (__res>=0) \
+ return (type) __res; \
+errno=-__res; \
+return -1; \
+}
+
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+static inline _syscall0(int,idle)
+static inline _syscall0(int,fork)
+static inline _syscall2(int,clone,unsigned long,flags,char *,esp)
+static inline _syscall0(int,pause)
+static inline _syscall0(int,setup)
+static inline _syscall0(int,sync)
+static inline _syscall0(pid_t,setsid)
+static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static inline _syscall1(int,dup,int,fd)
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+static inline _syscall1(int,close,int,fd)
+static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+
+static inline pid_t wait(int * wait_stat)
+{
+ return waitpid(-1,wait_stat,0);
+}
+
+/*
+ * This is the mechanism for creating a new kernel thread.
+ *
+ * NOTE! Only a kernel-only process(ie the swapper or direct descendants
+ * who haven't done an "execve()") should use this: it will work within
+ * a system call from a "real" process, but the process memory space will
+ * not be free'd until both the parent and the child have exited.
+ */
+static inline pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+ long retval;
+
+ __asm__ __volatile__(
+ "movl %%esp,%%esi\n\t"
+ "int $0x80\n\t" /* Linux/i386 system call */
+ "cmpl %%esp,%%esi\n\t" /* child or parent? */
+ "je 1f\n\t" /* parent - jump */
+ "pushl %3\n\t" /* push argument */
+ "call *%4\n\t" /* call fn */
+ "movl %2,%0\n\t" /* exit */
+ "int $0x80\n"
+ "1:\t"
+ :"=a" (retval)
+ :"0" (__NR_clone), "i" (__NR_exit),
+ "r" (arg), "r" (fn),
+ "b" (flags | CLONE_VM)
+ :"si");
+ return retval;
+}
+
+#endif
+
+#endif /* _ASM_I386_UNISTD_H_ */
diff --git a/kernel/table20/version.h b/kernel/table20/version.h
new file mode 100644
index 00000000..d47411ee
--- /dev/null
+++ b/kernel/table20/version.h
@@ -0,0 +1 @@
+#define _TABLE_VERSION 1
diff --git a/kernel/table21/.cvsignore b/kernel/table21/.cvsignore
new file mode 100644
index 00000000..a7ab2843
--- /dev/null
+++ b/kernel/table21/.cvsignore
@@ -0,0 +1,4 @@
+kernel.patch
+.main.o.flags
+.table.o.flags
+.module.o.flags
diff --git a/kernel/table21/Makefile b/kernel/table21/Makefile
new file mode 100644
index 00000000..2eedd527
--- /dev/null
+++ b/kernel/table21/Makefile
@@ -0,0 +1,16 @@
+#
+# Makefile for the linux system information tables.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+O_TARGET := table.o
+OX_OBJS := main.o
+
+M_TARGET := table_mod.o
+MX_OBJS := module.o
+
+include $(TOPDIR)/Rules.make
diff --git a/kernel/table21/README b/kernel/table21/README
new file mode 100644
index 00000000..88d26bec
--- /dev/null
+++ b/kernel/table21/README
@@ -0,0 +1,21 @@
+This is a new system call `table ()' for the Linux table. It is faster
+than reading from /proc and can be used to fetch all information required
+for libgtop until whe have some other function (extended sysctl, ...) in
+standard kernels.
+
+I didn't want to change sysctl or some other function myself cause this may
+cause other applications relying upon those function to fail. This is
+something for the ``real'' kernel gurus ...
+
+To use this new system call for libgtop, do the following:
+
+* Copy this directory to /usr/src/linux/table
+* Make /usr/src/linux/include/linux/table.h symlink to /usr/src/linux/table/table.h
+* Apply the patch `kernel.patch' to the kernel, compile, install and reboot
+* Recompile libgtop (remove `config.cache' and run the `autogen.sh' again).
+
+If you want to change and/or add something - feel free to do so !
+
+Have fun,
+
+Martin
diff --git a/kernel/table21/entry-i386.S b/kernel/table21/entry-i386.S
new file mode 100644
index 00000000..fb734fbc
--- /dev/null
+++ b/kernel/table21/entry-i386.S
@@ -0,0 +1,571 @@
+/*
+ * linux/arch/i386/entry.S
+ *
+ * Copyright (C) 1991, 1992 Linus Torvalds
+ */
+
+/*
+ * entry.S contains the system-call and fault low-level handling routines.
+ * This also contains the timer-interrupt handler, as well as all interrupts
+ * and faults that can result in a task-switch.
+ *
+ * NOTE: This code handles signal-recognition, which happens every time
+ * after a timer-interrupt and after each system call.
+ *
+ * I changed all the .align's to 4 (16 byte alignment), as that's faster
+ * on a 486.
+ *
+ * Stack layout in 'ret_from_system_call':
+ * ptrace needs to have all regs on the stack.
+ * if the order here is changed, it needs to be
+ * updated in fork.c:copy_process, signal.c:do_signal,
+ * ptrace.c and ptrace.h
+ *
+ * 0(%esp) - %ebx
+ * 4(%esp) - %ecx
+ * 8(%esp) - %edx
+ * C(%esp) - %esi
+ * 10(%esp) - %edi
+ * 14(%esp) - %ebp
+ * 18(%esp) - %eax
+ * 1C(%esp) - %ds
+ * 20(%esp) - %es
+ * 24(%esp) - orig_eax
+ * 28(%esp) - %eip
+ * 2C(%esp) - %cs
+ * 30(%esp) - %eflags
+ * 34(%esp) - %oldesp
+ * 38(%esp) - %oldss
+ *
+ * "current" is in register %ebx during any slow entries.
+ */
+
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/segment.h>
+#define ASSEMBLY
+#include <asm/smp.h>
+
+EBX = 0x00
+ECX = 0x04
+EDX = 0x08
+ESI = 0x0C
+EDI = 0x10
+EBP = 0x14
+EAX = 0x18
+DS = 0x1C
+ES = 0x20
+ORIG_EAX = 0x24
+EIP = 0x28
+CS = 0x2C
+EFLAGS = 0x30
+OLDESP = 0x34
+OLDSS = 0x38
+
+CF_MASK = 0x00000001
+IF_MASK = 0x00000200
+NT_MASK = 0x00004000
+VM_MASK = 0x00020000
+
+/*
+ * these are offsets into the task-struct.
+ */
+state = 0
+flags = 4
+sigpending = 8
+addr_limit = 12
+exec_domain = 16
+need_resched = 20
+
+ENOSYS = 38
+
+
+#define SAVE_ALL \
+ cld; \
+ pushl %es; \
+ pushl %ds; \
+ pushl %eax; \
+ pushl %ebp; \
+ pushl %edi; \
+ pushl %esi; \
+ pushl %edx; \
+ pushl %ecx; \
+ pushl %ebx; \
+ movl $(__KERNEL_DS),%edx; \
+ movl %dx,%ds; \
+ movl %dx,%es;
+
+#define RESTORE_ALL \
+ popl %ebx; \
+ popl %ecx; \
+ popl %edx; \
+ popl %esi; \
+ popl %edi; \
+ popl %ebp; \
+ popl %eax; \
+1: popl %ds; \
+2: popl %es; \
+3: addl $4,%esp; \
+ iret; \
+.section fixup,"ax"; \
+4: pushl $0; \
+ popl %ds; \
+ jmp 2b; \
+5: pushl $0; \
+ popl %es; \
+ jmp 3b; \
+.previous; \
+.section __ex_table,"a";\
+ .align 4; \
+ .long 1b,4b; \
+ .long 2b,5b; \
+.previous
+
+#define GET_CURRENT(reg) \
+ movl %esp, reg; \
+ andl $-8192, reg;
+
+ENTRY(lcall7)
+ pushfl # We get a different stack layout with call gates,
+ pushl %eax # which has to be cleaned up later..
+ SAVE_ALL
+ movl EIP(%esp),%eax # due to call gates, this is eflags, not eip..
+ movl CS(%esp),%edx # this is eip..
+ movl EFLAGS(%esp),%ecx # and this is cs..
+ movl %eax,EFLAGS(%esp) #
+ movl %edx,EIP(%esp) # Now we move them to their "normal" places
+ movl %ecx,CS(%esp) #
+ movl %esp,%ebx
+ pushl %ebx
+ andl $-8192,%ebx # GET_CURRENT
+ movl exec_domain(%ebx),%edx # Get the execution domain
+ movl 4(%edx),%edx # Get the lcall7 handler for the domain
+ call *%edx
+ popl %eax
+ jmp ret_from_sys_call
+
+
+#ifdef __SMP__
+ ALIGN
+ .globl ret_from_smpfork
+ret_from_smpfork:
+ GET_CURRENT(%ebx)
+ btrl $0, SYMBOL_NAME(scheduler_lock)
+ jmp ret_from_sys_call
+#endif /* __SMP__ */
+
+/*
+ * Return to user mode is not as complex as all this looks,
+ * but we want the default path for a system call return to
+ * go as quickly as possible which is why some of this is
+ * less clear than it otherwise should be.
+ */
+
+ENTRY(system_call)
+ pushl %eax # save orig_eax
+ SAVE_ALL
+ GET_CURRENT(%ebx)
+ cmpl $(NR_syscalls),%eax
+ jae badsys
+ testb $0x20,flags(%ebx) # PF_TRACESYS
+ jne tracesys
+ call *SYMBOL_NAME(sys_call_table)(,%eax,4)
+ movl %eax,EAX(%esp) # save the return value
+ ALIGN
+ .globl ret_from_sys_call
+ .globl ret_from_intr
+ret_from_sys_call:
+ movl SYMBOL_NAME(bh_mask),%eax
+ andl SYMBOL_NAME(bh_active),%eax
+ jne handle_bottom_half
+ret_with_reschedule:
+ cmpl $0,need_resched(%ebx)
+ jne reschedule
+ cmpl $0,sigpending(%ebx)
+ jne signal_return
+ RESTORE_ALL
+ ALIGN
+signal_return:
+ testl $(VM_MASK),EFLAGS(%esp)
+ pushl %esp
+ jne v86_signal_return
+ pushl $0
+ call SYMBOL_NAME(do_signal)
+ addl $8,%esp
+ RESTORE_ALL
+ ALIGN
+v86_signal_return:
+ call SYMBOL_NAME(save_v86_state)
+ movl %eax,%esp
+ pushl %eax
+ pushl $0
+ call SYMBOL_NAME(do_signal)
+ addl $8,%esp
+ RESTORE_ALL
+ ALIGN
+tracesys:
+ movl $-ENOSYS,EAX(%esp)
+ call SYMBOL_NAME(syscall_trace)
+ movl ORIG_EAX(%esp),%eax
+ call *SYMBOL_NAME(sys_call_table)(,%eax,4)
+ movl %eax,EAX(%esp) # save the return value
+ call SYMBOL_NAME(syscall_trace)
+ jmp ret_from_sys_call
+badsys:
+ movl $-ENOSYS,EAX(%esp)
+ jmp ret_from_sys_call
+
+ ALIGN
+ret_from_exception:
+ movl SYMBOL_NAME(bh_mask),%eax
+ andl SYMBOL_NAME(bh_active),%eax
+ jne handle_bottom_half
+ ALIGN
+ret_from_intr:
+ GET_CURRENT(%ebx)
+ movl EFLAGS(%esp),%eax # mix EFLAGS and CS
+ movb CS(%esp),%al
+ testl $(VM_MASK | 3),%eax # return to VM86 mode or non-supervisor?
+ jne ret_with_reschedule
+ RESTORE_ALL
+
+ ALIGN
+handle_bottom_half:
+ pushl $ret_from_intr
+ jmp SYMBOL_NAME(do_bottom_half)
+
+ ALIGN
+reschedule:
+ pushl $ret_from_sys_call
+ jmp SYMBOL_NAME(schedule) # test
+
+
+ENTRY(divide_error)
+ pushl $0 # no error code
+ pushl $ SYMBOL_NAME(do_divide_error)
+ ALIGN
+error_code:
+ pushl %ds
+ pushl %eax
+ xorl %eax,%eax
+ pushl %ebp
+ pushl %edi
+ pushl %esi
+ pushl %edx
+ decl %eax # eax = -1
+ pushl %ecx
+ pushl %ebx
+#if 1
+ xorl %ecx,%ecx # zero ecx
+ cld
+ mov %es,%cx # get the lower order bits of es
+#else
+ cld
+# Some older processors leave the top 16 bits of the 32 bit destination
+# register undefined, rather than zeroed in the following instruction.
+# This won't matter when restoring or loading a segment register from the
+# stack. It may be a problem if any code reads the full 32 bit value.
+# dosemu? kernel? Would somebody like to verify that this way is really OK?
+ movl %es,%cx
+#endif
+ xchgl %eax, ORIG_EAX(%esp) # orig_eax (get the error code. )
+ movl %esp,%edx
+ xchgl %ecx, ES(%esp) # get the address and save es.
+ pushl %eax # push the error code
+ pushl %edx
+ movl $(__KERNEL_DS),%edx
+ movl %dx,%ds
+ movl %dx,%es
+ GET_CURRENT(%ebx)
+ call *%ecx
+ addl $8,%esp
+ jmp ret_from_exception
+
+ENTRY(coprocessor_error)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_coprocessor_error)
+ jmp error_code
+
+ENTRY(device_not_available)
+ pushl $-1 # mark this as an int
+ SAVE_ALL
+ GET_CURRENT(%ebx)
+ pushl $ret_from_exception
+ movl %cr0,%eax
+ testl $0x4,%eax # EM (math emulation bit)
+ je SYMBOL_NAME(math_state_restore)
+ pushl $0 # temporary storage for ORIG_EIP
+ call SYMBOL_NAME(math_emulate)
+ addl $4,%esp
+ ret
+
+ENTRY(debug)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_debug)
+ jmp error_code
+
+ENTRY(nmi)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_nmi)
+ jmp error_code
+
+ENTRY(int3)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_int3)
+ jmp error_code
+
+ENTRY(overflow)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_overflow)
+ jmp error_code
+
+ENTRY(bounds)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_bounds)
+ jmp error_code
+
+ENTRY(invalid_op)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_invalid_op)
+ jmp error_code
+
+ENTRY(coprocessor_segment_overrun)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_coprocessor_segment_overrun)
+ jmp error_code
+
+ENTRY(reserved)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_reserved)
+ jmp error_code
+
+ENTRY(double_fault)
+ pushl $ SYMBOL_NAME(do_double_fault)
+ jmp error_code
+
+ENTRY(invalid_TSS)
+ pushl $ SYMBOL_NAME(do_invalid_TSS)
+ jmp error_code
+
+ENTRY(segment_not_present)
+ pushl $ SYMBOL_NAME(do_segment_not_present)
+ jmp error_code
+
+ENTRY(stack_segment)
+ pushl $ SYMBOL_NAME(do_stack_segment)
+ jmp error_code
+
+ENTRY(general_protection)
+ pushl $ SYMBOL_NAME(do_general_protection)
+ jmp error_code
+
+ENTRY(alignment_check)
+ pushl $ SYMBOL_NAME(do_alignment_check)
+ jmp error_code
+
+ENTRY(page_fault)
+ pushl $ SYMBOL_NAME(do_page_fault)
+ jmp error_code
+
+ENTRY(spurious_interrupt_bug)
+ pushl $0
+ pushl $ SYMBOL_NAME(do_spurious_interrupt_bug)
+ jmp error_code
+
+.data
+ENTRY(sys_call_table)
+ .long SYMBOL_NAME(sys_setup) /* 0 */
+ .long SYMBOL_NAME(sys_exit)
+ .long SYMBOL_NAME(sys_fork)
+ .long SYMBOL_NAME(sys_read)
+ .long SYMBOL_NAME(sys_write)
+ .long SYMBOL_NAME(sys_open) /* 5 */
+ .long SYMBOL_NAME(sys_close)
+ .long SYMBOL_NAME(sys_waitpid)
+ .long SYMBOL_NAME(sys_creat)
+ .long SYMBOL_NAME(sys_link)
+ .long SYMBOL_NAME(sys_unlink) /* 10 */
+ .long SYMBOL_NAME(sys_execve)
+ .long SYMBOL_NAME(sys_chdir)
+ .long SYMBOL_NAME(sys_time)
+ .long SYMBOL_NAME(sys_mknod)
+ .long SYMBOL_NAME(sys_chmod) /* 15 */
+ .long SYMBOL_NAME(sys_lchown)
+ .long SYMBOL_NAME(sys_ni_syscall) /* old break syscall holder */
+ .long SYMBOL_NAME(sys_stat)
+ .long SYMBOL_NAME(sys_lseek)
+ .long SYMBOL_NAME(sys_getpid) /* 20 */
+ .long SYMBOL_NAME(sys_mount)
+ .long SYMBOL_NAME(sys_umount)
+ .long SYMBOL_NAME(sys_setuid)
+ .long SYMBOL_NAME(sys_getuid)
+ .long SYMBOL_NAME(sys_stime) /* 25 */
+ .long SYMBOL_NAME(sys_ptrace)
+ .long SYMBOL_NAME(sys_alarm)
+ .long SYMBOL_NAME(sys_fstat)
+ .long SYMBOL_NAME(sys_pause)
+ .long SYMBOL_NAME(sys_utime) /* 30 */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old stty syscall holder */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old gtty syscall holder */
+ .long SYMBOL_NAME(sys_access)
+ .long SYMBOL_NAME(sys_nice)
+ .long SYMBOL_NAME(sys_ni_syscall) /* 35 */ /* old ftime syscall holder */
+ .long SYMBOL_NAME(sys_sync)
+ .long SYMBOL_NAME(sys_kill)
+ .long SYMBOL_NAME(sys_rename)
+ .long SYMBOL_NAME(sys_mkdir)
+ .long SYMBOL_NAME(sys_rmdir) /* 40 */
+ .long SYMBOL_NAME(sys_dup)
+ .long SYMBOL_NAME(sys_pipe)
+ .long SYMBOL_NAME(sys_times)
+ .long SYMBOL_NAME(sys_ni_syscall) /* old prof syscall holder */
+ .long SYMBOL_NAME(sys_brk) /* 45 */
+ .long SYMBOL_NAME(sys_setgid)
+ .long SYMBOL_NAME(sys_getgid)
+ .long SYMBOL_NAME(sys_signal)
+ .long SYMBOL_NAME(sys_geteuid)
+ .long SYMBOL_NAME(sys_getegid) /* 50 */
+ .long SYMBOL_NAME(sys_acct)
+ .long SYMBOL_NAME(sys_ni_syscall) /* old phys syscall holder */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old lock syscall holder */
+ .long SYMBOL_NAME(sys_ioctl)
+ .long SYMBOL_NAME(sys_fcntl) /* 55 */
+ .long SYMBOL_NAME(sys_ni_syscall) /* old mpx syscall holder */
+ .long SYMBOL_NAME(sys_setpgid)
+ .long SYMBOL_NAME(sys_ni_syscall) /* old ulimit syscall holder */
+ .long SYMBOL_NAME(sys_olduname)
+ .long SYMBOL_NAME(sys_umask) /* 60 */
+ .long SYMBOL_NAME(sys_chroot)
+ .long SYMBOL_NAME(sys_ustat)
+ .long SYMBOL_NAME(sys_dup2)
+ .long SYMBOL_NAME(sys_getppid)
+ .long SYMBOL_NAME(sys_getpgrp) /* 65 */
+ .long SYMBOL_NAME(sys_setsid)
+ .long SYMBOL_NAME(sys_sigaction)
+ .long SYMBOL_NAME(sys_sgetmask)
+ .long SYMBOL_NAME(sys_ssetmask)
+ .long SYMBOL_NAME(sys_setreuid) /* 70 */
+ .long SYMBOL_NAME(sys_setregid)
+ .long SYMBOL_NAME(sys_sigsuspend)
+ .long SYMBOL_NAME(sys_sigpending)
+ .long SYMBOL_NAME(sys_sethostname)
+ .long SYMBOL_NAME(sys_setrlimit) /* 75 */
+ .long SYMBOL_NAME(sys_getrlimit)
+ .long SYMBOL_NAME(sys_getrusage)
+ .long SYMBOL_NAME(sys_gettimeofday)
+ .long SYMBOL_NAME(sys_settimeofday)
+ .long SYMBOL_NAME(sys_getgroups) /* 80 */
+ .long SYMBOL_NAME(sys_setgroups)
+ .long SYMBOL_NAME(old_select)
+ .long SYMBOL_NAME(sys_symlink)
+ .long SYMBOL_NAME(sys_lstat)
+ .long SYMBOL_NAME(sys_readlink) /* 85 */
+ .long SYMBOL_NAME(sys_uselib)
+ .long SYMBOL_NAME(sys_swapon)
+ .long SYMBOL_NAME(sys_reboot)
+ .long SYMBOL_NAME(old_readdir)
+ .long SYMBOL_NAME(old_mmap) /* 90 */
+ .long SYMBOL_NAME(sys_munmap)
+ .long SYMBOL_NAME(sys_truncate)
+ .long SYMBOL_NAME(sys_ftruncate)
+ .long SYMBOL_NAME(sys_fchmod)
+ .long SYMBOL_NAME(sys_fchown) /* 95 */
+ .long SYMBOL_NAME(sys_getpriority)
+ .long SYMBOL_NAME(sys_setpriority)
+ .long SYMBOL_NAME(sys_ni_syscall) /* old profil syscall holder */
+ .long SYMBOL_NAME(sys_statfs)
+ .long SYMBOL_NAME(sys_fstatfs) /* 100 */
+ .long SYMBOL_NAME(sys_ioperm)
+ .long SYMBOL_NAME(sys_socketcall)
+ .long SYMBOL_NAME(sys_syslog)
+ .long SYMBOL_NAME(sys_setitimer)
+ .long SYMBOL_NAME(sys_getitimer) /* 105 */
+ .long SYMBOL_NAME(sys_newstat)
+ .long SYMBOL_NAME(sys_newlstat)
+ .long SYMBOL_NAME(sys_newfstat)
+ .long SYMBOL_NAME(sys_uname)
+ .long SYMBOL_NAME(sys_iopl) /* 110 */
+ .long SYMBOL_NAME(sys_vhangup)
+ .long SYMBOL_NAME(sys_idle)
+ .long SYMBOL_NAME(sys_vm86old)
+ .long SYMBOL_NAME(sys_wait4)
+ .long SYMBOL_NAME(sys_swapoff) /* 115 */
+ .long SYMBOL_NAME(sys_sysinfo)
+ .long SYMBOL_NAME(sys_ipc)
+ .long SYMBOL_NAME(sys_fsync)
+ .long SYMBOL_NAME(sys_sigreturn)
+ .long SYMBOL_NAME(sys_clone) /* 120 */
+ .long SYMBOL_NAME(sys_setdomainname)
+ .long SYMBOL_NAME(sys_newuname)
+ .long SYMBOL_NAME(sys_modify_ldt)
+ .long SYMBOL_NAME(sys_adjtimex)
+ .long SYMBOL_NAME(sys_mprotect) /* 125 */
+ .long SYMBOL_NAME(sys_sigprocmask)
+ .long SYMBOL_NAME(sys_create_module)
+ .long SYMBOL_NAME(sys_init_module)
+ .long SYMBOL_NAME(sys_delete_module)
+ .long SYMBOL_NAME(sys_get_kernel_syms) /* 130 */
+ .long SYMBOL_NAME(sys_quotactl)
+ .long SYMBOL_NAME(sys_getpgid)
+ .long SYMBOL_NAME(sys_fchdir)
+ .long SYMBOL_NAME(sys_bdflush)
+ .long SYMBOL_NAME(sys_sysfs) /* 135 */
+ .long SYMBOL_NAME(sys_personality)
+ .long SYMBOL_NAME(sys_ni_syscall) /* for afs_syscall */
+ .long SYMBOL_NAME(sys_setfsuid)
+ .long SYMBOL_NAME(sys_setfsgid)
+ .long SYMBOL_NAME(sys_llseek) /* 140 */
+ .long SYMBOL_NAME(sys_getdents)
+ .long SYMBOL_NAME(sys_select)
+ .long SYMBOL_NAME(sys_flock)
+ .long SYMBOL_NAME(sys_msync)
+ .long SYMBOL_NAME(sys_readv) /* 145 */
+ .long SYMBOL_NAME(sys_writev)
+ .long SYMBOL_NAME(sys_getsid)
+ .long SYMBOL_NAME(sys_fdatasync)
+ .long SYMBOL_NAME(sys_sysctl)
+ .long SYMBOL_NAME(sys_mlock) /* 150 */
+ .long SYMBOL_NAME(sys_munlock)
+ .long SYMBOL_NAME(sys_mlockall)
+ .long SYMBOL_NAME(sys_munlockall)
+ .long SYMBOL_NAME(sys_sched_setparam)
+ .long SYMBOL_NAME(sys_sched_getparam) /* 155 */
+ .long SYMBOL_NAME(sys_sched_setscheduler)
+ .long SYMBOL_NAME(sys_sched_getscheduler)
+ .long SYMBOL_NAME(sys_sched_yield)
+ .long SYMBOL_NAME(sys_sched_get_priority_max)
+ .long SYMBOL_NAME(sys_sched_get_priority_min) /* 160 */
+ .long SYMBOL_NAME(sys_sched_rr_get_interval)
+ .long SYMBOL_NAME(sys_nanosleep)
+ .long SYMBOL_NAME(sys_mremap)
+ .long SYMBOL_NAME(sys_setresuid)
+ .long SYMBOL_NAME(sys_getresuid) /* 165 */
+ .long SYMBOL_NAME(sys_vm86)
+ .long SYMBOL_NAME(sys_query_module)
+ .long SYMBOL_NAME(sys_poll)
+ .long SYMBOL_NAME(sys_nfsservctl)
+ .long SYMBOL_NAME(sys_setresgid) /* 170 */
+ .long SYMBOL_NAME(sys_getresgid)
+ .long SYMBOL_NAME(sys_prctl)
+ .long SYMBOL_NAME(sys_rt_sigreturn)
+ .long SYMBOL_NAME(sys_rt_sigaction)
+ .long SYMBOL_NAME(sys_rt_sigprocmask) /* 175 */
+ .long SYMBOL_NAME(sys_rt_sigpending)
+ .long SYMBOL_NAME(sys_rt_sigtimedwait)
+ .long SYMBOL_NAME(sys_rt_sigqueueinfo)
+ .long SYMBOL_NAME(sys_rt_sigsuspend)
+ .long SYMBOL_NAME(sys_pread) /* 180 */
+ .long SYMBOL_NAME(sys_pwrite)
+ .long SYMBOL_NAME(sys_chown)
+ .long SYMBOL_NAME(sys_getcwd)
+ .long SYMBOL_NAME(sys_capget)
+ .long SYMBOL_NAME(sys_capset) /* 185 */
+ .long SYMBOL_NAME(sys_sigaltstack)
+ .long SYMBOL_NAME(sys_sendfile)
+ .long SYMBOL_NAME(sys_ni_syscall) /* streams1 */
+ .long SYMBOL_NAME(sys_ni_syscall) /* streams2 */
+ .long SYMBOL_NAME(sys_table) /* 190 */
+
+ .rept NR_syscalls-190
+ .long SYMBOL_NAME(sys_ni_syscall)
+ .endr
diff --git a/kernel/table21/main.c b/kernel/table21/main.c
new file mode 100644
index 00000000..e6d1882b
--- /dev/null
+++ b/kernel/table21/main.c
@@ -0,0 +1,61 @@
+/*
+ * linux/table/table_impl.c
+ * Copyright (C) 1998 Martin Baulig
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/kernel_stat.h>
+#include <linux/tty.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/string.h>
+#include <linux/mman.h>
+#include <linux/proc_fs.h>
+#include <linux/ioport.h>
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/swap.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/signal.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+
+#include <linux/module.h>
+#include <linux/table.h>
+
+#include "version.h"
+
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+
+int (*table_function_ptr) (int, union table *, const void *) = 0;
+
+EXPORT_SYMBOL(table_function_ptr);
+
+EXPORT_SYMBOL(nr_running);
+EXPORT_SYMBOL(pidhash);
+EXPORT_SYMBOL(task);
+EXPORT_SYMBOL(si_swapinfo);
+EXPORT_SYMBOL(scheduling_functions_start_here);
+EXPORT_SYMBOL(scheduling_functions_end_here);
+EXPORT_SYMBOL(avenrun);
+EXPORT_SYMBOL(nr_tasks);
+EXPORT_SYMBOL(last_pid);
+EXPORT_SYMBOL(page_cache_size);
+EXPORT_SYMBOL(init_mm);
+
+asmlinkage int
+sys_table (int type, union table *buf, const void *param)
+{
+ if (table_function_ptr == 0)
+ return -ENOSYS;
+
+ return (*table_function_ptr) (type, buf, param);
+}
diff --git a/kernel/table21/module.c b/kernel/table21/module.c
new file mode 100644
index 00000000..1c1fa9c2
--- /dev/null
+++ b/kernel/table21/module.c
@@ -0,0 +1,607 @@
+/*
+ * linux/table/table_impl.c
+ * Copyright (C) 1998 Martin Baulig
+ */
+
+#include <linux/types.h>
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/kernel_stat.h>
+#include <linux/tty.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/string.h>
+#include <linux/mman.h>
+#include <linux/proc_fs.h>
+#include <linux/ioport.h>
+#include <linux/config.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
+#include <linux/swap.h>
+#include <linux/slab.h>
+#include <linux/smp.h>
+#include <linux/signal.h>
+
+#include <asm/uaccess.h>
+#include <asm/pgtable.h>
+#include <asm/io.h>
+
+#include <linux/module.h>
+#include <linux/table.h>
+
+#include "version.h"
+
+extern int (*table_function_ptr) (int, union table *, const void *);
+
+int table_fkt (int, union table *, const void *);
+
+EXPORT_NO_SYMBOLS;
+
+int
+init_module(void)
+{
+ printk ("init_module () = %p - %d, %d\n",
+ table_fkt, sizeof (union table), sizeof (sigset_t));
+ table_function_ptr = table_fkt;
+ return 0;
+}
+
+void
+cleanup_module(void)
+{
+ table_function_ptr = 0;
+}
+
+#define LOAD_INT(x) ((x) >> FSHIFT)
+#define LOAD_FRAC(x) LOAD_INT(((x) & (FIXED_1-1)) * 100)
+
+#ifdef CONFIG_DEBUG_MALLOC
+int get_malloc(char * buffer);
+#endif
+
+static void collect_sigign_sigcatch(struct task_struct *p, sigset_t *ign,
+ sigset_t *catch)
+{
+ struct k_sigaction *k;
+ int i;
+
+ sigemptyset(ign);
+ sigemptyset(catch);
+
+#if 0
+ printk ("collect_sigign_sigcatch: %p - %p\n",
+ p, p->sig);
+#endif
+
+ if (p->sig) {
+ k = p->sig->action;
+ for (i = 1; i <= _NSIG; ++i, ++k) {
+#if 0
+ printk ("signal: %d - %p (%p, %p)\n",
+ i, k->sa.sa_handler, SIG_IGN, SIG_DFL);
+#endif
+ if (k->sa.sa_handler == SIG_IGN)
+ sigaddset(ign, i);
+ else if (k->sa.sa_handler != SIG_DFL)
+ sigaddset(catch, i);
+ }
+ }
+}
+
+/*
+ * These bracket the sleeping functions..
+ */
+extern void scheduling_functions_start_here(void);
+extern void scheduling_functions_end_here(void);
+#define first_sched ((unsigned long) scheduling_functions_start_here)
+#define last_sched ((unsigned long) scheduling_functions_end_here)
+
+static unsigned long get_wchan(struct task_struct *p)
+{
+ if (!p || p == current || p->state == TASK_RUNNING)
+ return 0;
+#if defined(__i386__)
+ {
+ unsigned long ebp, eip;
+ unsigned long stack_page;
+ int count = 0;
+
+ stack_page = 4096 + (unsigned long)p;
+ if (!stack_page)
+ return 0;
+ ebp = p->tss.ebp;
+ do {
+ if (ebp < stack_page || ebp >= 4092+stack_page)
+ return 0;
+ eip = *(unsigned long *) (ebp+4);
+ if (eip < first_sched || eip >= last_sched)
+ return eip;
+ ebp = *(unsigned long *) ebp;
+ } while (count++ < 16);
+ }
+#elif defined(__alpha__)
+ /*
+ * This one depends on the frame size of schedule(). Do a
+ * "disass schedule" in gdb to find the frame size. Also, the
+ * code assumes that sleep_on() follows immediately after
+ * interruptible_sleep_on() and that add_timer() follows
+ * immediately after interruptible_sleep(). Ugly, isn't it?
+ * Maybe adding a wchan field to task_struct would be better,
+ * after all...
+ */
+ {
+ unsigned long schedule_frame;
+ unsigned long pc;
+
+ pc = thread_saved_pc(&p->tss);
+ if (pc >= first_sched && pc < last_sched) {
+ schedule_frame = ((unsigned long *)p->tss.ksp)[6];
+ return ((unsigned long *)schedule_frame)[12];
+ }
+ return pc;
+ }
+#elif defined(__mc68000__)
+ {
+ unsigned long fp, pc;
+ unsigned long stack_page;
+ int count = 0;
+ extern int sys_pause (void);
+
+ stack_page = p->kernel_stack_page;
+ if (!stack_page)
+ return 0;
+ fp = ((struct switch_stack *)p->tss.ksp)->a6;
+ do {
+ if (fp < stack_page || fp >= 4088+stack_page)
+ return 0;
+ pc = ((unsigned long *)fp)[1];
+ /* FIXME: This depends on the order of these functions. */
+ if (pc < first_sched || pc >= last_sched)
+ return pc;
+ fp = *(unsigned long *) fp;
+ } while (count++ < 16);
+ }
+#elif defined(__powerpc__)
+ return (p->tss.wchan);
+#elif defined (CONFIG_ARM)
+ {
+ unsigned long fp, lr;
+ unsigned long stack_page;
+ int count = 0;
+
+ stack_page = 4096 + (unsigned long)p;
+ fp = get_css_fp (&p->tss);
+ do {
+ if (fp < stack_page || fp > 4092+stack_page)
+ return 0;
+ lr = pc_pointer (((unsigned long *)fp)[-1]);
+ if (lr < first_sched || lr > last_sched)
+ return lr;
+ fp = *(unsigned long *) (fp - 12);
+ } while (count ++ < 16);
+ }
+#endif
+ return 0;
+}
+
+#if defined(__i386__)
+# define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1019])
+# define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022])
+#elif defined(__alpha__)
+ /*
+ * See arch/alpha/kernel/ptrace.c for details.
+ */
+# define PT_REG(reg) (PAGE_SIZE - sizeof(struct pt_regs) \
+ + (long)&((struct pt_regs *)0)->reg)
+# define KSTK_EIP(tsk) \
+ (*(unsigned long *)(PT_REG(pc) + PAGE_SIZE + (unsigned long)(tsk)))
+# define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp)
+#elif defined(CONFIG_ARM)
+# define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1022])
+# define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)(tsk)))[1020])
+#elif defined(__mc68000__)
+#define KSTK_EIP(tsk) \
+ ({ \
+ unsigned long eip = 0; \
+ if ((tsk)->tss.esp0 > PAGE_SIZE && \
+ MAP_NR((tsk)->tss.esp0) < max_mapnr) \
+ eip = ((struct pt_regs *) (tsk)->tss.esp0)->pc; \
+ eip; })
+#define KSTK_ESP(tsk) ((tsk) == current ? rdusp() : (tsk)->tss.usp)
+#elif defined(__powerpc__)
+#define KSTK_EIP(tsk) ((tsk)->tss.regs->nip)
+#define KSTK_ESP(tsk) ((tsk)->tss.regs->gpr[1])
+#elif defined (__sparc_v9__)
+# define KSTK_EIP(tsk) ((tsk)->tss.kregs->tpc)
+# define KSTK_ESP(tsk) ((tsk)->tss.kregs->u_regs[UREG_FP])
+#elif defined(__sparc__)
+# define KSTK_EIP(tsk) ((tsk)->tss.kregs->pc)
+# define KSTK_ESP(tsk) ((tsk)->tss.kregs->u_regs[UREG_FP])
+#endif
+
+/* Gcc optimizes away "strlen(x)" for constant x */
+#define ADDBUF(buffer, string) \
+do { memcpy(buffer, string, strlen(string)); \
+ buffer += strlen(string); } while (0)
+
+static inline void statm_pte_range(pmd_t * pmd, unsigned long address, unsigned long size,
+ int * pages, int * shared, int * dirty, int * total)
+{
+ pte_t * pte;
+ unsigned long end;
+
+ if (pmd_none(*pmd))
+ return;
+ if (pmd_bad(*pmd)) {
+ printk("statm_pte_range: bad pmd (%08lx)\n", pmd_val(*pmd));
+ pmd_clear(pmd);
+ return;
+ }
+ pte = pte_offset(pmd, address);
+ address &= ~PMD_MASK;
+ end = address + size;
+ if (end > PMD_SIZE)
+ end = PMD_SIZE;
+ do {
+ pte_t page = *pte;
+
+ address += PAGE_SIZE;
+ pte++;
+ if (pte_none(page))
+ continue;
+ ++*total;
+ if (!pte_present(page))
+ continue;
+ ++*pages;
+ if (pte_dirty(page))
+ ++*dirty;
+ if (MAP_NR(pte_page(page)) >= max_mapnr)
+ continue;
+ if (atomic_read(&mem_map[MAP_NR(pte_page(page))].count) > 1)
+ ++*shared;
+ } while (address < end);
+}
+
+static inline void statm_pmd_range(pgd_t * pgd, unsigned long address, unsigned long size,
+ int * pages, int * shared, int * dirty, int * total)
+{
+ pmd_t * pmd;
+ unsigned long end;
+
+ if (pgd_none(*pgd))
+ return;
+ if (pgd_bad(*pgd)) {
+ printk("statm_pmd_range: bad pgd (%08lx)\n", pgd_val(*pgd));
+ pgd_clear(pgd);
+ return;
+ }
+ pmd = pmd_offset(pgd, address);
+ address &= ~PGDIR_MASK;
+ end = address + size;
+ if (end > PGDIR_SIZE)
+ end = PGDIR_SIZE;
+ do {
+ statm_pte_range(pmd, address, end - address, pages, shared, dirty, total);
+ address = (address + PMD_SIZE) & PMD_MASK;
+ pmd++;
+ } while (address < end);
+}
+
+static void statm_pgd_range(pgd_t * pgd, unsigned long address, unsigned long end,
+ int * pages, int * shared, int * dirty, int * total)
+{
+ while (address < end) {
+ statm_pmd_range(pgd, address, end - address, pages, shared, dirty, total);
+ address = (address + PGDIR_SIZE) & PGDIR_MASK;
+ pgd++;
+ }
+}
+
+int
+table_fkt (int type, union table *buf, const void *param)
+{
+ union table tbl;
+ struct sysinfo i;
+ struct task_struct *tsk = NULL;
+ struct proclist_args plistargs;
+ int index, tindex, err, tty;
+ sigset_t sigign, sigcatch;
+ pid_t pid;
+
+ if (type == TABLE_VERSION)
+ return _TABLE_VERSION;
+
+ if (!buf)
+ return -EFAULT;
+
+ memset (&tbl, 0, sizeof (union table));
+
+ /* For TABLE_PROC_*, read pid and get task_struct */
+
+ switch (type) {
+ case TABLE_PROC_UID:
+ case TABLE_PROC_MEM:
+ case TABLE_PROC_SEGMENT:
+ case TABLE_PROC_TIME:
+ case TABLE_PROC_STATE:
+ case TABLE_PROC_SIGNAL:
+ case TABLE_PROC_KERNEL:
+ err = verify_area (VERIFY_READ, param, sizeof (pid_t));
+ if (err)
+ return err;
+ copy_from_user (&pid, param, sizeof (pid_t));
+
+ read_lock (&tasklist_lock);
+ tsk = find_task_by_pid (pid);
+ /* FIXME!! This should be done after the last use */
+ read_unlock(&tasklist_lock);
+
+ if (tsk == NULL)
+ return -ESRCH;
+ break;
+ case TABLE_PROCLIST:
+ err = verify_area (VERIFY_READ, param,
+ sizeof (struct proclist_args));
+ if (err)
+ return err;
+ copy_from_user (&plistargs, param,
+ sizeof (struct proclist_args));
+ break;
+ }
+
+ /* Main function dispatcher */
+
+ switch (type) {
+ case TABLE_PROCLIST:
+ tsk = task [0];
+ read_lock (&tasklist_lock);
+ for (index = tindex = 0; index < nr_tasks;
+ index++, tsk = tsk->next_task) {
+ if (tsk->pid == 0) continue;
+ switch (plistargs.which & TABLE_KERN_PROC_MASK) {
+ case TABLE_KERN_PROC_PID:
+ if (tsk->pid != plistargs.arg) continue;
+ break;
+ case TABLE_KERN_PROC_PGRP:
+ if (tsk->pgrp != plistargs.arg) continue;
+ break;
+ case TABLE_KERN_PROC_SESSION:
+ if (tsk->session != plistargs.arg) continue;
+ case TABLE_KERN_PROC_TTY:
+ tty = tsk->tty ?
+ kdev_t_to_nr (tsk->tty->device) : 0;
+ if (tty != plistargs.arg) continue;
+ break;
+ case TABLE_KERN_PROC_UID:
+ if (tsk->uid != plistargs.arg) continue;
+ break;
+ case TABLE_KERN_PROC_RUID:
+ if (tsk->euid != plistargs.arg) continue;
+ break;
+ }
+
+ if ((plistargs.which & TABLE_EXCLUDE_IDLE) &&
+ (tsk->state != 0))
+ continue;
+
+ if ((plistargs.which & TABLE_EXCLUDE_NOTTY) &&
+ (tsk->tty == NULL))
+ continue;
+
+ tbl.proclist.pids [tindex++] = tsk->pid;
+ }
+ tbl.proclist.nr_running = nr_running;
+ tbl.proclist.last_pid = last_pid;
+ tbl.proclist.nr_tasks = tindex;
+ read_unlock(&tasklist_lock);
+ break;
+ case TABLE_CPU:
+ tbl.cpu.total = jiffies;
+ tbl.cpu.user = kstat.cpu_user;
+ tbl.cpu.nice = kstat.cpu_nice;
+ tbl.cpu.sys = kstat.cpu_system;
+ tbl.cpu.idle = tbl.cpu.total -
+ (tbl.cpu.user + tbl.cpu.nice + tbl.cpu.sys);
+ tbl.cpu.frequency = HZ;
+ break;
+ case TABLE_MEM:
+ si_meminfo (&i);
+ tbl.mem.total = i.totalram;
+ tbl.mem.used = i.totalram - i.freeram;
+ tbl.mem.free = i.freeram;
+ tbl.mem.shared = i.sharedram;
+ tbl.mem.buffer = i.bufferram;
+ tbl.mem.cached = page_cache_size << PAGE_SHIFT;
+ break;
+ case TABLE_SWAP:
+ si_swapinfo (&i);
+ tbl.swap.total = i.totalswap;
+ tbl.swap.used = i.totalswap - i.freeswap;
+ tbl.swap.free = i.freeswap;
+ break;
+ case TABLE_LOADAVG:
+ tbl.loadavg.loadavg [0] = (double) avenrun [0] / (1 << FSHIFT);
+ tbl.loadavg.loadavg [1] = (double) avenrun [1] / (1 << FSHIFT);
+ tbl.loadavg.loadavg [2] = (double) avenrun [2] / (1 << FSHIFT);
+ tbl.loadavg.nr_running = nr_running;
+ tbl.loadavg.nr_tasks = nr_tasks;
+ tbl.loadavg.last_pid = last_pid;
+ break;
+ case TABLE_UPTIME:
+ tbl.uptime.uptime = jiffies;
+ tbl.uptime.idle = task[0]->times.tms_utime +
+ task[0]->times.tms_stime;
+ break;
+ case TABLE_PROC_STATE:
+ tbl.proc_state.uid = tsk->uid;
+ tbl.proc_state.gid = tsk->gid;
+ tbl.proc_state.state = tsk->state;
+ tbl.proc_state.flags = tsk->flags;
+ memcpy (tbl.proc_state.comm, tsk->comm,
+ sizeof (tbl.proc_state.comm));
+ break;
+ case TABLE_PROC_UID:
+ tbl.proc_uid.uid = tsk->uid;
+ tbl.proc_uid.euid = tsk->euid;
+ tbl.proc_uid.suid = tsk->suid;
+ tbl.proc_uid.fsuid = tsk->fsuid;
+
+ tbl.proc_uid.gid = tsk->gid;
+ tbl.proc_uid.egid = tsk->egid;
+ tbl.proc_uid.sgid = tsk->sgid;
+ tbl.proc_uid.fsgid = tsk->fsgid;
+
+ tbl.proc_uid.pid = tsk->pid;
+ tbl.proc_uid.pgrp = tsk->pgrp;
+ tbl.proc_uid.ppid = tsk->p_pptr->pid;
+
+ tbl.proc_uid.session = tsk->session;
+ tbl.proc_uid.tty = tsk->tty ?
+ kdev_t_to_nr (tsk->tty->device) : 0;
+ tbl.proc_uid.tpgid = tsk->tty ? tsk->tty->pgrp : -1;
+
+ tbl.proc_uid.priority = tsk->priority;
+ tbl.proc_uid.counter = tsk->counter;
+ tbl.proc_uid.def_priority = DEF_PRIORITY;
+ break;
+ case TABLE_PROC_SIGNAL:
+ memcpy (&tbl.proc_signal.signal, &tsk->signal,
+ sizeof (tbl.proc_signal.signal));
+
+ memcpy (&tbl.proc_signal.blocked, &tsk->blocked,
+ sizeof (tbl.proc_signal.blocked));
+
+ collect_sigign_sigcatch (tsk, &sigign, &sigcatch);
+
+ memcpy (&tbl.proc_signal.ignored, &sigign,
+ sizeof (tbl.proc_signal.ignored));
+
+ memcpy (&tbl.proc_signal.caught, &sigcatch,
+ sizeof (tbl.proc_signal.caught));
+
+#if 0
+ printk ("PROC_SIGNAL: (%lu, %lu) - (%lu, %lu)\n",
+ tbl.proc_signal.ignored.sig [0],
+ tbl.proc_signal.ignored.sig [1],
+ tbl.proc_signal.caught.sig [0],
+ tbl.proc_signal.caught.sig [1]);
+#endif
+ break;
+ case TABLE_PROC_MEM:
+ if (tsk->mm && tsk->mm != &init_mm) {
+ tbl.proc_mem.context = tsk->mm->context;
+ tbl.proc_mem.start_code = tsk->mm->start_code;
+ tbl.proc_mem.end_code = tsk->mm->end_code;
+ tbl.proc_mem.start_data = tsk->mm-> start_data;
+ tbl.proc_mem.end_data = tsk->mm->end_data;
+ tbl.proc_mem.start_brk = tsk->mm->start_brk;
+ tbl.proc_mem.brk = tsk->mm->brk;
+ tbl.proc_mem.start_stack = tsk->mm->start_stack;
+ tbl.proc_mem.start_mmap = tsk->mm->mmap ?
+ tsk->mm->mmap->vm_start : 0;
+ tbl.proc_mem.arg_start = tsk->mm->arg_start;
+ tbl.proc_mem.arg_end = tsk->mm->arg_end;
+ tbl.proc_mem.env_start = tsk->mm->env_start;
+ tbl.proc_mem.env_end = tsk->mm->env_end;
+ tbl.proc_mem.rss = tsk->mm->rss << PAGE_SHIFT;
+ tbl.proc_mem.total_vm = tsk->mm->total_vm;
+ tbl.proc_mem.locked_vm = tsk->mm->locked_vm;
+ }
+ tbl.proc_mem.rlim = tsk->rlim ? tsk->rlim[RLIMIT_RSS].rlim_cur : 0;
+ break;
+ case TABLE_PROC_SEGMENT:
+ if (tsk->mm && tsk->mm != &init_mm) {
+ unsigned long vsize = 0;
+ int size = 0, resident = 0, share = 0;
+ int trs = 0, lrs = 0, drs = 0, srs = 0, dt = 0;
+ struct vm_area_struct * vma = tsk->mm->mmap;
+
+ while (vma) {
+ pgd_t *pgd = pgd_offset(tsk->mm, vma->vm_start);
+ int pages = 0, shared = 0, dirty = 0, total = 0;
+
+ vsize += vma->vm_end - vma->vm_start;
+
+ statm_pgd_range (pgd, vma->vm_start, vma->vm_end,
+
+ &pages, &shared, &dirty, &total);
+
+ resident += pages;
+ share += shared;
+ dt += dirty;
+ size += total;
+
+ /* Well, shared library seem to get mapped
+ * above 0x40000000 and are executable,
+ * so I use this hack to get their size.
+ */
+
+ if (vma->vm_flags & VM_GROWSDOWN)
+ srs += pages; /* stack */
+ else if ((vma->vm_flags & VM_EXEC) &&
+ (vma->vm_start > 0x40000000))
+ lrs += pages; /* library */
+ else if (vma->vm_flags & VM_EXECUTABLE)
+ trs += pages; /* text */
+ else
+ drs += pages;
+
+ vma = vma->vm_next;
+ }
+
+ tbl.proc_segment.vsize = vsize;
+ tbl.proc_segment.size = size << PAGE_SHIFT;
+ tbl.proc_segment.resident = resident << PAGE_SHIFT;
+ tbl.proc_segment.shared = share << PAGE_SHIFT;
+ tbl.proc_segment.trs = trs << PAGE_SHIFT;
+ tbl.proc_segment.lrs = lrs << PAGE_SHIFT;
+ tbl.proc_segment.drs = drs << PAGE_SHIFT;
+ tbl.proc_segment.srs = srs << PAGE_SHIFT;
+ tbl.proc_segment.dt = dt << PAGE_SHIFT;
+ }
+ break;
+ case TABLE_PROC_TIME:
+ tbl.proc_time.utime = tsk->times.tms_utime;
+ tbl.proc_time.stime = tsk->times.tms_stime;
+ tbl.proc_time.cutime = tsk->times.tms_cutime;
+ tbl.proc_time.cstime = tsk->times.tms_cstime;
+
+ tbl.proc_time.start_time = tsk->start_time;
+ tbl.proc_time.timeout = tsk->timeout;
+ tbl.proc_time.policy = tsk->policy;
+ tbl.proc_time.rt_priority = tsk->rt_priority;
+
+ tbl.proc_time.it_real_value = tsk->it_real_value;
+ tbl.proc_time.it_prof_value = tsk->it_prof_value;
+ tbl.proc_time.it_virt_value = tsk->it_virt_value;
+ tbl.proc_time.it_real_incr = tsk->it_real_incr;
+ tbl.proc_time.it_prof_incr = tsk->it_prof_incr;
+ tbl.proc_time.it_virt_incr = tsk->it_virt_incr;
+ break;
+ case TABLE_PROC_KERNEL:
+ tbl.proc_kernel.min_flt = tsk->min_flt;
+ tbl.proc_kernel.cmin_flt = tsk->cmin_flt;
+ tbl.proc_kernel.maj_flt = tsk->maj_flt;
+ tbl.proc_kernel.cmaj_flt = tsk->cmaj_flt;
+
+ tbl.proc_kernel.kesp = KSTK_ESP(tsk);
+ tbl.proc_kernel.keip = KSTK_EIP(tsk);
+
+ tbl.proc_kernel.nswap = tsk->nswap;
+ tbl.proc_kernel.cnswap = tsk->cnswap;
+
+ tbl.proc_kernel.wchan = get_wchan (tsk);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ err = verify_area (VERIFY_WRITE, buf, sizeof (struct table));
+ if (err)
+ return err;
+
+ copy_to_user (buf, &tbl, sizeof (union table));
+
+ return 0;
+}
diff --git a/kernel/table21/unistd-i386.h b/kernel/table21/unistd-i386.h
new file mode 100644
index 00000000..a7c30c83
--- /dev/null
+++ b/kernel/table21/unistd-i386.h
@@ -0,0 +1,344 @@
+#ifndef _ASM_I386_UNISTD_H_
+#define _ASM_I386_UNISTD_H_
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_setup 0 /* used only by init, to get system going */
+#define __NR_exit 1
+#define __NR_fork 2
+#define __NR_read 3
+#define __NR_write 4
+#define __NR_open 5
+#define __NR_close 6
+#define __NR_waitpid 7
+#define __NR_creat 8
+#define __NR_link 9
+#define __NR_unlink 10
+#define __NR_execve 11
+#define __NR_chdir 12
+#define __NR_time 13
+#define __NR_mknod 14
+#define __NR_chmod 15
+#define __NR_lchown 16
+#define __NR_break 17
+#define __NR_oldstat 18
+#define __NR_lseek 19
+#define __NR_getpid 20
+#define __NR_mount 21
+#define __NR_umount 22
+#define __NR_setuid 23
+#define __NR_getuid 24
+#define __NR_stime 25
+#define __NR_ptrace 26
+#define __NR_alarm 27
+#define __NR_oldfstat 28
+#define __NR_pause 29
+#define __NR_utime 30
+#define __NR_stty 31
+#define __NR_gtty 32
+#define __NR_access 33
+#define __NR_nice 34
+#define __NR_ftime 35
+#define __NR_sync 36
+#define __NR_kill 37
+#define __NR_rename 38
+#define __NR_mkdir 39
+#define __NR_rmdir 40
+#define __NR_dup 41
+#define __NR_pipe 42
+#define __NR_times 43
+#define __NR_prof 44
+#define __NR_brk 45
+#define __NR_setgid 46
+#define __NR_getgid 47
+#define __NR_signal 48
+#define __NR_geteuid 49
+#define __NR_getegid 50
+#define __NR_acct 51
+#define __NR_phys 52
+#define __NR_lock 53
+#define __NR_ioctl 54
+#define __NR_fcntl 55
+#define __NR_mpx 56
+#define __NR_setpgid 57
+#define __NR_ulimit 58
+#define __NR_oldolduname 59
+#define __NR_umask 60
+#define __NR_chroot 61
+#define __NR_ustat 62
+#define __NR_dup2 63
+#define __NR_getppid 64
+#define __NR_getpgrp 65
+#define __NR_setsid 66
+#define __NR_sigaction 67
+#define __NR_sgetmask 68
+#define __NR_ssetmask 69
+#define __NR_setreuid 70
+#define __NR_setregid 71
+#define __NR_sigsuspend 72
+#define __NR_sigpending 73
+#define __NR_sethostname 74
+#define __NR_setrlimit 75
+#define __NR_getrlimit 76
+#define __NR_getrusage 77
+#define __NR_gettimeofday 78
+#define __NR_settimeofday 79
+#define __NR_getgroups 80
+#define __NR_setgroups 81
+#define __NR_select 82
+#define __NR_symlink 83
+#define __NR_oldlstat 84
+#define __NR_readlink 85
+#define __NR_uselib 86
+#define __NR_swapon 87
+#define __NR_reboot 88
+#define __NR_readdir 89
+#define __NR_mmap 90
+#define __NR_munmap 91
+#define __NR_truncate 92
+#define __NR_ftruncate 93
+#define __NR_fchmod 94
+#define __NR_fchown 95
+#define __NR_getpriority 96
+#define __NR_setpriority 97
+#define __NR_profil 98
+#define __NR_statfs 99
+#define __NR_fstatfs 100
+#define __NR_ioperm 101
+#define __NR_socketcall 102
+#define __NR_syslog 103
+#define __NR_setitimer 104
+#define __NR_getitimer 105
+#define __NR_stat 106
+#define __NR_lstat 107
+#define __NR_fstat 108
+#define __NR_olduname 109
+#define __NR_iopl 110
+#define __NR_vhangup 111
+#define __NR_idle 112
+#define __NR_vm86old 113
+#define __NR_wait4 114
+#define __NR_swapoff 115
+#define __NR_sysinfo 116
+#define __NR_ipc 117
+#define __NR_fsync 118
+#define __NR_sigreturn 119
+#define __NR_clone 120
+#define __NR_setdomainname 121
+#define __NR_uname 122
+#define __NR_modify_ldt 123
+#define __NR_adjtimex 124
+#define __NR_mprotect 125
+#define __NR_sigprocmask 126
+#define __NR_create_module 127
+#define __NR_init_module 128
+#define __NR_delete_module 129
+#define __NR_get_kernel_syms 130
+#define __NR_quotactl 131
+#define __NR_getpgid 132
+#define __NR_fchdir 133
+#define __NR_bdflush 134
+#define __NR_sysfs 135
+#define __NR_personality 136
+#define __NR_afs_syscall 137 /* Syscall for Andrew File System */
+#define __NR_setfsuid 138
+#define __NR_setfsgid 139
+#define __NR__llseek 140
+#define __NR_getdents 141
+#define __NR__newselect 142
+#define __NR_flock 143
+#define __NR_msync 144
+#define __NR_readv 145
+#define __NR_writev 146
+#define __NR_getsid 147
+#define __NR_fdatasync 148
+#define __NR__sysctl 149
+#define __NR_mlock 150
+#define __NR_munlock 151
+#define __NR_mlockall 152
+#define __NR_munlockall 153
+#define __NR_sched_setparam 154
+#define __NR_sched_getparam 155
+#define __NR_sched_setscheduler 156
+#define __NR_sched_getscheduler 157
+#define __NR_sched_yield 158
+#define __NR_sched_get_priority_max 159
+#define __NR_sched_get_priority_min 160
+#define __NR_sched_rr_get_interval 161
+#define __NR_nanosleep 162
+#define __NR_mremap 163
+#define __NR_setresuid 164
+#define __NR_getresuid 165
+#define __NR_vm86 166
+#define __NR_query_module 167
+#define __NR_poll 168
+#define __NR_nfsservctl 169
+#define __NR_setresgid 170
+#define __NR_getresgid 171
+#define __NR_prctl 172
+#define __NR_rt_sigreturn 173
+#define __NR_rt_sigaction 174
+#define __NR_rt_sigprocmask 175
+#define __NR_rt_sigpending 176
+#define __NR_rt_sigtimedwait 177
+#define __NR_rt_sigqueueinfo 178
+#define __NR_rt_sigsuspend 179
+#define __NR_pread 180
+#define __NR_pwrite 181
+#define __NR_chown 182
+#define __NR_getcwd 183
+#define __NR_capget 184
+#define __NR_capset 185
+#define __NR_sigaltstack 186
+#define __NR_sendfile 187
+#define __NR_streams1 188 /* some people actually want it */
+#define __NR_streams2 189 /* some people actually want it */
+#define __NR_table 190
+
+/* user-visible error numbers are in the range -1 - -122: see <asm-i386/errno.h> */
+
+#define __syscall_return(type, res) \
+do { \
+ if ((unsigned long)(res) >= (unsigned long)(-125)) { \
+ errno = -(res); \
+ res = -1; \
+ } \
+ return (type) (res); \
+} while (0)
+
+/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+ : "=a" (__res) \
+ : "0" (__NR_##name)); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall1(type,name,type1,arg1) \
+type name(type1 arg1) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"b" ((long)(arg1))); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1,type2 arg2) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2))); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name(type1 arg1,type2 arg2,type3 arg3) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+ "d" ((long)(arg3))); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+ "d" ((long)(arg3)),"S" ((long)(arg4))); \
+__syscall_return(type,__res); \
+}
+
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+ type5,arg5) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+{ \
+long __res; \
+__asm__ volatile ("int $0x80" \
+ : "=a" (__res) \
+ : "0" (__NR_##name),"b" ((long)(arg1)),"c" ((long)(arg2)), \
+ "d" ((long)(arg3)),"S" ((long)(arg4)),"D" ((long)(arg5))); \
+__syscall_return(type,__res); \
+}
+
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+#define __NR__exit __NR_exit
+static inline _syscall0(int,idle)
+static inline _syscall0(int,pause)
+static inline _syscall1(int,setup,int,magic)
+static inline _syscall0(int,sync)
+static inline _syscall0(pid_t,setsid)
+static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static inline _syscall3(int,read,int,fd,char *,buf,off_t,count)
+static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count)
+static inline _syscall1(int,dup,int,fd)
+static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static inline _syscall3(int,open,const char *,file,int,flag,int,mode)
+static inline _syscall1(int,close,int,fd)
+static inline _syscall1(int,_exit,int,exitcode)
+static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+static inline _syscall1(int,delete_module,const char *,name)
+
+static inline pid_t wait(int * wait_stat)
+{
+ return waitpid(-1,wait_stat,0);
+}
+
+/*
+ * This is the mechanism for creating a new kernel thread.
+ *
+ * NOTE! Only a kernel-only process(ie the swapper or direct descendants
+ * who haven't done an "execve()") should use this: it will work within
+ * a system call from a "real" process, but the process memory space will
+ * not be free'd until both the parent and the child have exited.
+ */
+static inline pid_t kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+ long retval;
+
+ __asm__ __volatile__(
+ "movl %%esp,%%esi\n\t"
+ "int $0x80\n\t" /* Linux/i386 system call */
+ "cmpl %%esp,%%esi\n\t" /* child or parent? */
+ "je 1f\n\t" /* parent - jump */
+ "pushl %3\n\t" /* push argument */
+ "call *%4\n\t" /* call fn */
+ "movl %2,%0\n\t" /* exit */
+ "int $0x80\n"
+ "1:\t"
+ :"=a" (retval)
+ :"0" (__NR_clone), "i" (__NR_exit),
+ "r" (arg), "r" (fn),
+ "b" (flags | CLONE_VM)
+ :"si");
+ return retval;
+}
+
+#endif
+
+#endif /* _ASM_I386_UNISTD_H_ */
diff --git a/kernel/table21/version.h b/kernel/table21/version.h
new file mode 100644
index 00000000..d47411ee
--- /dev/null
+++ b/kernel/table21/version.h
@@ -0,0 +1 @@
+#define _TABLE_VERSION 1
diff --git a/kernel/version.h b/kernel/version.h
new file mode 100644
index 00000000..d47411ee
--- /dev/null
+++ b/kernel/version.h
@@ -0,0 +1 @@
+#define _TABLE_VERSION 1