From aae7d999e258ba7b26027251d99db728ea1622cf Mon Sep 17 00:00:00 2001 From: Kai Germaschewski Date: Thu, 16 Jan 2003 22:26:43 -0600 Subject: kbuild: Fix __start_SECTION, __stop_SECTION In a discussion with Sam Ravnborg, the following problem became apparent: Most vmlinux.lds.S (but the ARM ones) used the following construct: __start___ksymtab = .; __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { *(__ksymtab) } __stop___ksymtab = .; However, the link will align the beginning of the section __ksymtab according to the requirements for the input sections. If '.' (current location counter) wasn't sufficiently aligned before, it's possible that __ksymtab actually starts at an address after the one __start___ksymtab points to, which will confuse the users of __start___ksymtab badly. The fix is to follow what the ARM Makefiles did for this case, ie __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { __start___ksymtab = .; *(__ksymtab) __stop___ksymtab = .; } --- include/asm-generic/vmlinux.lds.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 3d97aae1c3e6..7563b5730aaa 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -13,18 +13,18 @@ } \ \ /* Kernel symbol table: Normal symbols */ \ - __start___ksymtab = .; \ __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ + __start___ksymtab = .; \ *(__ksymtab) \ + __stop___ksymtab = .; \ } \ - __stop___ksymtab = .; \ \ /* Kernel symbol table: GPL-only symbols */ \ - __start___gpl_ksymtab = .; \ __gpl_ksymtab : AT(ADDR(__gpl_ksymtab) - LOAD_OFFSET) { \ + __start___gpl_ksymtab = .; \ *(__gpl_ksymtab) \ + __stop___gpl_ksymtab = .; \ } \ - __stop___gpl_ksymtab = .; \ \ /* Kernel symbol table: strings */ \ __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ -- cgit v1.2.3 From a6b9977667ca069f18ad85fab1c2445a0f2f4e78 Mon Sep 17 00:00:00 2001 From: Kai Germaschewski Date: Fri, 24 Jan 2003 02:27:06 -0600 Subject: kbuild: Add CONFIG_MODVERSIONING and __kcrctab This patch adds the new config option CONFIG_MODVERSIONING which will be the new way of checking for ABI changes between kernel and module code. This and the following patches are in part based on an initial implementation by Rusty Russell and I believe some of the ideas go back to discussions on linux-kbuild, Keith Owens and Rusty. though I'm not sure I think credit for the basic idea of storing version info in sections goes to Keith Owens and Rusty. o Rename __gpl_ksymtab to __ksymtab_gpl since that looks more consistent and appending _gpl instead of putting it into the middle simplifies sharing code for EXPORT_SYMBOL() and EXPORT_SYMBOL_GPL() o Add CONFIG_MODVERSIONING o If CONFIG_MODVERSIONING is set, add a section __kcrctab{,_gpl}, which contains the ABI checksums for the exported symbols listed in __ksymtab{,_crc} Since we don't know the checksums yet at compilation time, just make them an unresolved symbol which gets filled in by the linker later. --- include/asm-generic/vmlinux.lds.h | 22 ++++++++++++++++++---- include/linux/module.h | 31 +++++++++++++++++++++---------- init/Kconfig | 13 +++++++++++++ kernel/module.c | 21 +++++++++++---------- scripts/per-cpu-check.awk | 2 +- 5 files changed, 64 insertions(+), 25 deletions(-) (limited to 'include') diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 7563b5730aaa..0f09f5b73a69 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -20,10 +20,24 @@ } \ \ /* Kernel symbol table: GPL-only symbols */ \ - __gpl_ksymtab : AT(ADDR(__gpl_ksymtab) - LOAD_OFFSET) { \ - __start___gpl_ksymtab = .; \ - *(__gpl_ksymtab) \ - __stop___gpl_ksymtab = .; \ + __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \ + __start___ksymtab_gpl = .; \ + *(__ksymtab_gpl) \ + __stop___ksymtab_gpl = .; \ + } \ + \ + /* Kernel symbol table: Normal symbols */ \ + __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \ + __start___kcrctab = .; \ + *(__kcrctab) \ + __stop___kcrctab = .; \ + } \ + \ + /* Kernel symbol table: GPL-only symbols */ \ + __kcrctab_gpl : AT(ADDR(__kcrctab_gpl) - LOAD_OFFSET) { \ + __start___kcrctab_gpl = .; \ + *(__kcrctab_gpl) \ + __stop___kcrctab_gpl = .; \ } \ \ /* Kernel symbol table: strings */ \ diff --git a/include/linux/module.h b/include/linux/module.h index 6dad1479105f..d017a67210c6 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -134,29 +134,40 @@ struct exception_table #ifdef CONFIG_MODULES + /* Get/put a kernel symbol (calls must be symmetric) */ void *__symbol_get(const char *symbol); void *__symbol_get_gpl(const char *symbol); #define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x))) +#ifdef CONFIG_MODVERSIONING +/* Mark the CRC weak since genksyms apparently decides not to + * generate a checksums for some symbols */ +#define __CRC_SYMBOL(sym, sec) \ + extern void *__crc_##sym __attribute__((weak)); \ + static const unsigned long __kcrctab_##sym \ + __attribute__((section("__kcrctab" sec))) \ + = (unsigned long) &__crc_##sym; +#else +#define __CRC_SYMBOL(sym, sec) +#endif + /* For every exported symbol, place a struct in the __ksymtab section */ -#define EXPORT_SYMBOL(sym) \ +#define __EXPORT_SYMBOL(sym, sec) \ + __CRC_SYMBOL(sym, sec) \ static const char __kstrtab_##sym[] \ __attribute__((section("__ksymtab_strings"))) \ = MODULE_SYMBOL_PREFIX #sym; \ static const struct kernel_symbol __ksymtab_##sym \ - __attribute__((section("__ksymtab"))) \ + __attribute__((section("__ksymtab" sec))) \ = { (unsigned long)&sym, __kstrtab_##sym } -#define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym) +#define EXPORT_SYMBOL(sym) __EXPORT_SYMBOL(sym, "") +#define EXPORT_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_gpl") -#define EXPORT_SYMBOL_GPL(sym) \ - static const char __kstrtab_##sym[] \ - __attribute__((section("__ksymtab_strings"))) \ - = MODULE_SYMBOL_PREFIX #sym; \ - static const struct kernel_symbol __ksymtab_##sym \ - __attribute__((section("__gpl_ksymtab"))) \ - = { (unsigned long)&sym, __kstrtab_##sym } +/* We don't mangle the actual symbol anymore, so no need for + * special casing EXPORT_SYMBOL_NOVERS */ +#define EXPORT_SYMBOL_NOVERS(sym) EXPORT_SYMBOL(sym) struct module_ref { diff --git a/init/Kconfig b/init/Kconfig index fcdd9fdb7896..5541908be8c0 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -144,6 +144,19 @@ config OBSOLETE_MODPARM have not been converted to the new module parameter system yet. If unsure, say Y. +config MODVERSIONING + bool "Module versioning support (EXPERIMENTAL)" + depends on MODULES && EXPERIMENTAL + help + ---help--- + Usually, you have to use modules compiled with your kernel. + Saying Y here makes it sometimes possible to use modules + compiled for different kernels, by adding enough information + to the modules to (hopefully) spot any changes which would + make them incompatible with the kernel you are running. If + you say Y here, you will need a copy of genksyms. If + unsure, say N. + config KMOD bool "Kernel module loader" depends on MODULES diff --git a/kernel/module.c b/kernel/module.c index 864828099b36..b798fd62ad2f 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -1040,6 +1040,11 @@ static struct module *load_module(void *umod, /* Exported symbols. */ DEBUGP("EXPORT table in section %u\n", i); exportindex = i; + } else if (strcmp(secstrings+sechdrs[i].sh_name, + "__ksymtab_gpl") == 0) { + /* Exported symbols. (GPL) */ + DEBUGP("GPL symbols found in section %u\n", i); + gplindex = i; } else if (strcmp(secstrings+sechdrs[i].sh_name, "__param") == 0) { /* Setup parameter info */ @@ -1060,11 +1065,6 @@ static struct module *load_module(void *umod, /* MODULE_LICENSE() */ DEBUGP("Licence found in section %u\n", i); licenseindex = i; - } else if (strcmp(secstrings+sechdrs[i].sh_name, - "__gpl_ksymtab") == 0) { - /* EXPORT_SYMBOL_GPL() */ - DEBUGP("GPL symbols found in section %u\n", i); - gplindex = i; } else if (strcmp(secstrings+sechdrs[i].sh_name, "__vermagic") == 0) { /* Version magic. */ @@ -1492,8 +1492,8 @@ int module_text_address(unsigned long addr) /* Provided by the linker */ extern const struct kernel_symbol __start___ksymtab[]; extern const struct kernel_symbol __stop___ksymtab[]; -extern const struct kernel_symbol __start___gpl_ksymtab[]; -extern const struct kernel_symbol __stop___gpl_ksymtab[]; +extern const struct kernel_symbol __start___ksymtab_gpl[]; +extern const struct kernel_symbol __stop___ksymtab_gpl[]; static struct kernel_symbol_group kernel_symbols, kernel_gpl_symbols; @@ -1504,9 +1504,10 @@ static int __init symbols_init(void) kernel_symbols.syms = __start___ksymtab; kernel_symbols.gplonly = 0; list_add(&kernel_symbols.list, &symbols); - kernel_gpl_symbols.num_syms = (__stop___gpl_ksymtab - - __start___gpl_ksymtab); - kernel_gpl_symbols.syms = __start___gpl_ksymtab; + + kernel_gpl_symbols.num_syms = (__stop___ksymtab_gpl + - __start___ksymtab_gpl); + kernel_gpl_symbols.syms = __start___ksymtab_gpl; kernel_gpl_symbols.gplonly = 1; list_add(&kernel_gpl_symbols.list, &symbols); diff --git a/scripts/per-cpu-check.awk b/scripts/per-cpu-check.awk index f1b34c42df4b..3be9f0d25ebd 100644 --- a/scripts/per-cpu-check.awk +++ b/scripts/per-cpu-check.awk @@ -6,7 +6,7 @@ IN_PER_CPU=0 } -/__per_cpu$$/ && ! ( / __ksymtab_/ || / __kstrtab_/ ) { +/__per_cpu$$/ && ! ( / __ksymtab_/ || / __kstrtab_/ || / __kcrctab_/ ) { if (!IN_PER_CPU) { print $$3 " not in per-cpu section" > "/dev/stderr"; FOUND=1; -- cgit v1.2.3 From 09369f635011eb6d520925f375f364f4273163e1 Mon Sep 17 00:00:00 2001 From: Kai Germaschewski Date: Fri, 24 Jan 2003 09:45:27 -0600 Subject: kbuild: Generate versions for exported symbols Up to now, we had a way to store the checksums associated with the exported symbols, but they were not filled in yet. This is done with this patch, using the linker to actually do that for us. The comment added with this patch explains what magic exactly is going on. --- include/linux/module.h | 16 +++++++++++++-- scripts/Makefile.build | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/include/linux/module.h b/include/linux/module.h index d017a67210c6..7475c1791529 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -140,6 +140,13 @@ void *__symbol_get(const char *symbol); void *__symbol_get_gpl(const char *symbol); #define symbol_get(x) ((typeof(&x))(__symbol_get(MODULE_SYMBOL_PREFIX #x))) +#ifdef __GENKSYMS__ + +/* genksyms doesn't handle GPL-only symbols yet */ +#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL + +#else + #ifdef CONFIG_MODVERSIONING /* Mark the CRC weak since genksyms apparently decides not to * generate a checksums for some symbols */ @@ -162,8 +169,13 @@ void *__symbol_get_gpl(const char *symbol); __attribute__((section("__ksymtab" sec))) \ = { (unsigned long)&sym, __kstrtab_##sym } -#define EXPORT_SYMBOL(sym) __EXPORT_SYMBOL(sym, "") -#define EXPORT_SYMBOL_GPL(sym) __EXPORT_SYMBOL(sym, "_gpl") +#define EXPORT_SYMBOL(sym) \ + __EXPORT_SYMBOL(sym, "") + +#define EXPORT_SYMBOL_GPL(sym) \ + __EXPORT_SYMBOL(sym, "_gpl") + +#endif /* We don't mangle the actual symbol anymore, so no need for * special casing EXPORT_SYMBOL_NOVERS */ diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 1fe8acad16fe..522c40663372 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -50,6 +50,55 @@ __build: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \ $(subdir-ym) $(build-targets) @: +# Module versioning +# --------------------------------------------------------------------------- + +ifdef CONFIG_MODVERSIONING + +# $(call if_changed_rule,vcc_o_c) does essentially the same as the +# normal $(call if_changed_dep,cc_o_c), i.e. compile an object file +# from a C file, keeping track of the command line and dependencies. +# +# However, actually it does: +# o compile a .tmp_.o from .c +# o if .tmp_.o doesn't contain a __ksymtab version, i.e. does +# not export symbols, we just rename .tmp_.o to .o and +# are done. +# o otherwise, we calculate symbol versions using the good old +# genksyms on the preprocessed source and postprocess them in a way +# that they are usable as a linker script +# o generate .o from .tmp_.o using the linker to +# replace the unresolved symbols __crc_exported_symbol with +# the actual value of the checksum generated by genksyms + +quiet_cmd_vcc_o_c = CC $(quiet_modtag) $@ +cmd_vcc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $< + +define rule_vcc_o_c + $(if $($(quiet)cmd_vcc_o_c),echo ' $($(quiet)cmd_vcc_o_c)';) \ + $(cmd_vcc_o_c); \ + \ + if ! $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \ + mv $(@D)/.tmp_$(@F) $@; \ + else \ + $(CPP) -D__GENKSYMS__ $(c_flags) $< \ + | $(GENKSYMS) -k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) \ + | grep __ver \ + | sed 's/\#define __ver_\([^ ]*\)[ ]*\([^ ]*\)/__crc_\1 = 0x\2 ;/g' \ + > $(@D)/.tmp_$(@F:.o=.ver); \ + \ + $(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \ + -T $(@D)/.tmp_$(@F:.o=.ver); \ + rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \ + fi; + \ + scripts/fixdep $(depfile) $@ '$(cmd_vcc_o_c)' > $(@D)/.$(@F).tmp; \ + rm -f $(depfile); \ + mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd +endef + +endif + # Compile C sources (.c) # --------------------------------------------------------------------------- @@ -97,7 +146,11 @@ quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< %.o: %.c FORCE +ifdef CONFIG_MODVERSIONING + $(call if_changed_rule,vcc_o_c) +else $(call if_changed_dep,cc_o_c) +endif quiet_cmd_cc_lst_c = MKLST $@ cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \ -- cgit v1.2.3 From 1336f151165fd8a2da10a5d8e1a633e3b72e3fd7 Mon Sep 17 00:00:00 2001 From: Kai Germaschewski Date: Fri, 24 Jan 2003 09:49:33 -0600 Subject: kbuild/modules: Track versions of exported symbols Store the information on the checksum alongside the rest of the information on exported symbols. To actually use them, we need something to check them against first, though ;) Also, fix some conditional debug code to actually compile. --- include/linux/module.h | 1 + kernel/module.c | 28 ++++++++++++++++++++++++---- 2 files changed, 25 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/linux/module.h b/include/linux/module.h index 7475c1791529..af4272910b27 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -119,6 +119,7 @@ struct kernel_symbol_group unsigned int num_syms; const struct kernel_symbol *syms; + const unsigned long *crcs; }; /* Given an address, look for it in the exception tables */ diff --git a/kernel/module.c b/kernel/module.c index f54e6ada3d26..c9dc1996d136 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -916,7 +916,7 @@ static void layout_sections(struct module *mod, || strstr(secstrings + s->sh_name, ".init")) continue; s->sh_entsize = get_offset(&mod->core_size, s); - DEBUGP("\t%s\n", name); + DEBUGP("\t%s\n", secstrings + s->sh_name); } } @@ -932,7 +932,7 @@ static void layout_sections(struct module *mod, continue; s->sh_entsize = (get_offset(&mod->init_size, s) | INIT_OFFSET_MASK); - DEBUGP("\t%s\n", name); + DEBUGP("\t%s\n", secstrings + s->sh_name); } } } @@ -976,7 +976,8 @@ static struct module *load_module(void *umod, Elf_Shdr *sechdrs; char *secstrings, *args; unsigned int i, symindex, exportindex, strindex, setupindex, exindex, - modindex, obsparmindex, licenseindex, gplindex, vmagindex; + modindex, obsparmindex, licenseindex, gplindex, vmagindex, + crcindex, gplcrcindex; long arglen; struct module *mod; long err = 0; @@ -1012,7 +1013,8 @@ static struct module *load_module(void *umod, /* May not export symbols, or have setup params, so these may not exist */ - exportindex = setupindex = obsparmindex = gplindex = licenseindex = 0; + exportindex = setupindex = obsparmindex = gplindex = licenseindex + = crcindex = gplcrcindex = 0; /* And these should exist, but gcc whinges if we don't init them */ symindex = strindex = exindex = modindex = vmagindex = 0; @@ -1045,6 +1047,16 @@ static struct module *load_module(void *umod, /* Exported symbols. (GPL) */ DEBUGP("GPL symbols found in section %u\n", i); gplindex = i; + } else if (strcmp(secstrings+sechdrs[i].sh_name, "__kcrctab") + == 0) { + /* Exported symbols CRCs. */ + DEBUGP("CRC table in section %u\n", i); + crcindex = i; + } else if (strcmp(secstrings+sechdrs[i].sh_name, "__kcrctab_gpl") + == 0) { + /* Exported symbols CRCs. (GPL)*/ + DEBUGP("CRC table in section %u\n", i); + gplcrcindex = i; } else if (strcmp(secstrings+sechdrs[i].sh_name, "__param") == 0) { /* Setup parameter info */ @@ -1192,9 +1204,11 @@ static struct module *load_module(void *umod, mod->symbols.num_syms = (sechdrs[exportindex].sh_size / sizeof(*mod->symbols.syms)); mod->symbols.syms = (void *)sechdrs[exportindex].sh_addr; + mod->symbols.crcs = (void *)sechdrs[crcindex].sh_addr; mod->gpl_symbols.num_syms = (sechdrs[gplindex].sh_size / sizeof(*mod->symbols.syms)); mod->gpl_symbols.syms = (void *)sechdrs[gplindex].sh_addr; + mod->gpl_symbols.crcs = (void *)sechdrs[gplcrcindex].sh_addr; /* Set up exception table */ if (exindex) { @@ -1497,6 +1511,10 @@ extern const struct kernel_symbol __start___ksymtab[]; extern const struct kernel_symbol __stop___ksymtab[]; extern const struct kernel_symbol __start___ksymtab_gpl[]; extern const struct kernel_symbol __stop___ksymtab_gpl[]; +extern const unsigned long __start___kcrctab[]; +extern const unsigned long __stop___kcrctab[]; +extern const unsigned long __start___kcrctab_gpl[]; +extern const unsigned long __stop___kcrctab_gpl[]; static struct kernel_symbol_group kernel_symbols, kernel_gpl_symbols; @@ -1505,12 +1523,14 @@ static int __init symbols_init(void) /* Add kernel symbols to symbol table */ kernel_symbols.num_syms = (__stop___ksymtab - __start___ksymtab); kernel_symbols.syms = __start___ksymtab; + kernel_symbols.crcs = __start___kcrctab; kernel_symbols.gplonly = 0; list_add(&kernel_symbols.list, &symbols); kernel_gpl_symbols.num_syms = (__stop___ksymtab_gpl - __start___ksymtab_gpl); kernel_gpl_symbols.syms = __start___ksymtab_gpl; + kernel_gpl_symbols.crcs = __start___kcrctab_gpl; kernel_gpl_symbols.gplonly = 1; list_add(&kernel_gpl_symbols.list, &symbols); -- cgit v1.2.3 From dcc38eae49e06d798497373771ae03f5508a2ec7 Mon Sep 17 00:00:00 2001 From: Kai Germaschewski Date: Fri, 24 Jan 2003 09:54:04 -0600 Subject: kbuild/modules: Record versions for unresolved symbols In the case of CONFIG_MODVERSIONING, the build step will only generate preliminary .o objects, and an additional postprocessing step is necessary to record the versions of the unresolved symbols and add them into the final .ko The version information for unresolved symbols is again recorded into a special section, "__versions", which contains an array of symbol name strings and checksum (struct modversion_info). Size is here not an issue, since this section will not be stored permanently in kernel memory. Makefile.modver takes care of the following steps: o Collect the version information for all exported symbols from vmlinux and all modules which export symbols. o For each module, generate a C file which contains the modversion information for all unresolved symbols in that module. o For each module, compile that C file to an object file o Finally, link the .ko using the preliminary + the version information above. The first two steps are currently done by not very efficient scripting, so there's room for performance improvement using some helper C code. --- Makefile | 15 +++++++-- include/linux/module.h | 7 ++++ scripts/Makefile.modver | 89 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 108 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/Makefile b/Makefile index 308673b8b2e5..3387d56da0b0 100644 --- a/Makefile +++ b/Makefile @@ -262,7 +262,7 @@ endif # When we're building modules with modversions, we need to consider # the built-in objects during the descend as well, in order to -# make sure the checksums are uptodate before we use them. +# make sure the checksums are uptodate before we record them. ifdef CONFIG_MODVERSIONING ifeq ($(KBUILD_MODULES),1) @@ -508,8 +508,16 @@ ifdef CONFIG_MODULES # Build modules -.PHONY: modules -modules: $(SUBDIRS) +.PHONY: modules __modversions +modules: $(SUBDIRS) __modversions + +ifdef CONFIG_MODVERSIONING + +__modversions: vmlinux $(SUBDIRS) + @echo ' Recording module symbol versions.'; + $(Q)$(MAKE) -rR -f scripts/Makefile.modver + +endif # Install modules @@ -690,6 +698,7 @@ MRPROPER_FILES += \ # Directories removed with 'make mrproper' MRPROPER_DIRS += \ + $(MODVERDIR) \ .tmp_export-objs \ include/config \ include/linux/modules diff --git a/include/linux/module.h b/include/linux/module.h index af4272910b27..e8726d9909d7 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -33,12 +33,19 @@ #endif #define MODULE_NAME_LEN (64 - sizeof(unsigned long)) + struct kernel_symbol { unsigned long value; const char *name; }; +struct modversion_info +{ + unsigned long crc; + char name[MODULE_NAME_LEN]; +}; + /* These are either module local, or the kernel's dummy ones. */ extern int init_module(void); extern void cleanup_module(void); diff --git a/scripts/Makefile.modver b/scripts/Makefile.modver index 5405cbce2170..372d6aff5a32 100644 --- a/scripts/Makefile.modver +++ b/scripts/Makefile.modver @@ -2,3 +2,92 @@ # Module versions # =========================================================================== +.PHONY: __modversions +__modversions: + +include scripts/Makefile.lib + +# + +modules := $(patsubst ./%,%,$(shell cd $(MODVERDIR); find . -name \*.ko)) + +__modversions: $(modules) + @: + +quiet_cmd_ld_ko_o = LD [M] $@ + cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \ + $(filter-out FORCE,$^) + +init/vermagic.o: ; + +$(modules): %.ko :%.o $(MODVERDIR)/%.o init/vermagic.o FORCE + $(call if_changed,ld_ko_o) + +targets += $(modules) + + +quiet_cmd_cc_o_c = CC $@ + cmd_cc_o_c = $(CC) $(CFLAGS) -c -o $@ $< + +$(addprefix $(MODVERDIR)/,$(modules:.ko=.o)): %.o: %.c FORCE + $(call if_changed,cc_o_c) + +targets += $(addprefix $(MODVERDIR)/,$(modules:.ko=.o)) + +define rule_mkver_o_c + echo ' MKVER $@'; \ + ( echo "#include "; \ + echo ""; \ + echo "static const struct modversion_info ____versions[]"; \ + echo "__attribute__((section(\"__versions\"))) = {"; \ + for sym in `nm -u $<`; do \ + grep "\"$$sym\"" .tmp_all-versions \ + || echo "*** Warning: $(<:.o=.ko): \"$$sym\" unresolved!" >&2;\ + done; \ + echo "};"; \ + ) > $@ +endef + +$(addprefix $(MODVERDIR)/,$(modules:.ko=.c)): \ +$(MODVERDIR)/%.c: %.o .tmp_all-versions FORCE + $(call if_changed_rule,mkver_o_c) + +targets += $(addprefix $(MODVERDIR)/,$(modules:.ko=.o.c)) + +export-objs := $(shell for m in vmlinux $(modules:.ko=.o); do objdump -h $$m | grep -q __ksymtab && echo $$m; done) + +cmd_gen-all-versions = mksyms $(export-objs) +define rule_gen-all-versions + echo ' MKSYMS $@'; \ + for mod in $(export-objs); do \ + modname=`basename $$mod`; \ + nm $$mod \ + | grep ' __crc_' \ + | sed "s/\([^ ]*\) A __crc_\(.*\)/{ 0x\1, \"\2\" }, \/* $$modname *\//g;s/.* w __crc_\(.*\)/{ 0x0 , \"\1\" }, \/* $$modname *\//g"; \ + done > $@; \ + echo 'cmd_$@ := $(cmd_$(1))' > $(@D)/.$(@F).cmd +endef + +.tmp_all-versions: $(export-objs) FORCE + $(call if_changed_rule,gen-all-versions) + +targets += .tmp_all-versions + +# Add FORCE to the prequisites of a target to force it to be always rebuilt. +# --------------------------------------------------------------------------- + +.PHONY: FORCE + +FORCE: + +# Read all saved command lines and dependencies for the $(targets) we +# may be building above, using $(if_changed{,_dep}). As an +# optimization, we don't need to read them if the target does not +# exist, we will rebuild anyway in that case. + +targets := $(wildcard $(sort $(targets))) +cmd_files := $(wildcard $(foreach f,$(targets),$(dir $(f)).$(notdir $(f)).cmd)) + +ifneq ($(cmd_files),) + include $(cmd_files) +endif -- cgit v1.2.3 From e9aff3178f09e5281ddc4bb1220a9acc64888421 Mon Sep 17 00:00:00 2001 From: Kai Germaschewski Date: Sat, 25 Jan 2003 08:20:44 -0600 Subject: kbuild: gcc-3.3 warns about 2.5.59 EXPORT_SYMBOL When building linux-2.5.59 with gcc-3.3 (on s390, if that matters), I get a warning like "warning: `__ksymtab___foo' defined but not used" each time that EXPORT_SYMBOL is used. by Arnd Bergmann --- include/linux/module.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'include') diff --git a/include/linux/module.h b/include/linux/module.h index e8726d9909d7..1be44624ec3a 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -99,7 +99,7 @@ extern const struct gtype##_id __mod_##gtype##_table \ */ #define MODULE_LICENSE(license) \ static const char __module_license[] \ - __attribute__((section(".init.license"))) = license + __attribute__((section(".init.license"), unused)) = license #else /* !MODULE */ @@ -161,7 +161,7 @@ void *__symbol_get_gpl(const char *symbol); #define __CRC_SYMBOL(sym, sec) \ extern void *__crc_##sym __attribute__((weak)); \ static const unsigned long __kcrctab_##sym \ - __attribute__((section("__kcrctab" sec))) \ + __attribute__((section("__kcrctab" sec), unused)) \ = (unsigned long) &__crc_##sym; #else #define __CRC_SYMBOL(sym, sec) @@ -174,7 +174,7 @@ void *__symbol_get_gpl(const char *symbol); __attribute__((section("__ksymtab_strings"))) \ = MODULE_SYMBOL_PREFIX #sym; \ static const struct kernel_symbol __ksymtab_##sym \ - __attribute__((section("__ksymtab" sec))) \ + __attribute__((section("__ksymtab" sec), unused)) \ = { (unsigned long)&sym, __kstrtab_##sym } #define EXPORT_SYMBOL(sym) \ -- cgit v1.2.3 From d5ea3bb59fe2d4a5216e1daa1e5631f47825665e Mon Sep 17 00:00:00 2001 From: Kai Germaschewski Date: Mon, 3 Feb 2003 02:19:44 -0600 Subject: kbuild: Rename CONFIG_MODVERSIONING -> CONFIG_MODVERSIONS CONFIG_MODVERSIONING was a temporary name introduced to distinguish between the old and new module version implementation. Since the traces of the old implementation are now gone from the build system, we rename the config option back in order to not confuse users more than necessary in 2.6. Also, remove some historic modversions cruft throughout the tree. --- Makefile | 6 +++--- drivers/char/ftape/compressor/zftape-compress.c | 6 +----- drivers/char/ftape/lowlevel/ftape-init.c | 6 +----- drivers/char/ftape/zftape/zftape-init.c | 6 +----- drivers/scsi/aic7xxx/aic79xx_osm.c | 6 ------ drivers/scsi/aic7xxx/aic79xx_osm.h | 3 --- drivers/scsi/aic7xxx/aic7xxx_osm.c | 6 ------ drivers/scsi/aic7xxx/aic7xxx_osm.h | 3 --- include/linux/module.h | 2 +- init/Kconfig | 3 +-- kernel/ksyms.c | 7 ------- kernel/module.c | 4 ++-- scripts/Makefile.build | 12 ++++++------ 13 files changed, 16 insertions(+), 54 deletions(-) (limited to 'include') diff --git a/Makefile b/Makefile index f2904aa745d7..11b0d705a782 100644 --- a/Makefile +++ b/Makefile @@ -266,7 +266,7 @@ endif # the built-in objects during the descend as well, in order to # make sure the checksums are uptodate before we record them. -ifdef CONFIG_MODVERSIONING +ifdef CONFIG_MODVERSIONS ifeq ($(KBUILD_MODULES),1) ifneq ($(KBUILD_BUILTIN),1) KBUILD_BUILTIN := 1 @@ -402,7 +402,7 @@ $(SUBDIRS): prepare .PHONY: prepare prepare: include/linux/version.h include/asm include/config/MARKER -ifdef CONFIG_MODVERSIONING +ifdef CONFIG_MODVERSIONS ifdef KBUILD_MODULES ifeq ($(origin SUBDIRS),file) $(Q)rm -rf $(MODVERDIR) @@ -511,7 +511,7 @@ ifdef CONFIG_MODULES .PHONY: modules __modversions modules: $(SUBDIRS) __modversions -ifdef CONFIG_MODVERSIONING +ifdef CONFIG_MODVERSIONS __modversions: vmlinux $(SUBDIRS) @echo ' Recording module symbol versions.'; diff --git a/drivers/char/ftape/compressor/zftape-compress.c b/drivers/char/ftape/compressor/zftape-compress.c index 6f58ed077944..37c8fbaf247b 100644 --- a/drivers/char/ftape/compressor/zftape-compress.c +++ b/drivers/char/ftape/compressor/zftape-compress.c @@ -1196,11 +1196,7 @@ int zft_compressor_init(void) printk( KERN_INFO "(c) 1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n" KERN_INFO "Compressor for zftape (lzrw3 algorithm)\n" -KERN_INFO "Compiled for kernel version %s" -#ifdef MODVERSIONS - " with versioned symbols" -#endif - "\n", UTS_RELEASE); +KERN_INFO "Compiled for kernel version %s\n", UTS_RELEASE); } #else /* !MODULE */ /* print a short no-nonsense boot message */ diff --git a/drivers/char/ftape/lowlevel/ftape-init.c b/drivers/char/ftape/lowlevel/ftape-init.c index 70530a2bebd0..9ffe3de655c0 100644 --- a/drivers/char/ftape/lowlevel/ftape-init.c +++ b/drivers/char/ftape/lowlevel/ftape-init.c @@ -70,11 +70,7 @@ KERN_INFO "(c) 1993-1996 Bas Laarhoven (bas@vimec.nl)\n" KERN_INFO "(c) 1995-1996 Kai Harrekilde-Petersen (khp@dolphinics.no)\n" KERN_INFO "(c) 1996-1997 Claus-Justus Heine (claus@momo.math.rwth-aachen.de)\n" KERN_INFO "QIC-117 driver for QIC-40/80/3010/3020 floppy tape drives\n" -KERN_INFO "Compiled for Linux version %s" -#ifdef MODVERSIONS - " with versioned symbols" -#endif - "\n", UTS_RELEASE); +KERN_INFO "Compiled for Linux version %s\n", UTS_RELEASE); } #else /* !MODULE */ /* print a short no-nonsense boot message */ diff --git a/drivers/char/ftape/zftape/zftape-init.c b/drivers/char/ftape/zftape/zftape-init.c index 4e56739b6a32..b1c015254c6f 100644 --- a/drivers/char/ftape/zftape/zftape-init.c +++ b/drivers/char/ftape/zftape/zftape-init.c @@ -331,11 +331,7 @@ KERN_INFO KERN_INFO "and builtin compression (lzrw3 algorithm).\n" KERN_INFO -"Compiled for Linux version %s" -#ifdef MODVERSIONS - " with versioned symbols" -#endif - "\n", UTS_RELEASE); +"Compiled for Linux version %s\n", UTS_RELEASE); } #else /* !MODULE */ /* print a short no-nonsense boot message */ diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c index 05edbed59319..0d15557c8383 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.c +++ b/drivers/scsi/aic7xxx/aic79xx_osm.c @@ -42,12 +42,6 @@ * POSSIBILITY OF SUCH DAMAGES. */ -/* - * This is the only file where module.h should - * embed module global version info. - */ -#define AHD_MODVERSION_FILE - #include "aic79xx_osm.h" #include "aic79xx_inline.h" #include diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.h b/drivers/scsi/aic7xxx/aic79xx_osm.h index ecf6fdf9ef01..38da2b580d2d 100644 --- a/drivers/scsi/aic7xxx/aic79xx_osm.h +++ b/drivers/scsi/aic7xxx/aic79xx_osm.h @@ -50,9 +50,6 @@ #include #include #include -#ifndef AHD_MODVERSION_FILE -#define __NO_VERSION__ -#endif #include #include diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c index 07087d348cd6..123ec0b80606 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.c +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c @@ -119,12 +119,6 @@ * */ -/* - * This is the only file where module.h should - * embed module global version info. - */ -#define AHC_MODVERSION_FILE - #include "aic7xxx_osm.h" #include "aic7xxx_inline.h" #include diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.h b/drivers/scsi/aic7xxx/aic7xxx_osm.h index a76fa110ffdc..2c309f53022c 100644 --- a/drivers/scsi/aic7xxx/aic7xxx_osm.h +++ b/drivers/scsi/aic7xxx/aic7xxx_osm.h @@ -67,9 +67,6 @@ #include #include #include -#ifndef AHC_MODVERSION_FILE -#define __NO_VERSION__ -#endif #include #include #include diff --git a/include/linux/module.h b/include/linux/module.h index 1be44624ec3a..1265b060475d 100644 --- a/include/linux/module.h +++ b/include/linux/module.h @@ -155,7 +155,7 @@ void *__symbol_get_gpl(const char *symbol); #else -#ifdef CONFIG_MODVERSIONING +#ifdef CONFIG_MODVERSIONS /* Mark the CRC weak since genksyms apparently decides not to * generate a checksums for some symbols */ #define __CRC_SYMBOL(sym, sec) \ diff --git a/init/Kconfig b/init/Kconfig index 5541908be8c0..887abc316ee2 100644 --- a/init/Kconfig +++ b/init/Kconfig @@ -144,11 +144,10 @@ config OBSOLETE_MODPARM have not been converted to the new module parameter system yet. If unsure, say Y. -config MODVERSIONING +config MODVERSIONS bool "Module versioning support (EXPERIMENTAL)" depends on MODULES && EXPERIMENTAL help - ---help--- Usually, you have to use modules compiled with your kernel. Saying Y here makes it sometimes possible to use modules compiled for different kernels, by adding enough information diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 574addf5af63..b65124149fc3 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -68,13 +68,6 @@ extern struct timezone sys_tz; extern int panic_timeout; -#ifdef CONFIG_MODVERSIONS -const struct module_symbol __export_Using_Versions -__attribute__((section("__ksymtab"))) = { - 1 /* Version version */, "Using_Versions" -}; -#endif - /* process memory management */ EXPORT_SYMBOL(do_mmap_pgoff); EXPORT_SYMBOL(do_munmap); diff --git a/kernel/module.c b/kernel/module.c index 64fb7e574927..72b3569404bf 100644 --- a/kernel/module.c +++ b/kernel/module.c @@ -725,7 +725,7 @@ static int obsolete_params(const char *name, } #endif /* CONFIG_OBSOLETE_MODPARM */ -#ifdef CONFIG_MODVERSIONING +#ifdef CONFIG_MODVERSIONS static int check_version(Elf_Shdr *sechdrs, unsigned int versindex, const char *symname, @@ -779,7 +779,7 @@ static inline int check_version(Elf_Shdr *sechdrs, { return 1; } -#endif /* CONFIG_MODVERSIONING */ +#endif /* CONFIG_MODVERSIONS */ /* Resolve a symbol for this module. I.e. if we find one, record usage. Must be holding module_mutex. */ diff --git a/scripts/Makefile.build b/scripts/Makefile.build index 1c2a3d057b40..554368dc80c8 100644 --- a/scripts/Makefile.build +++ b/scripts/Makefile.build @@ -45,7 +45,7 @@ O_TARGET := $(obj)/built-in.o endif endif -ifdef CONFIG_MODVERSIONING +ifdef CONFIG_MODVERSIONS modules := $(obj-m) touch-module = @mkdir -p $(MODVERDIR)/$(@D); touch $(MODVERDIR)/$(@:.o=.ko) else @@ -60,7 +60,7 @@ __build: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \ # Module versioning # --------------------------------------------------------------------------- -ifdef CONFIG_MODVERSIONING +ifdef CONFIG_MODVERSIONS # $(call if_changed_rule,vcc_o_c) does essentially the same as the # normal $(call if_changed_dep,cc_o_c), i.e. compile an object file @@ -153,7 +153,7 @@ quiet_cmd_cc_o_c = CC $(quiet_modtag) $@ cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $< %.o: %.c FORCE -ifdef CONFIG_MODVERSIONING +ifdef CONFIG_MODVERSIONS $(call if_changed_rule,vcc_o_c) else $(call if_changed_dep,cc_o_c) @@ -162,7 +162,7 @@ endif # For modversioning, we need to special case single-part modules # to mark them in $(MODVERDIR) -ifdef CONFIG_MODVERSIONING +ifdef CONFIG_MODVERSIONS $(single-used-m): %.o: %.c FORCE $(touch-module) $(call if_changed_rule,vcc_o_c) @@ -259,9 +259,9 @@ targets += $(multi-used-y) $(multi-used-m) # Rule to link modules ( .o -> .ko ) # -# With CONFIG_MODVERSIONING, generation of the final .ko is handled +# With CONFIG_MODVERSIONS, generation of the final .ko is handled # by scripts/Makefile.modver -ifndef CONFIG_MODVERSIONING +ifndef CONFIG_MODVERSIONS quiet_cmd_link_module = LD [M] $@ cmd_link_module = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $< init/vermagic.o -- cgit v1.2.3