Handle Linux kernels that don't export sys_call_table.
authorChaskiel M Grundman <cg2v@andrew.cmu.edu>
Tue, 12 Nov 2002 21:17:21 +0000 (21:17 +0000)
committerGarry Zacheiss <zacheiss@mit.edu>
Tue, 12 Nov 2002 21:17:21 +0000 (21:17 +0000)
acconfig.h
acinclude.m4
src/afs/LINUX/osi_module.c
src/cf/linux-test4.m4
src/cf/linux-test5.m4 [new file with mode: 0644]
src/libafs/MakefileProto.LINUX.in

index fa4756b..76cf79c 100644 (file)
@@ -36,6 +36,9 @@ static /**/const char *const rcsid[] = { (char *)rcsid, "\100(#)" msg }
 #undef STRUCT_INODE_HAS_I_DIRTY_DATA_BUFFERS
 #undef STRUCT_INODE_HAS_I_DEVICES
 #undef EXPORTED_TASKLIST_LOCK
+#undef EXPORTED_SYS_CALL_TABLE
+#undef EXPORTED_KALLSYMS_SYMBOL
+#undef EXPORTED_KALLSYMS_ADDRESS
 #undef COMPLETION_H_EXISTS
 #undef ssize_t
 
index 3324095..1fad5bd 100644 (file)
@@ -130,6 +130,12 @@ case $system in
                        OMIT_FRAME_POINTER=-fomit-frame-pointer
                 fi
                 AC_SUBST(OMIT_FRAME_POINTER)
+                OPENAFS_GCC_SUPPORTS_MARCH
+                AC_SUBST(P5PLUS_KOPTS)
+                OPENAFS_GCC_NEEDS_NO_STRENGTH_REDUCE
+                OPENAFS_GCC_NEEDS_NO_STRICT_ALIASING
+                OPENAFS_GCC_SUPPORTS_NO_COMMON
+                AC_SUBST(LINUX_GCC_KOPTS)
                 ifdef([OPENAFS_CONFIGURE_LIBAFS],
                   [LINUX_BUILD_VNODE_FROM_INODE(src/config,afs)],
                   [LINUX_BUILD_VNODE_FROM_INODE(${srcdir}/src/config,src/afs/LINUX,${srcdir}/src/afs/LINUX)]
@@ -144,9 +150,42 @@ case $system in
                 LINUX_EXPORTS_TASKLIST_LOCK
                 LINUX_NEED_RHCONFIG
                 LINUX_WHICH_MODULES
+                 if test "$ac_cv_linux_config_modversions" = "xno"; then
+                   AC_MSG_WARN([Cannot determine sys_call_table status. assuming it's exported])
+                   ac_cv_linux_exports_sys_call_table=yes
+                 else
+                   LINUX_EXPORTS_SYS_CALL_TABLE
+                   LINUX_EXPORTS_KALLSYMS_SYMBOL
+                   LINUX_EXPORTS_KALLSYMS_ADDRESS
+                   LINUX_EXPORTS_INIT_MM
+                   if test "x$ac_cv_linux_exports_sys_call_table" = "xno"; then
+                         linux_syscall_method=none
+                         if test "x$ac_cv_linux_exports_init_mm" = "xyes"; then
+                            linux_syscall_method=scan
+                            if test "x$ac_cv_linux_exports_kallsyms_address" = "xyes"; then
+                               linux_syscall_method=scan_with_kallsyms_address
+                            fi
+                         fi
+                         if test "x$ac_cv_linux_exports_kallsyms_symbol" = "xyes"; then
+                            linux_syscall_method=kallsyms_symbol
+                         fi
+                         if test "x$linux_syscall_method" = "xnone"; then
+                        AC_MSG_ERROR([no available sys_call_table access method])
+                         fi
+                   fi
+                 fi
                 if test "x$ac_cv_linux_exports_tasklist_lock" = "xyes" ; then
                  AC_DEFINE(EXPORTED_TASKLIST_LOCK, 1, [define if your linux kernel exports tasklist_lock])
                 fi
+                 if test "x$ac_cv_linux_exports_sys_call_table" = "xyes"; then
+                  AC_DEFINE(EXPORTED_SYS_CALL_TABLE)
+                 fi
+                 if test "x$ac_cv_linux_exports_kallsyms_symbol" = "xyes"; then
+                  AC_DEFINE(EXPORTED_KALLSYMS_SYMBOL)
+                 fi
+                 if test "x$ac_cv_linux_exports_kallsyms_address" = "xyes"; then
+                  AC_DEFINE(EXPORTED_KALLSYMS_ADDRESS)
+                 fi
                 if test "x$ac_cv_linux_completion_h_exists" = "xyes" ; then
                  AC_DEFINE(COMPLETION_H_EXISTS, 1, [define if your h_exists exists])
                 fi
index 3e6c939..b7a5271 100644 (file)
@@ -26,6 +26,10 @@ RCSID("$Header$");
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,0)
 #include <linux/init.h>
 #endif
+#ifndef EXPORTED_SYS_CALL_TABLE
+#include <linux/sched.h>
+#include <linux/syscall.h>
+#endif
 
 
 
@@ -37,11 +41,19 @@ asmlinkage int (*sys_settimeofdayp)(struct timeval *tv, struct timezone *tz);
 asmlinkage int (*sys_killp)(int pid, int signal);
 asmlinkage long (*sys_setgroupsp)(int gidsetsize, gid_t *grouplist);
 
+#ifdef EXPORTED_SYS_CALL_TABLE
 #ifdef AFS_SPARC64_LINUX20_ENV
 extern unsigned int sys_call_table[];  /* changed to uint because SPARC64 has syscaltable of 32bit items */
 #else
 extern void * sys_call_table[]; /* safer for other linuces */
 #endif
+#else /* EXPORTED_SYS_CALL_TABLE */
+#ifdef AFS_SPARC64_LINUX20_ENV
+static unsigned int *sys_call_table;  /* changed to uint because SPARC64 has syscaltable of 32bit items */
+#else
+static void ** sys_call_table; /* safer for other linuces */
+#endif
+#endif
 extern struct file_system_type afs_file_system;
 
 static long get_page_offset(void);
@@ -69,7 +81,11 @@ asmlinkage int (*sys32_setgroupsp)(int gidsetsize, __kernel_gid_t32 *grouplist);
 #if defined(__NR_setgroups32)
 asmlinkage int (*sys32_setgroups32p)(int gidsetsize, __kernel_gid_t32 *grouplist);
 #endif
+#ifdef EXPORTED_SYS_CALL_TABLE
 extern unsigned int sys_call_table32[];
+#else
+static unsigned int *sys_call_table32;
+#endif
 
 asmlinkage int afs_syscall32(long syscall, long parm1, long parm2, long parm3,
                             long parm4, long parm5)
@@ -197,6 +213,23 @@ int init_module(void)
 #endif
 #endif
 
+#ifndef EXPORTED_SYS_CALL_TABLE
+    unsigned long *ptr;
+    unsigned long offset;
+    unsigned long datalen;
+    int ret;
+    unsigned long token;
+    char      *mod_name;
+    unsigned long    mod_start;
+    unsigned long    mod_end;
+    char      *sec_name;
+    unsigned long    sec_start;
+    unsigned long    sec_end;
+    char      *sym_name;
+    unsigned long    sym_start;
+    unsigned long    sym_end;
+#endif
+
     RWLOCK_INIT(&afs_xosi, "afs_xosi");
 
     /* obtain PAGE_OFFSET value */
@@ -209,7 +242,58 @@ int init_module(void)
         return -EIO;
     }
 #endif
-
+#ifndef EXPORTED_SYS_CALL_TABLE
+    sys_call_table=0;
+
+#ifdef EXPORTED_KALLSYMS_SYMBOL
+    ret=1;
+    token=0;
+    while (ret) {
+      sym_start=0;
+      ret=kallsyms_symbol_to_address("sys_call_table", &token, &mod_name,
+                                    &mod_start, &mod_end, &sec_name, &sec_start, &sec_end,
+                                    &sym_name, &sym_start, &sym_end);
+      if (ret && !strcmp(mod_name, "kernel"))
+       break;
+    }
+    if (ret && sym_start) {
+      sys_call_table=sym_start;
+    }
+#else
+#ifdef EXPORTED_KALLSYMS_ADDRESS
+    ret=kallsyms_address_to_symbol((unsigned long)&init_mm, &mod_name,
+                                  &mod_start, &mod_end, &sec_name, &sec_start, &sec_end,
+                                  &sym_name, &sym_start, &sym_end);
+    ptr=(unsigned long *)sec_start;
+    datalen=(sec_end-sec_start)/sizeof(unsigned long);
+#else
+    ptr=(unsigned long *)&init_mm;
+    datalen=16384;
+#endif
+    for (offset=0;offset <datalen;ptr++,offset++) {
+      if (ptr[0] == (unsigned long)&sys_exit &&
+         ptr[__NR_open - __NR_exit] == (unsigned long)&sys_open) {
+       sys_call_table=ptr - __NR_exit;
+       break;
+      }
+    }
+#ifdef EXPORTED_KALLSYMS_ADDRESS
+    ret=kallsyms_address_to_symbol((unsigned long)sys_call_table, &mod_name,
+                                  &mod_start, &mod_end, &sec_name, &sec_start, &sec_end,
+                                  &sym_name, &sym_start, &sym_end);
+    if (ret && strcmp(sym_name, "sys_call_table"))
+      sys_call_table=0;
+#endif
+#endif
+    if (!sys_call_table) {
+      printf("Failed to find address of sys_call_table\n");
+      return -EIO;
+    }
+# ifdef AFS_SPARC64_LINUX20_ENV
+    error cant support this yet.
+#endif
+#endif /* SYS_CALL_TABLE */
+      
     /* Initialize pointers to kernel syscalls. */
 #if defined(AFS_IA64_LINUX20_ENV)
     kernel_gp = ((struct fptr *)printk)->gp;
@@ -241,7 +325,6 @@ int init_module(void)
        return -EBUSY;
     }
 
