]> git.hungrycats.org Git - linux/commitdiff
[PATCH] compat ioctl_table fix
authorAndrew Morton <akpm@osdl.org>
Sun, 31 Aug 2003 11:34:45 +0000 (04:34 -0700)
committerLinus Torvalds <torvalds@home.osdl.org>
Sun, 31 Aug 2003 11:34:45 +0000 (04:34 -0700)
The arch ioctl tables are doing this:

struct foo ioctl_start[] = {
...
};
struct foo ioctl_end[0];

and fs/compat.c expects that the table lies between &ioctl_end and
&ioctl_start.

Problem is, gcc-3.3 puts ioctl_end into bss, even if it is initialised.  It
doesn't work.

So we do away with the ioctl_end thing and add

int ioctl_table_length = ARRAY_SIZE(ioctl_start);

to each architecture.

arch/ia64/ia32/ia32_ioctl.c
arch/mips/kernel/ioctl32.c
arch/parisc/kernel/ioctl32.c
arch/ppc64/kernel/ioctl32.c
arch/s390/kernel/compat_ioctl.c
arch/sparc64/kernel/ioctl32.c
arch/x86_64/ia32/ia32_ioctl.c
fs/compat.c

index 25783cdc6b169b068248820a79a77dec058dc566..2772de29bf528e7e8f0dd1ef37c271bb0f863e50 100644 (file)
@@ -70,7 +70,7 @@ typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, str
 #define IOCTL_TABLE_START \
        struct ioctl_trans ioctl_start[] = {
 #define IOCTL_TABLE_END \
-       }; struct ioctl_trans ioctl_end[0];
+       };
 
 IOCTL_TABLE_START
 HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32)
@@ -79,3 +79,5 @@ HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32)
 #include "compat_ioctl.c"
 #include <linux/compat_ioctl.h>
 IOCTL_TABLE_END
+
+int ioctl_table_size = ARRAY_SIZE(ioctl_start);
index 77777859a9054cb4828b662ca3dfb0afaca95f88..12231b7718e51a9446b2c9f69bd6ab3616a04bb7 100644 (file)
@@ -810,8 +810,7 @@ typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, str
 #define IOCTL_TABLE_START \
        struct ioctl_trans ioctl_start[] = {
 #define IOCTL_TABLE_END \
-       }; struct ioctl_trans ioctl_end[0];
-
+       };
 
 IOCTL_TABLE_START
 #include <linux/compat_ioctl.h>
@@ -1206,5 +1205,7 @@ COMPATIBLE_IOCTL(RTC_WKALM_SET)
 COMPATIBLE_IOCTL(RTC_WKALM_RD)
 IOCTL_TABLE_END
 
+int ioctl_table_size = ARRAY_SIZE(ioctl_start);
+
 #define NR_IOCTL_TRANS         (sizeof(ioctl_translations) /   \
                                 sizeof(ioctl_translations[0]))
index d481533c93229abd315999d9fdd27af00b0aa376..3383de28ceff1d8c6987182caaafab92421a6602 100644 (file)
@@ -2458,7 +2458,7 @@ int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
 #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd, sys_ioctl) 
 
 #define IOCTL_TABLE_START  struct ioctl_trans ioctl_start[] = {
-#define IOCTL_TABLE_END    }; struct ioctl_trans ioctl_end[0];
+#define IOCTL_TABLE_END    };
 
 IOCTL_TABLE_START
 #include <linux/compat_ioctl.h>
@@ -2631,3 +2631,4 @@ HANDLE_IOCTL(DRM32_IOCTL_RES_CTX, drm32_res_ctx);
 #endif /* DRM */
 IOCTL_TABLE_END
 
+int ioctl_table_size = ARRAY_SIZE(ioctl_start);
index 7bb3ce19a865b45232a1426745ff6049fe1b9905..d3d4a8cb00fb57d39a8a368bc3bbf9b4299b2fd5 100644 (file)
@@ -725,7 +725,7 @@ static int do_usbdevfs_discsignal(unsigned int fd, unsigned int cmd, unsigned lo
 #define IOCTL_TABLE_START \
        struct ioctl_trans ioctl_start[] = {
 #define IOCTL_TABLE_END \
-       }; struct ioctl_trans ioctl_end[0];
+       };
 
 IOCTL_TABLE_START
 #include <linux/compat_ioctl.h>
@@ -763,3 +763,5 @@ HANDLE_IOCTL(USBDEVFS_REAPURB32, do_usbdevfs_reapurb)
 HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb)
 HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
 IOCTL_TABLE_END
