diff --git a/drivers/md/md.c b/drivers/md/md.c index b6d1602..51a87ad 100644 --- a/drivers/md/md.c +++ b/drivers/md/md.c @@ -2888,6 +2888,7 @@ static struct kobj_type md_ktype = { }; int mdp_major = 0; +__internal_export(mdp_major); static struct kobject *md_probe(dev_t dev, int *part, void *data) { @@ -5583,7 +5584,7 @@ void md_autodetect_dev(dev_t dev) if (dev_cnt >= 0 && dev_cnt < 127) detected_devices[dev_cnt++] = dev; } - +__internal_export(md_autodetect_dev); static void autostart_arrays(int part) { diff --git a/drivers/video/fbcvt.c b/drivers/video/fbcvt.c index b549899..1aa48a3 100644 --- a/drivers/video/fbcvt.c +++ b/drivers/video/fbcvt.c @@ -376,3 +376,4 @@ int fb_find_mode_cvt(struct fb_videomode return 0; } +__internal_export(fb_find_mode_cvt); diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c index e8ae304..8a15f70 100644 --- a/fs/debugfs/inode.c +++ b/fs/debugfs/inode.c @@ -27,7 +27,7 @@ #include #define DEBUGFS_MAGIC 0x64626720 /* declared over in file.c */ -extern struct file_operations debugfs_file_operations; +extern const struct file_operations debugfs_file_operations; static struct vfsmount *debugfs_mount; static int debugfs_mount_count; diff --git a/fs/devpts/inode.c b/fs/devpts/inode.c index f7aef5b..b06b865 100644 --- a/fs/devpts/inode.c +++ b/fs/devpts/inode.c @@ -187,6 +187,7 @@ int devpts_pty_new(struct tty_struct *tt return 0; } +__internal_export(devpts_pty_new); struct tty_struct *devpts_get_tty(int number) { @@ -204,6 +205,7 @@ struct tty_struct *devpts_get_tty(int nu return tty; } +__internal_export(devpts_get_tty); void devpts_pty_kill(int number) { @@ -220,6 +222,7 @@ void devpts_pty_kill(int number) } mutex_unlock(&devpts_root->d_inode->i_mutex); } +__internal_export(devpts_pty_kill); static int __init init_devpts_fs(void) { diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c index 924ecde..99f3120 100644 --- a/fs/hfsplus/inode.c +++ b/fs/hfsplus/inode.c @@ -269,7 +269,7 @@ static int hfsplus_file_release(struct i } extern struct inode_operations hfsplus_dir_inode_operations; -extern struct file_operations hfsplus_dir_operations; +extern const struct file_operations hfsplus_dir_operations; static struct inode_operations hfsplus_file_inode_operations = { .lookup = hfsplus_file_lookup, diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c index c3920c9..919b357 100644 --- a/fs/hugetlbfs/inode.c +++ b/fs/hugetlbfs/inode.c @@ -45,6 +45,7 @@ static struct backing_dev_info hugetlbfs }; int sysctl_hugetlb_shm_group; +__internal_export(sysctl_hugetlb_shm_group); static void huge_pagevec_release(struct pagevec *pvec) { @@ -567,6 +568,7 @@ const struct file_operations hugetlbfs_f .fsync = simple_sync_file, .get_unmapped_area = hugetlb_get_unmapped_area, }; +__internal_export(hugetlbfs_file_operations); static struct inode_operations hugetlbfs_dir_inode_operations = { .create = hugetlbfs_create, @@ -707,6 +709,7 @@ int hugetlb_get_quota(struct address_spa return ret; } +__internal_export(hugetlb_get_quota); void hugetlb_put_quota(struct address_space *mapping) { @@ -718,6 +721,7 @@ void hugetlb_put_quota(struct address_sp spin_unlock(&sbinfo->stat_lock); } } +__internal_export(hugetlb_put_quota); static int hugetlbfs_get_sb(struct file_system_type *fs_type, int flags, const char *dev_name, void *data, struct vfsmount *mnt) @@ -800,6 +804,7 @@ out_shm_unlock: user_shm_unlock(size, current->user); return ERR_PTR(error); } +__internal_export(hugetlb_zero_setup); static int __init init_hugetlbfs_fs(void) { diff --git a/fs/proc/base.c b/fs/proc/base.c index fe8d55f..f4bab72 100644 --- a/fs/proc/base.c +++ b/fs/proc/base.c @@ -71,6 +71,7 @@ #include #include #include #include +#include #include "internal.h" /* NOTE: @@ -2020,6 +2021,7 @@ out_put_leader: out: return; } +__internal_export(proc_flush_task); /* SMP-safe */ struct dentry *proc_pid_lookup(struct inode *dir, struct dentry * dentry, struct nameidata *nd) diff --git a/fs/proc/generic.c b/fs/proc/generic.c index 4ba0300..e778ff4 100644 --- a/fs/proc/generic.c +++ b/fs/proc/generic.c @@ -20,8 +20,8 @@ #include #include #include #include +#include #include - #include "internal.h" static ssize_t proc_file_read(struct file *file, char __user *buf, @@ -38,6 +38,7 @@ int proc_match(int len, const char *name return 0; return !memcmp(name, de->name, len); } +__internal_export(proc_match); static struct file_operations proc_file_operations = { .llseek = proc_file_lseek, diff --git a/fs/proc/kcore.c b/fs/proc/kcore.c index 6a984f6..b551388 100644 --- a/fs/proc/kcore.c +++ b/fs/proc/kcore.c @@ -19,6 +19,7 @@ #include #include #include #include +#include #include #include @@ -65,6 +66,7 @@ kclist_add(struct kcore_list *new, void kclist = new; write_unlock(&kclist_lock); } +__internal_export(kclist_add); static size_t get_kcore_size(int *nphdr, size_t *elf_buflen) { diff --git a/fs/proc/proc_tty.c b/fs/proc/proc_tty.c index 15c4455..109c374 100644 --- a/fs/proc/proc_tty.c +++ b/fs/proc/proc_tty.c @@ -201,6 +201,7 @@ void proc_tty_register_driver(struct tty driver->proc_entry = ent; } +__internal_export(proc_tty_register_driver); /* * This function is called by tty_unregister_driver() @@ -217,6 +218,7 @@ void proc_tty_unregister_driver(struct t driver->proc_entry = NULL; } +__internal_export(proc_tty_unregister_driver); /* * Called by proc_root_init() to initialize the /proc/tty subtree diff --git a/fs/proc/root.c b/fs/proc/root.c index 8901c65..032c05e 100644 --- a/fs/proc/root.c +++ b/fs/proc/root.c @@ -19,7 +19,9 @@ #include #include "internal.h" -struct proc_dir_entry *proc_net, *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver; +struct proc_dir_entry *proc_net; + +struct proc_dir_entry *proc_net_stat, *proc_bus, *proc_root_fs, *proc_root_driver; #ifdef CONFIG_SYSCTL struct proc_dir_entry *proc_sys_root; @@ -78,6 +80,7 @@ #ifdef CONFIG_PROC_DEVICETREE #endif proc_bus = proc_mkdir("bus", NULL); } +__internal_export(proc_root_init); static int proc_root_getattr(struct vfsmount *mnt, struct dentry *dentry, struct kstat *stat ) @@ -150,6 +153,7 @@ struct proc_dir_entry proc_root = { .parent = &proc_root, }; +__internal_export(proc_sys_root); EXPORT_SYMBOL(proc_symlink); EXPORT_SYMBOL(proc_mkdir); EXPORT_SYMBOL(create_proc_entry); diff --git a/fs/ramfs/inode.c b/fs/ramfs/inode.c index b967733..592cb87 100644 --- a/fs/ramfs/inode.c +++ b/fs/ramfs/inode.c @@ -226,5 +226,6 @@ int __init init_rootfs(void) { return register_filesystem(&rootfs_fs_type); } +__internal_export(init_rootfs); MODULE_LICENSE("GPL"); diff --git a/fs/reiserfs/dir.c b/fs/reiserfs/dir.c index 9aabcc0..68ab9c0 100644 --- a/fs/reiserfs/dir.c +++ b/fs/reiserfs/dir.c @@ -11,7 +11,7 @@ #include #include #include -extern struct reiserfs_key MIN_KEY; +extern const struct reiserfs_key MIN_KEY; static int reiserfs_readdir(struct file *, void *, filldir_t); static int reiserfs_dir_fsync(struct file *filp, struct dentry *dentry, diff --git a/include/linux/module.h b/include/linux/module.h index 0dfb794..d677785 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -21,6 +21,15 @@ #include #include + +#ifdef CONFIG_COMBINED_COMPILE +#define __externally_visible__ __attribute__((externally_visible,used)) +#define __internal_export(sym) extern typeof(sym) sym __externally_visible__ +#else +#define __externally_visible__ +#define __internal_export(sym) +#endif + /* Not Yet Implemented */ #define MODULE_SUPPORTED_DEVICE(name) @@ -184,7 +193,7 @@ #endif /* For every exported symbol, place a struct in the __ksymtab section */ #define __EXPORT_SYMBOL(sym, sec) \ - extern typeof(sym) sym; \ + extern typeof(sym) sym __externally_visible__; \ __CRC_SYMBOL(sym, sec) \ static const char __kstrtab_##sym[] \ __attribute__((section("__ksymtab_strings"))) \ @@ -208,8 +217,8 @@ #ifdef CONFIG_UNUSED_SYMBOLS #define EXPORT_UNUSED_SYMBOL(sym) __EXPORT_SYMBOL(sym, "_unused") #define EXPORT_UNUSED_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_unused_gpl") #else -#define EXPORT_UNUSED_SYMBOL(sym) -#define EXPORT_UNUSED_SYMBOL_GPL(sym) +#define EXPORT_UNUSED_SYMBOL(sym) __internal_export(sym) +#define EXPORT_UNUSED_SYMBOL_GPL(sym) __internal_export(sym) #endif #endif @@ -470,11 +479,12 @@ void module_add_driver(struct module *, void module_remove_driver(struct device_driver *); #else /* !CONFIG_MODULES... */ -#define EXPORT_SYMBOL(sym) -#define EXPORT_SYMBOL_GPL(sym) -#define EXPORT_SYMBOL_GPL_FUTURE(sym) -#define EXPORT_UNUSED_SYMBOL(sym) -#define EXPORT_UNUSED_SYMBOL_GPL(sym) + +#define EXPORT_SYMBOL(sym) __internal_export(sym) +#define EXPORT_SYMBOL_GPL(sym) __internal_export(sym) +#define EXPORT_SYMBOL_GPL_FUTURE(sym) __internal_export(sym) +#define EXPORT_UNUSED_SYMBOL(sym) __internal_export(sym) +#define EXPORT_UNUSED_SYMBOL_GPL(sym) __internal_export(sym) /* Given an address, look for it in the exception tables. */ static inline const struct exception_table_entry * diff --git a/init/Kconfig b/init/Kconfig index a099fc6..54d3e71 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -468,6 +468,11 @@ config MODULE_FORCE_UNLOAD rmmod). This is mainly for kernel developers and desperate users. If unsure, say N. +config COMBINED_COMPILE + bool "Use combined compilation (gcc --combine)" + help + fish + config MODVERSIONS bool "Module versioning support" depends on MODULES diff --git a/init/do_mounts.c b/init/do_mounts.c index 94aeec7..dd29d04 100644 --- a/init/do_mounts.c +++ b/init/do_mounts.c @@ -25,6 +25,10 @@ static char __initdata saved_root_name[6 dev_t ROOT_DEV; +__internal_export(root_mountflags); +__internal_export(rd_doload); +__internal_export(ROOT_DEV); + static int __init load_ramdisk(char *str) { rd_doload = simple_strtol(str,NULL,0) & 3; @@ -204,6 +208,7 @@ fail: res = 0; goto done; } +__internal_export(name_to_dev_t); static int __init root_dev_setup(char *line) { @@ -430,4 +435,4 @@ out: sys_chroot("."); security_sb_post_mountroot(); } - +__internal_export(prepare_namespace); diff --git a/init/do_mounts_initrd.c b/init/do_mounts_initrd.c index a06f037..8f35aaa 100644 --- a/init/do_mounts_initrd.c +++ b/init/do_mounts_initrd.c @@ -7,6 +7,7 @@ #include #include #include #include +#include #include "do_mounts.h" @@ -16,6 +17,11 @@ unsigned int real_root_dev; /* do_proc_d static int __initdata old_fd, root_fd; static int __initdata mount_initrd = 1; +__internal_export(initrd_start); +__internal_export(initrd_end); +__internal_export(initrd_below_start_ok); +__internal_export(real_root_dev); + static int __init no_initrd(char *str) { mount_initrd = 0; diff --git a/init/do_mounts_rd.c b/init/do_mounts_rd.c index ed652f4..d43cded 100644 --- a/init/do_mounts_rd.c +++ b/init/do_mounts_rd.c @@ -7,12 +7,14 @@ #include #include #include #include +#include #include "do_mounts.h" #define BUILD_CRAMDISK int __initdata rd_prompt = 1;/* 1 = prompt for RAM disk, 0 = don't prompt */ +__internal_export(rd_prompt); static int __init prompt_ramdisk(char *str) { @@ -22,6 +24,7 @@ static int __init prompt_ramdisk(char *s __setup("prompt_ramdisk=", prompt_ramdisk); int __initdata rd_image_start; /* starting block # of image */ +__internal_export(rd_image_start); static int __init ramdisk_start_setup(char *str) { diff --git a/net/netfilter/core.c b/net/netfilter/core.c index 5d29d5e..ce6fde9 100644 --- a/net/netfilter/core.c +++ b/net/netfilter/core.c @@ -264,3 +264,5 @@ #endif if (netfilter_log_init() < 0) panic("cannot initialize nf_log"); } +__internal_export(netfilter_init); + diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 3cb445c..8a8e844 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -128,6 +128,11 @@ modname = $(basetarget) $(multi-objs-y:.o=.s) : modname = $(modname-multi) $(multi-objs-y:.o=.lst) : modname = $(modname-multi) +ifdef CONFIG_COMBINED_COMPILE +$(multi-used-m) : CFLAGS += -fwhole-program --combine $(sort $(addprefix $(srctree)/$(obj)/,$($(subst $(obj)/,,$(@:.o=-y)):.o=.c) $($(subst $(obj)/,,$(@:.o=-objs)):.o=.c))) +$(multi-used-y) : CFLAGS += -fwhole-program --combine $(sort $(addprefix $(srctree)/$(obj)/,$($(subst $(obj)/,,$(@:.o=-y)):.o=.c) $($(subst $(obj)/,,$(@:.o=-objs)):.o=.c))) +endif + quiet_cmd_cc_s_c = CC $(quiet_modtag) $@ cmd_cc_s_c = $(CC) $(c_flags) -fverbose-asm -S -o $@ $< @@ -283,6 +288,22 @@ cmd_link_l_target = rm -f $@; $(AR) $(EX targets += $(lib-target) endif +ifdef CONFIG_COMBINED_COMPILE +# We would rather have a list of rules like +# foo.o: $(foo-objs) +# but that's not so easy, so we rather make all composite objects depend +# on the set of all their parts + +$(multi-used-y) : %.o: $(srctree)/dummy.c $(multi-objs-y:.o=.c) FORCE + $(call cmd,force_checksrc) + $(call if_changed_rule,cc_o_c) + +$(multi-used-m) : %.o: $(srctree)/dummy.c $(multi-objs-m:.o=.c) FORCE + $(call cmd,force_checksrc) + $(call if_changed_rule,cc_o_c) + +targets += $(multi-used-y) $(multi-used-m) +else # # Rule to link composite objects # @@ -313,7 +334,7 @@ # on the set of all their parts @{ echo $(@:.o=.ko); echo $(link_multi_deps); } > $(MODVERDIR)/$(@F:.o=.mod) targets += $(multi-used-y) $(multi-used-m) - +endif # Descending # ---------------------------------------------------------------------------