-
 #if defined(AFS_IA64_LINUX20_ENV)
     afs_ni_syscall = sys_call_table[__NR_afs_syscall - 1024];
     sys_call_table[__NR_afs_syscall - 1024] = POINTER2SYSCALL ((struct fptr *)afs_syscall_stub)->ip;
index 6947327..ca39852 100644 (file)
@@ -14,6 +14,70 @@ ac_cv_linux_exports_tasklist_lock=no)])
 AC_MSG_RESULT($ac_cv_linux_exports_tasklist_lock)
 CPPFLAGS="$save_CPPFLAGS"])
 
+AC_DEFUN(LINUX_EXPORTS_SYS_CALL_TABLE, [
+AC_MSG_CHECKING(for exported sys_call_table)
+save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -D__KERNEL__ $CPPFLAGS"
+AC_CACHE_VAL(ac_cv_linux_exports_sys_call_table,
+[
+AC_TRY_COMPILE(
+[#include <linux/modversions.h>],
+[#ifndef __ver_sys_call_table
+#error sys_call_table not exported
+#endif],
+ac_cv_linux_exports_sys_call_table=yes,
+ac_cv_linux_exports_sys_call_table=no)])
+AC_MSG_RESULT($ac_cv_linux_exports_sys_call_table)
+CPPFLAGS="$save_CPPFLAGS"])
+
+AC_DEFUN(LINUX_EXPORTS_INIT_MM, [
+AC_MSG_CHECKING(for exported init_mm)
+save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -D__KERNEL__ $CPPFLAGS"
+AC_CACHE_VAL(ac_cv_linux_exports_init_mm,
+[
+AC_TRY_COMPILE(
+[#include <linux/modversions.h>],
+[#ifndef __ver_init_mm
+#error init_mm not exported
+#endif],
+ac_cv_linux_exports_init_mm=yes,
+ac_cv_linux_exports_init_mm=no)])
+AC_MSG_RESULT($ac_cv_linux_exports_init_mm)
+CPPFLAGS="$save_CPPFLAGS"])
+
+AC_DEFUN(LINUX_EXPORTS_KALLSYMS_SYMBOL, [
+AC_MSG_CHECKING(for exported kallsyms_symbol_to_address)
+save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -D__KERNEL__ $CPPFLAGS"
+AC_CACHE_VAL(ac_cv_linux_exports_kallsyms_symbol,
+[
+AC_TRY_COMPILE(
+[#include <linux/modversions.h>],
+[#ifndef __ver_kallsyms_symbol_to_address
+#error kallsyms_symbol_to_address not exported
+#endif],
+ac_cv_linux_exports_kallsyms_symbol=yes,
+ac_cv_linux_exports_kallsyms_symbol=no)])
+AC_MSG_RESULT($ac_cv_linux_exports_kallsyms_symbol)
+CPPFLAGS="$save_CPPFLAGS"])
+
+AC_DEFUN(LINUX_EXPORTS_KALLSYMS_ADDRESS, [
+AC_MSG_CHECKING(for exported kallsyms_address_to_symbol)
+save_CPPFLAGS="$CPPFLAGS"
+CPPFLAGS="-I${LINUX_KERNEL_PATH}/include -D__KERNEL__ $CPPFLAGS"
+AC_CACHE_VAL(ac_cv_linux_exports_kallsyms_address,
+[
+AC_TRY_COMPILE(
+[#include <linux/modversions.h>],
+[#ifndef __ver_kallsyms_address_to_symbol
+#error kallsyms_address_to_symbol not exported
+#endif],
+ac_cv_linux_exports_kallsyms_address=yes,
+ac_cv_linux_exports_kallsyms_address=no)])
+AC_MSG_RESULT($ac_cv_linux_exports_kallsyms_address)
+CPPFLAGS="$save_CPPFLAGS"])
+
 AC_DEFUN(LINUX_COMPLETION_H_EXISTS, [
 AC_MSG_CHECKING(for linux/completion.h existance)
 save_CPPFLAGS="$CPPFLAGS"
diff --git a/src/cf/linux-test5.m4 b/src/cf/linux-test5.m4
new file mode 100644 (file)
index 0000000..97ce80b
--- /dev/null
@@ -0,0 +1,71 @@
+
+AC_DEFUN(OPENAFS_GCC_SUPPORTS_MARCH, [
+AC_MSG_CHECKING(if $CC accepts -march=pentium)
+save_CFLAGS="$CFLAGS"
+CFLAGS="-MARCH=pentium"
+AC_CACHE_VAL(openafs_gcc_supports_march,[
+AC_TRY_COMPILE(
+[],
+[int x;],
+openafs_gcc_supports_march=yes,
+openafs_gcc_supports_march=no)])
+AC_MSG_RESULT($openafs_gcc_supports_march)
+if test x$openafs_gcc_supports_march = xyes; then
+  P5PLUS_KOPTS="-march=pentium"
+else
+  P5PLUS_KOPTS="-m486 -malign-loops=2 -malign-jumps=2 -malign-functions=2"
+fi
+CFLAGS="$save_CFLAGS"
+])
+
+AC_DEFUN(OPENAFS_GCC_NEEDS_NO_STRICT_ALIASING, [
+AC_MSG_CHECKING(if $CC needs -fno-strict-aliasing)
+save_CFLAGS="$CFLAGS"
+CFLAGS="-fno-strict-aliasing"
+AC_CACHE_VAL(openafs_gcc_needs_no_strict_aliasing,[
+AC_TRY_COMPILE(
+[],
+[int x;],
+openafs_gcc_needs_no_strict_aliasing=yes,
+openafs_gcc_needs_no_strict_aliasing=no)])
+AC_MSG_RESULT($openafs_gcc_needs_no_strict_aliasing)
+if test x$openafs_gcc_needs_no_strict_aliasing = xyes; then
+  LINUX_GCC_KOPTS="$LINUX_GCC_KOPTS -fno-strict-aliasing"
+fi
+CFLAGS="$save_CFLAGS"
+])
+
+AC_DEFUN(OPENAFS_GCC_NEEDS_NO_STRENGTH_REDUCE, [
+AC_MSG_CHECKING(if $CC needs -fno-strength-reduce)
+save_CFLAGS="$CFLAGS"
+CFLAGS="-fno-strength-reduce"
+AC_CACHE_VAL(openafs_gcc_needs_no_strength_reduce,[
+AC_TRY_COMPILE(
+[],
+[int x;],
+openafs_gcc_needs_no_strength_reduce=yes,
+openafs_gcc_needs_no_strength_reduce=no)])
+AC_MSG_RESULT($openafs_gcc_needs_no_strength_reduce)
+if test x$openafs_gcc_needs_no_strength_reduce = xyes; then
+  LINUX_GCC_KOPTS="$LINUX_GCC_KOPTS -fno-strength-reduce"
+fi
+CFLAGS="$save_CFLAGS"
+])
+
+AC_DEFUN(OPENAFS_GCC_SUPPORTS_NO_COMMON, [
+AC_MSG_CHECKING(if $CC supports -fno-common)
+save_CFLAGS="$CFLAGS"
+CFLAGS="-fno-common"
+AC_CACHE_VAL(openafs_gcc_supports_no_common,[
+AC_TRY_COMPILE(
+[],
+[int x;],
+openafs_gcc_supports_no_common=yes,
+openafs_gcc_supports_no_common=no)])
+AC_MSG_RESULT($openafs_gcc_supports_no_common)
+if test x$openafs_gcc_supports_no_common = xyes; then
+  LINUX_GCC_KOPTS="$LINUX_GCC_KOPTS -fno-common"
+fi
+CFLAGS="$save_CFLAGS"
+])
+
index 3bdcf84..6341909 100644 (file)
@@ -30,45 +30,41 @@ AFS_OS_NFSOBJS =
 
 AFS_OS_NONFSOBJS =
 
-
+GCC_KOPTS=@LINUX_GCC_KOPTS@
 # System specific build commands and flags
 <i386_linux22 i386_linux24>
-CCFLAGS =  $(KDEBUG) -O2 $(FOMIT) \
-       -fno-strength-reduce -pipe -march=i486 -malign-loops=2 -malign-jumps=2 \
-       -malign-functions=2
+P5PLUS=@P5PLUS_KOPTS@
+CCFLAGS =  $(KDEBUG) -O2 $(FOMIT) $(GCC_KOPTS) -pipe $(P5PLUS)
 DEFINES = -D__KERNEL__  -DCPU=586 -DKERNEL -D_KERNEL -DMODULE ${SMP_DEF} ${KDEFINES}
 <alpha_linux_22 alpha_linux_24>
-CCFLAGS = $(KDEBUG) -O2 $(FOMIT) -fno-strength-reduce -pipe -mno-fp-regs -ffixed-8
+CCFLAGS = $(KDEBUG) -O2 $(FOMIT) $(GCC_KOPTS) -pipe -mno-fp-regs -ffixed-8
 DEFINES = -D__KERNEL__ -DKERNEL -D_KERNEL -DMODULE ${SMP_DEF}
 <s390_linux22 s390_linux24>
-CCFLAGS =   -O $(FOMIT) -fno-strength-reduce \
-       -fno-strict-aliasing -fsigned-char 
+CCFLAGS =   -O $(FOMIT) $(GCC_KOPTS) -fsigned-char
 DEFINES = -D__KERNEL__  -D__s390__ -DKERNEL -D_KERNEL -DMODULE ${SMP_DEF}
 <sparc_linux22 sparc_linux24>
 LD = ld -m elf32_sparc
-CCFLAGS =   $(KDEBUG) -O2 $(FOMIT) \
-       -fno-strength-reduce -pipe -mcpu=v8 -mno-fpu -fcall-used-g5 -fcall-used-g7
+CCFLAGS =   $(KDEBUG) -O2 $(FOMIT) $(GCC_KOPTS) \
+      -pipe -mcpu=v8 -mno-fpu -fcall-used-g5 -fcall-used-g7
 DEFINES = -D__KERNEL__  -DCPU=sparc -DKERNEL -D_KERNEL -DMODULE ${SMP_DEF}
 <sparc64_linux22 sparc64_linux24>
 CC = sparc64-linux-gcc
 LD = ld -m elf64_sparc
-CCFLAGS =   $(KDEBUG) -O2 $(FOMIT) \
-       -fno-strength-reduce -pipe -mcpu=ultrasparc -m64 -mno-fpu -mcmodel=medlow -ffixed-g4 -fcall-used-g5 -fcall-used-g7 -Wno-sign-compare
+CCFLAGS =   $(KDEBUG) -O2 $(FOMIT) $(GCC_KOPTS) \
+      -pipe -mcpu=ultrasparc -m64 -mno-fpu -mcmodel=medlow -ffixed-g4 -fcall-used-g5 -fcall-used-g7 -Wno-sign-compare
 DEFINES = -D__KERNEL__  -DCPU=sparc64 -DKERNEL -D_KERNEL -DMODULE ${SMP_DEF}
 <ppc_linux22 ppc_linux24>
-CCFLAGS =   $(KDEBUG) -O2 $(FOMIT) -fno-strength-reduce \
-       -fno-strict-aliasing -fsigned-char -msoft-float -pipe \
-       -fno-builtin -ffixed-r2
+CCFLAGS =   $(KDEBUG) -O2 $(FOMIT) $(GCC_KOPTS) -fsigned-char -msoft-float -pipe \
+      -fno-builtin -ffixed-r2
 DEFINES = -D__KERNEL__  -D__powerpc__ -DKERNEL -D_KERNEL -DMODULE ${SMP_DEF}
 <parisc_linux24>
-CCFLAGS =   $(KDEBUG) -O2 $(FOMIT) \
-       -fno-strict-aliasing -fno-common -fno-strength-reduce \
-        -fno-strict-aliasing -fsigned-char -mno-space-regs -mfast-indirect-calls \
-        -mdisable-fpregs -ffunction-sections -march=1.1 -mschedule=7100
+CCFLAGS =   $(KDEBUG) -O2 $(FOMIT) $(GCC_KOPTS) -fsigned-char -mno-space-regs \
+      -mfast-indirect-calls -mdisable-fpregs -ffunction-sections \
+      -march=1.1 -mschedule=7100
 DEFINES = -D__KERNEL__  -D__linux__ -DKERNEL -D_KERNEL -DMODULE ${SMP_DEF}
 <ia64_linux24>
-CCFLAGS =   $(KDEBUG) -O2 $(FOMIT) -fno-strict-aliasing -fno-common -pipe \
-       -ffixed-r13 -mfixed-range=f10-f15,f32-f127 -falign-functions=32 -mb-step
+CCFLAGS =   $(KDEBUG) -O2 $(FOMIT) $(GCC_KOPTS) -pipe -ffixed-r13 \
+       -mfixed-range=f10-f15,f32-f127 -falign-functions=32 -mb-step
 DEFINES = -D__KERNEL__ -DKERNEL -D_KERNEL ${SMP_DEF} -DMODULE
 <all>
 INCLUDES = -I. -I../ -I${TOP_OBJDIR}/src/config