+
+int ioctl_table_size = ARRAY_SIZE(ioctl_start);
index b69c9d98b4aed6e3eb7d7575be1a4caa6120f530..2f58414cc96047cfeb42963cb079fa1ee655bcc1 100644 (file)
@@ -808,7 +808,7 @@ int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd,
 #define IOCTL_TABLE_START \
        struct ioctl_trans ioctl_start[] = {
 #define IOCTL_TABLE_END \
-       }; struct ioctl_trans ioctl_end[0];
+       };
 
 IOCTL_TABLE_START
 #include <linux/compat_ioctl.h>
@@ -899,3 +899,5 @@ HANDLE_IOCTL(BLKSECTGET, w_long)
 HANDLE_IOCTL(BLKPG, blkpg_ioctl_trans)
 
 IOCTL_TABLE_END
+
+int ioctl_table_size = ARRAY_SIZE(ioctl_start);
index 7b0e2cc6c59bac9ee2dd94db50dd3831fb83fa9f..dcbe443edc41d0d6661cb8052fdb7f806dad4c61 100644 (file)
@@ -1388,7 +1388,7 @@ typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, str
 #define IOCTL_TABLE_START \
        struct ioctl_trans ioctl_start[] = {
 #define IOCTL_TABLE_END \
-       }; struct ioctl_trans ioctl_end[0];
+       };
 
 IOCTL_TABLE_START
 #include <linux/compat_ioctl.h>
@@ -1583,3 +1583,5 @@ HANDLE_IOCTL(USBDEVFS_REAPURBNDELAY32, do_usbdevfs_reapurb)
 HANDLE_IOCTL(USBDEVFS_DISCSIGNAL32, do_usbdevfs_discsignal)
 /* take care of sizeof(sizeof()) breakage */
 IOCTL_TABLE_END
+
+int ioctl_table_size = ARRAY_SIZE(ioctl_start);
index 4f60ddb4574d971c384c63e65654447823b1d7bc..7fedc0d64c614b8374d122959a9a71ddbf3f484b 100644 (file)
@@ -673,12 +673,10 @@ static int mtrr_ioctl32(unsigned int fd, unsigned int cmd, unsigned long arg)
        return err;
 } 
 
-#define REF_SYMBOL(handler) if (0) (void)handler;
-#define HANDLE_IOCTL2(cmd,handler) REF_SYMBOL(handler);  asm volatile(".quad %P0, " #handler ",0"::"i" (cmd)); 
-#define HANDLE_IOCTL(cmd,handler) HANDLE_IOCTL2(cmd,handler)
+#define HANDLE_IOCTL(cmd,handler) { (cmd), (ioctl_trans_handler_t)(handler), NULL },
 #define COMPATIBLE_IOCTL(cmd) HANDLE_IOCTL(cmd,sys_ioctl)
-#define IOCTL_TABLE_START void ioctl_dummy(void) { asm volatile("\n.global ioctl_start\nioctl_start:\n\t" );
-#define IOCTL_TABLE_END  asm volatile("\n.global ioctl_end;\nioctl_end:\n"); }
+#define IOCTL_TABLE_START struct ioctl_trans ioctl_start[] = {
+#define IOCTL_TABLE_END  };
 
 IOCTL_TABLE_START
 #include <linux/compat_ioctl.h>
@@ -765,3 +763,4 @@ HANDLE_IOCTL(MTRRIOC32_GET_PAGE_ENTRY, mtrr_ioctl32)
 HANDLE_IOCTL(MTRRIOC32_KILL_PAGE_ENTRY, mtrr_ioctl32)
 IOCTL_TABLE_END
 
+int ioctl_table_size = ARRAY_SIZE(ioctl_start);
index 043428888e27ab74c54d9f2342e009a54f142321..e2eec3eb91ce41d4e3ea2d6d92dac80967d91c9f 100644 (file)
@@ -227,7 +227,8 @@ out:
 #define IOCTL_HASHSIZE 256
 struct ioctl_trans *ioctl32_hash_table[IOCTL_HASHSIZE];
 
-extern struct ioctl_trans ioctl_start[], ioctl_end[]; 
+extern struct ioctl_trans ioctl_start[];
+extern int ioctl_table_size;
 
 static inline unsigned long ioctl32_hash(unsigned long cmd)
 {
@@ -255,7 +256,7 @@ static int __init init_sys32_ioctl(void)
 {
        int i;
 
-       for (i = 0; &ioctl_start[i] < &ioctl_end[0]; i++) {
+       for (i = 0; i < ioctl_table_size; i++) {
                if (ioctl_start[i].next != 0) { 
                        printk("ioctl translation %d bad\n",i); 
                        return -1;
@@ -318,8 +319,7 @@ int register_ioctl32_conversion(unsigned int cmd, int (*handler)(unsigned int, u
 
 static inline int builtin_ioctl(struct ioctl_trans *t)
 { 
-       return t >= (struct ioctl_trans *)ioctl_start &&
-              t < (struct ioctl_trans *)ioctl_end; 
+       return t >= ioctl_start && t < (ioctl_start + ioctl_table_size);
 } 
 
 /* Problem: