Commit c99e695c authored by Kai Germaschewski's avatar Kai Germaschewski

Hand merged

parents c92cacc2 e24c9231
......@@ -183,6 +183,8 @@ export CPPFLAGS NOSTDINC_FLAGS OBJCOPYFLAGS LDFLAGS
export CFLAGS CFLAGS_KERNEL CFLAGS_MODULE
export AFLAGS AFLAGS_KERNEL AFLAGS_MODULE
export MODVERDIR := .tmp_versions
# The temporary file to save gcc -MD generated dependencies must not
# contain a comma
depfile = $(subst $(comma),_,$(@D)/.$(@F).d)
......@@ -190,7 +192,7 @@ depfile = $(subst $(comma),_,$(@D)/.$(@F).d)
noconfig_targets := xconfig menuconfig config oldconfig randconfig \
defconfig allyesconfig allnoconfig allmodconfig \
clean mrproper distclean \
help tags TAGS sgmldocs psdocs pdfdocs htmldocs \
help tags TAGS cscope sgmldocs psdocs pdfdocs htmldocs \
checkconfig checkhelp checkincludes
RCS_FIND_IGNORE := \( -name SCCS -o -name BitKeeper -o -name .svn -o -name CVS \) -prune -o
......@@ -256,14 +258,22 @@ ifdef include_config
-include .config.cmd
ifdef CONFIG_MODULES
export EXPORT_FLAGS := -DEXPORT_SYMTAB
endif
ifndef CONFIG_FRAME_POINTER
CFLAGS += -fomit-frame-pointer
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 record them.
ifdef CONFIG_MODVERSIONS
ifeq ($(KBUILD_MODULES),1)
ifneq ($(KBUILD_BUILTIN),1)
KBUILD_BUILTIN := 1
endif
endif
endif
#
# INSTALL_PATH specifies where to place the updated kernel and system map
# images. Uncomment if you want to place them anywhere other than root.
......@@ -384,7 +394,7 @@ $(sort $(vmlinux-objs)): $(SUBDIRS) ;
# Handle descending into subdirectories listed in $(SUBDIRS)
.PHONY: $(SUBDIRS)
$(SUBDIRS): .hdepend prepare
$(SUBDIRS): prepare
$(Q)$(MAKE) $(build)=$@
# Things we need done before we descend to build or make
......@@ -392,6 +402,16 @@ $(SUBDIRS): .hdepend prepare
.PHONY: prepare
prepare: include/linux/version.h include/asm include/config/MARKER
ifdef CONFIG_MODVERSIONS
ifdef KBUILD_MODULES
ifeq ($(origin SUBDIRS),file)
$(Q)rm -rf $(MODVERDIR)
else
@echo '*** Warning: Overriding SUBDIRS on the command line can cause'
@echo '*** inconsistencies with module symbol versions'
endif
endif
endif
@echo ' Starting the build. KBUILD_BUILTIN=$(KBUILD_BUILTIN) KBUILD_MODULES=$(KBUILD_MODULES)'
# We need to build init/vermagic.o before descending since all modules
......@@ -475,61 +495,11 @@ include/linux/version.h: Makefile
) > $@.tmp
@$(update-if-changed)
# Generate module versions
# ---------------------------------------------------------------------------
# The targets are still named depend / dep for traditional
# reasons, but the only thing we do here is generating
# the module version checksums.
.PHONY: depend dep $(patsubst %,_sfdep_%,$(SUBDIRS))
depend dep: .hdepend
# .hdepend is our (misnomed) marker for whether we've
# generated module versions
make-versions := $(strip $(if $(filter dep depend,$(MAKECMDGOALS)),1) \
$(if $(wildcard .hdepend),,1))
.hdepend: prepare FORCE
ifneq ($(make-versions),)
@$(MAKE) include/linux/modversions.h
@touch $@
endif
ifdef CONFIG_MODVERSIONS
# Update modversions.h, but only if it would change.
.PHONY: __rm_tmp_export-objs
__rm_tmp_export-objs:
@rm -rf .tmp_export-objs
include/linux/modversions.h: $(patsubst %,_modver_%,$(SUBDIRS))
@echo -n ' Generating $@'
@( echo "#ifndef _LINUX_MODVERSIONS_H";\
echo "#define _LINUX_MODVERSIONS_H"; \
echo "#include <linux/modsetver.h>"; \
cd .tmp_export-objs >/dev/null; \
for f in `find modules -name \*.ver -print | sort`; do \
echo "#include <linux/$${f}>"; \
done; \
echo "#endif"; \
) > $@.tmp; \
$(update-if-changed)
.PHONY: $(patsubst %, _modver_%, $(SUBDIRS))
$(patsubst %, _modver_%, $(SUBDIRS)): __rm_tmp_export-objs
$(Q)$(MAKE) -f scripts/Makefile.modver obj=$(patsubst _modver_%,%,$@)
else # !CONFIG_MODVERSIONS
.PHONY: include/linux/modversions.h
include/linux/modversions.h:
endif # CONFIG_MODVERSIONS
.PHONY: depend dep
depend dep:
@echo'*** Warning: make $@ is unnecessary now.'
# ---------------------------------------------------------------------------
# Modules
......@@ -538,12 +508,16 @@ ifdef CONFIG_MODULES
# Build modules
.PHONY: modules __modversions
modules: $(SUBDIRS) __modversions
ifdef CONFIG_MODVERSIONS
MODFLAGS += -include include/linux/modversions.h
endif
.PHONY: modules
modules: $(SUBDIRS)
__modversions: vmlinux $(SUBDIRS)
@echo ' Recording module symbol versions.';
$(Q)$(MAKE) -rR -f scripts/Makefile.modver
endif
# Install modules
......@@ -574,6 +548,7 @@ _modinst_post:
.PHONY: $(patsubst %, _modinst_%, $(SUBDIRS))
$(patsubst %, _modinst_%, $(SUBDIRS)) :
$(Q)$(MAKE) -rR -f scripts/Makefile.modinst obj=$(patsubst _modinst_%,%,$@)
else # CONFIG_MODULES
# Modules not configured
......@@ -624,7 +599,7 @@ spec:
rpm: clean spec
find . $(RCS_FIND_IGNORE) \
\( -size 0 -o -name .depend -o -name .hdepend \) \
\( -size 0 -o -name .depend -o -name .hdepend\) \
-type f -print | xargs rm -f
set -e; \
cd $(TOPDIR)/.. ; \
......@@ -718,11 +693,12 @@ MRPROPER_FILES += \
.menuconfig.log \
include/asm \
.hdepend include/linux/modversions.h \
tags TAGS kernel.spec \
tags TAGS cscope kernel.spec \
.tmp*
# Directories removed with 'make mrproper'
MRPROPER_DIRS += \
$(MODVERDIR) \
.tmp_export-objs \
include/config \
include/linux/modules
......@@ -775,6 +751,9 @@ define all-sources
-name '*.[chS]' -print )
endef
quiet_cmd_cscope = MAKE $@
cmd_cscope = $(all-sources) | cscope -k -b -i -
quiet_cmd_TAGS = MAKE $@
cmd_TAGS = $(all-sources) | etags -
......@@ -787,6 +766,9 @@ define cmd_tags
$(all-sources) | xargs ctags $$CTAGSF -a
endef
cscope: FORCE
$(call cmd,cscope)
TAGS: FORCE
$(call cmd,TAGS)
......
......@@ -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 */
......
......@@ -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 */
......
......@@ -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 */
......
......@@ -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 <scsi/scsicam.h>
......
......@@ -50,9 +50,6 @@
#include <linux/pci.h>
#include <linux/smp_lock.h>
#include <linux/version.h>
#ifndef AHD_MODVERSION_FILE
#define __NO_VERSION__
#endif
#include <linux/module.h>
#include <asm/byteorder.h>
#include <asm/io.h>
......
......@@ -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 <scsi/scsicam.h>
......
......@@ -67,9 +67,6 @@
#include <linux/pci.h>
#include <linux/smp_lock.h>
#include <linux/version.h>
#ifndef AHC_MODVERSION_FILE
#define __NO_VERSION__
#endif
#include <linux/module.h>
#include <asm/byteorder.h>
#include <asm/io.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 */ \
......
......@@ -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);
......@@ -92,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 */
......@@ -119,6 +126,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 */
......@@ -134,29 +142,52 @@ 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 __GENKSYMS__
/* genksyms doesn't handle GPL-only symbols yet */
#define EXPORT_SYMBOL_GPL EXPORT_SYMBOL
#else
#ifdef CONFIG_MODVERSIONS
/* 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), unused)) \
= (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), unused)) \
= { (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) \
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 }
__EXPORT_SYMBOL(sym, "_gpl")
#endif
/* 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
{
......
......@@ -144,6 +144,18 @@ config OBSOLETE_MODPARM
have not been converted to the new module parameter system yet.
If unsure, say Y.
config MODVERSIONS
bool "Module versioning support (EXPERIMENTAL)"
depends on MODULES && EXPERIMENTAL
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
......
......@@ -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);
......
......@@ -78,6 +78,7 @@ EXPORT_SYMBOL(init_module);
/* Find a symbol, return value and the symbol group */
static unsigned long __find_symbol(const char *name,
struct kernel_symbol_group **group,
unsigned int *symidx,
int gplok)
{
struct kernel_symbol_group *ks;
......@@ -90,6 +91,8 @@ static unsigned long __find_symbol(const char *name,
for (i = 0; i < ks->num_syms; i++) {
if (strcmp(ks->syms[i].name, name) == 0) {
*group = ks;
if (symidx)
*symidx = i;
return ks->syms[i].value;
}
}
......@@ -520,7 +523,7 @@ void __symbol_put(const char *symbol)
unsigned long flags;
spin_lock_irqsave(&modlist_lock, flags);
if (!__find_symbol(symbol, &ksg, 1))
if (!__find_symbol(symbol, &ksg, NULL, 1))
BUG();
module_put(ksg->owner);
spin_unlock_irqrestore(&modlist_lock, flags);
......@@ -722,22 +725,91 @@ static int obsolete_params(const char *name,
}
#endif /* CONFIG_OBSOLETE_MODPARM */
#ifdef CONFIG_MODVERSIONS
static int check_version(Elf_Shdr *sechdrs,
unsigned int versindex,
const char *symname,
struct module *mod,
struct kernel_symbol_group *ksg,
unsigned int symidx)
{
unsigned long crc;
unsigned int i, num_versions;
struct modversion_info *versions;
/* Exporting module didn't supply crcs? OK, we're already tainted. */
if (!ksg->crcs)
return 1;
crc = ksg->crcs[symidx];
versions = (void *) sechdrs[versindex].sh_addr;
num_versions = sechdrs[versindex].sh_size
/ sizeof(struct modversion_info);
for (i = 0; i < num_versions; i++) {
if (strcmp(versions[i].name, symname) != 0)
continue;
if (versions[i].crc == crc)
return 1;
printk("%s: disagrees about version of symbol %s\n",
mod->name, symname);
DEBUGP("Found checksum %lX vs module %lX\n",
crc, versions[i].crc);
return 0;
}
/* Not in module's version table. OK, but that taints the kernel. */
if (!(tainted & TAINT_FORCED_MODULE)) {
printk("%s: no version for \"%s\" found: kernel tainted.\n",
mod->name, symname);
tainted |= TAINT_FORCED_MODULE;
}
return 1;
}
/* First part is kernel version, which we ignore. */
static inline int same_magic(const char *amagic, const char *bmagic)
{
amagic += strcspn(amagic, " ");
bmagic += strcspn(bmagic, " ");
return strcmp(amagic, bmagic) == 0;
}
#else
static inline int check_version(Elf_Shdr *sechdrs,
unsigned int versindex,
const char *symname,
struct module *mod,
struct kernel_symbol_group *ksg,
unsigned int symidx)
{
return 1;
}
static inline int same_magic(const char *amagic, const char *bmagic)
{
return strcmp(amagic, bmagic) == 0;
}
#endif /* CONFIG_MODVERSIONS */
/* Resolve a symbol for this module. I.e. if we find one, record usage.
Must be holding module_mutex. */
static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
unsigned int symindex,
const char *strtab,
unsigned int versindex,
const char *name,
struct module *mod)
{
struct kernel_symbol_group *ksg;
unsigned long ret;
unsigned int symidx;
spin_lock_irq(&modlist_lock);
ret = __find_symbol(name, &ksg, mod->license_gplok);
ret = __find_symbol(name, &ksg, &symidx, mod->license_gplok);
if (ret) {
/* This can fail due to OOM, or module unloading */
if (!use_module(mod, ksg->owner))
/* use_module can fail due to OOM, or module unloading */
if (!check_version(sechdrs, versindex, name, mod,
ksg, symidx) ||
!use_module(mod, ksg->owner))
ret = 0;
}
spin_unlock_irq(&modlist_lock);
......@@ -772,7 +844,7 @@ void *__symbol_get(const char *symbol)
unsigned long value, flags;
spin_lock_irqsave(&modlist_lock, flags);
value = __find_symbol(symbol, &ksg, 1);
value = __find_symbol(symbol, &ksg, NULL, 1);
if (value && !strong_try_module_get(ksg->owner))
value = 0;
spin_unlock_irqrestore(&modlist_lock, flags);
......@@ -824,6 +896,7 @@ static int handle_section(const char *name,
static int simplify_symbols(Elf_Shdr *sechdrs,
unsigned int symindex,
unsigned int strindex,
unsigned int versindex,
struct module *mod)
{
Elf_Sym *sym = (void *)sechdrs[symindex].sh_addr;
......@@ -848,7 +921,7 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
case SHN_UNDEF:
sym[i].st_value
= resolve_symbol(sechdrs, symindex, strtab,
= resolve_symbol(sechdrs, versindex,
strtab + sym[i].st_name, mod);
/* Ok if resolved. */
......@@ -916,7 +989,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 +1005,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 +1049,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, versindex;
long arglen;
struct module *mod;
long err = 0;
......@@ -1012,7 +1086,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 = versindex = 0;
/* And these should exist, but gcc whinges if we don't init them */
symindex = strindex = exindex = modindex = vmagindex = 0;
......@@ -1040,6 +1115,21 @@ 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, "__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 */
......@@ -1060,16 +1150,21 @@ static struct module *load_module(void *umod,
/* MODULE_LICENSE() */
DEBUGP("Licence found in section %u\n", i);
licenseindex = i;
sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
} 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) {
"__vermagic") == 0 &&
(sechdrs[i].sh_flags & SHF_ALLOC)) {
/* Version magic. */
DEBUGP("Version magic found in section %u\n", i);
vmagindex = i;
sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
} else if (strcmp(secstrings+sechdrs[i].sh_name,
"__versions") == 0 &&
(sechdrs[i].sh_flags & SHF_ALLOC)) {
/* Module version info (both exported and needed) */
DEBUGP("Versions found in section %u\n", i);
versindex = i;
sechdrs[i].sh_flags &= ~(unsigned long)SHF_ALLOC;
}
#ifdef CONFIG_KALLSYMS
/* symbol and string tables for decoding later. */
......@@ -1090,12 +1185,12 @@ static struct module *load_module(void *umod,
}
mod = (void *)sechdrs[modindex].sh_addr;
/* This is allowed: modprobe --force will strip it. */
/* This is allowed: modprobe --force will invalidate it. */
if (!vmagindex) {
tainted |= TAINT_FORCED_MODULE;
printk(KERN_WARNING "%s: no version magic, tainting kernel.\n",
mod->name);
} else if (strcmp((char *)sechdrs[vmagindex].sh_addr, vermagic) != 0) {
} else if (!same_magic((char *)sechdrs[vmagindex].sh_addr, vermagic)) {
printk(KERN_ERR "%s: version magic '%s' should be '%s'\n",
mod->name, (char*)sechdrs[vmagindex].sh_addr, vermagic);
err = -ENOEXEC;
......@@ -1181,7 +1276,7 @@ static struct module *load_module(void *umod,
set_license(mod, sechdrs, licenseindex);
/* Fix up syms, so that st_value is a pointer to location. */
err = simplify_symbols(sechdrs, symindex, strindex, mod);
err = simplify_symbols(sechdrs, symindex, strindex, versindex, mod);
if (err < 0)
goto cleanup;
......@@ -1189,9 +1284,23 @@ 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;
if (crcindex)
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;
if (gplcrcindex)
mod->gpl_symbols.crcs = (void *)sechdrs[gplcrcindex].sh_addr;
#ifdef CONFIG_MODVERSIONS
if ((mod->symbols.num_syms && !crcindex)
|| (mod->gpl_symbols.num_syms && !gplcrcindex))
printk(KERN_WARNING "%s: No versions for exported symbols."
" Tainting kernel.\n", mod->name);
tainted |= TAINT_FORCED_MODULE;
}
#endif
/* Set up exception table */
if (exindex) {
......@@ -1492,8 +1601,12 @@ 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[];
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;
......@@ -1502,11 +1615,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___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.crcs = __start___kcrctab_gpl;
kernel_gpl_symbols.gplonly = 1;
list_add(&kernel_gpl_symbols.list, &symbols);
......
......@@ -45,11 +45,67 @@ O_TARGET := $(obj)/built-in.o
endif
endif
ifdef CONFIG_MODVERSIONS
modules := $(obj-m)
touch-module = @mkdir -p $(MODVERDIR)/$(@D); touch $(MODVERDIR)/$(@:.o=.ko)
else
modules := $(obj-m:.o=.ko)
endif
__build: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \
$(if $(KBUILD_MODULES),$(obj-m:.o=.ko)) \
$(if $(KBUILD_MODULES),$(modules)) \
$(subdir-ym) $(build-targets)
@:
# Module versioning
# ---------------------------------------------------------------------------
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
# from a C file, keeping track of the command line and dependencies.
#
# However, actually it does:
# o compile a .tmp_<file>.o from <file>.c
# o if .tmp_<file>.o doesn't contain a __ksymtab version, i.e. does
# not export symbols, we just rename .tmp_<file>.o to <file>.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 <file>.o from .tmp_<file>.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)
# ---------------------------------------------------------------------------
......@@ -69,11 +125,6 @@ $(real-objs-m:.o=.lst): quiet_modtag := [M]
$(obj-m) : quiet_modtag := [M]
$(export-objs) : export_flags := $(EXPORT_FLAGS)
$(export-objs:.o=.i) : export_flags := $(EXPORT_FLAGS)
$(export-objs:.o=.s) : export_flags := $(EXPORT_FLAGS)
$(export-objs:.o=.lst): export_flags := $(EXPORT_FLAGS)
# Default for not multi-part modules
modname = $(*F)
......@@ -102,7 +153,20 @@ quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
%.o: %.c FORCE
ifdef CONFIG_MODVERSIONS
$(call if_changed_rule,vcc_o_c)
else
$(call if_changed_dep,cc_o_c)
endif
# For modversioning, we need to special case single-part modules
# to mark them in $(MODVERDIR)
ifdef CONFIG_MODVERSIONS
$(single-used-m): %.o: %.c FORCE
$(touch-module)
$(call if_changed_rule,vcc_o_c)
endif
quiet_cmd_cc_lst_c = MKLST $@
cmd_cc_lst_c = $(CC) $(c_flags) -g -c -o $*.o $< && \
......@@ -176,15 +240,7 @@ quiet_cmd_link_multi-y = LD $@
cmd_link_multi-y = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) -r -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.o=-objs))) $($(subst $(obj)/,,$(@:.o=-y)))),$^)
quiet_cmd_link_multi-m = LD [M] $@
cmd_link_multi-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.ko=-objs))) $($(subst $(obj)/,,$(@:.ko=-y)))),$^) init/vermagic.o
quiet_cmd_link_single-m = LD [M] $@
cmd_link_single-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $< init/vermagic.o
# Don't rebuilt vermagic.o unless we actually are in the init/ dir
ifneq ($(obj),init)
init/vermagic.o: ;
endif
cmd_link_multi-m = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $(filter $(addprefix $(obj)/,$($(subst $(obj)/,,$(@:.o=-objs))) $($(subst $(obj)/,,$(@:.o=-y)))),$^)
# We would rather have a list of rules like
# foo.o: $(foo-objs)
......@@ -193,13 +249,34 @@ endif
$(multi-used-y) : %.o: $(multi-objs-y) FORCE
$(call if_changed,link_multi-y)
$(multi-used-m:.o=.ko) : %.ko: $(multi-objs-m) init/vermagic.o FORCE
$(multi-used-m) : %.o: $(multi-objs-m) FORCE
$(touch-module)
$(call if_changed,link_multi-m)
$(single-used-m:.o=.ko) : %.ko: %.o init/vermagic.o FORCE
$(call if_changed,link_single-m)
targets += $(multi-used-y) $(multi-used-m)
#
# Rule to link modules ( .o -> .ko )
#
# With CONFIG_MODVERSIONS, generation of the final .ko is handled
# by scripts/Makefile.modver
ifndef CONFIG_MODVERSIONS
quiet_cmd_link_module = LD [M] $@
cmd_link_module = $(LD) $(LDFLAGS) $(EXTRA_LDFLAGS) $(LDFLAGS_MODULE) -o $@ $< init/vermagic.o
targets += $(multi-used-y) $(multi-used-m:.o=.ko) $(single-used-m:.o=.ko)
# Don't rebuilt vermagic.o unless we actually are in the init/ dir
ifneq ($(obj),init)
init/vermagic.o: ;
endif
$(single-used-m:.o=.ko) $(multi-used-m:.o=.ko): %.ko: %.o init/vermagic.o FORCE
$(call if_changed,link_module)
targets += $(single-used-m:.o=.ko) $(multi-used-m:.o=.ko)
endif
# Compile programs on the host
# ===========================================================================
......
......@@ -34,14 +34,9 @@ obj-m := $(filter-out %/, $(obj-m))
subdir-ym := $(sort $(subdir-y) $(subdir-m))
# export.o is never a composite object, since $(export-objs) has a
# fixed meaning (== objects which EXPORT_SYMBOL())
__obj-y = $(filter-out export.o,$(obj-y))
__obj-m = $(filter-out export.o,$(obj-m))
# if $(foo-objs) exists, foo.o is a composite object
multi-used-y := $(sort $(foreach m,$(__obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
multi-used-m := $(sort $(foreach m,$(__obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
multi-used-y := $(sort $(foreach m,$(obj-y), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
multi-used-m := $(sort $(foreach m,$(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))), $(m))))
multi-used := $(multi-used-y) $(multi-used-m)
single-used-m := $(sort $(filter-out $(multi-used-m),$(obj-m)))
......@@ -59,9 +54,6 @@ subdir-obj-y := $(foreach o,$(obj-y),$(if $(filter-out $(o),$(notdir $(o))),$(o)
real-objs-y := $(foreach m, $(filter-out $(subdir-obj-y), $(obj-y)), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m))) $(EXTRA_TARGETS)
real-objs-m := $(foreach m, $(obj-m), $(if $(strip $($(m:.o=-objs)) $($(m:.o=-y))),$($(m:.o=-objs)) $($(m:.o=-y)),$(m)))
# Only build module versions for files which are selected to be built
export-objs := $(filter $(export-objs),$(real-objs-y) $(real-objs-m))
# C code
# Executables compiled from a single .c file
host-csingle := $(foreach m,$(host-progs),$(if $($(m)-objs),,$(m)))
......@@ -96,7 +88,6 @@ EXTRA_TARGETS := $(addprefix $(obj)/,$(EXTRA_TARGETS))
build-targets := $(addprefix $(obj)/,$(build-targets))
obj-y := $(addprefix $(obj)/,$(obj-y))
obj-m := $(addprefix $(obj)/,$(obj-m))
export-objs := $(addprefix $(obj)/,$(export-objs))
subdir-obj-y := $(addprefix $(obj)/,$(subdir-obj-y))
real-objs-y := $(addprefix $(obj)/,$(real-objs-y))
real-objs-m := $(addprefix $(obj)/,$(real-objs-m))
......@@ -130,7 +121,7 @@ basename_flags = -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F)))
modname_flags = $(if $(filter 1,$(words $(modname))),-DKBUILD_MODNAME=$(subst $(comma),_,$(subst -,_,$(modname))))
c_flags = -Wp,-MD,$(depfile) $(CFLAGS) $(NOSTDINC_FLAGS) \
$(modkern_cflags) $(EXTRA_CFLAGS) $(CFLAGS_$(*F).o) \
$(basename_flags) $(modname_flags) $(export_flags)
$(basename_flags) $(modname_flags)
a_flags = -Wp,-MD,$(depfile) $(AFLAGS) $(NOSTDINC_FLAGS)\
$(modkern_aflags) $(EXTRA_AFLAGS) $(AFLAGS_$(*F).o)
hostc_flags = -Wp,-MD,$(depfile) $(HOSTCFLAGS) $(HOST_EXTRACFLAGS)\
......@@ -217,7 +208,6 @@ if_changed_rule = $(if $(strip $? \
$(filter-out $(cmd_$(1)),$(cmd_$@))\
$(filter-out $(cmd_$@),$(cmd_$(1)))),\
@set -e; \
mkdir -p $(dir $@); \
$(rule_$(1)))
# If quiet is set, only print short version of command
......
......@@ -2,105 +2,82 @@
# Module versions
# ===========================================================================
src := $(obj)
.PHONY: __modversions
__modversions:
MODVERDIR := include/linux/modules
include scripts/Makefile.lib
.PHONY: modver
modver:
#
include .config
modules := $(patsubst ./%,%,$(shell cd $(MODVERDIR); find . -name \*.ko))
include $(obj)/Makefile
__modversions: $(modules)
@:
include scripts/Makefile.lib
# The final module link
# ===========================================================================
quiet_cmd_ld_ko_o = LD [M] $@
cmd_ld_ko_o = $(LD) $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \
$(filter-out FORCE,$^)
ifeq ($(strip $(export-objs)),)
init/vermagic.o: ;
# If we don't export any symbols in this dir, just descend
# ---------------------------------------------------------------------------
$(modules): %.ko :%.o %.ver.o init/vermagic.o FORCE
$(call if_changed,ld_ko_o)
modver: $(subdir-ym)
@:
targets += $(modules)
else
# Compile version info for unresolved symbols
# This sets version suffixes on exported symbols
# ---------------------------------------------------------------------------
quiet_cmd_cc_o_c = CC $@
cmd_cc_o_c = $(CC) $(CFLAGS) -c -o $@ $<
#
# Added the SMP separator to stop module accidents between uniprocessor
# and SMP Intel boxes - AC - from bits by Michael Chastain
#
$(modules:.ko=.ver.o): %.ver.o: %.ver.c FORCE
$(call if_changed,cc_o_c)
ifdef CONFIG_SMP
genksyms_smp_prefix := -p smp_
else
genksyms_smp_prefix :=
endif
targets += $(modules:.ko=.ver.o)
# Generate C source with version info for unresolved symbols
# Don't include modversions.h, we're just about to generate it here.
CFLAGS_MODULE := $(filter-out -include include/linux/modversions.h,$(CFLAGS_MODULE))
$(addprefix $(MODVERDIR)/,$(real-objs-y:.o=.ver)): modkern_cflags := $(CFLAGS_KERNEL)
$(addprefix $(MODVERDIR)/,$(real-objs-m:.o=.ver)): modkern_cflags := $(CFLAGS_MODULE)
$(addprefix $(MODVERDIR)/,$(export-objs:.o=.ver)): export_flags := -D__GENKSYMS__
# Default for not multi-part modules
modname = $(*F)
$(addprefix $(MODVERDIR)/,$(multi-objs:.o=.ver)) : modname = $(modname-multi)
# Our objects only depend on modversions.h, not on the individual .ver
# files (fix-dep filters them), so touch modversions.h if any of the .ver
# files changes
quiet_cmd_cc_ver_c = MKVER include/linux/modules/$*.ver
cmd_cc_ver_c = $(CPP) $(c_flags) $< | $(GENKSYMS) $(genksyms_smp_prefix) \
-k $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) > $@.tmp
# Okay, let's explain what's happening in rule_make_cc_ver_c:
# o echo the command
# o execute the command
# o If the $(CPP) fails, we won't notice because it's output is piped
# to $(GENKSYMS) which does not fail. We recognize this case by
# looking if the generated $(depfile) exists, though.
# o If the .ver file changed, touch modversions.h, which is our marker
# of any changed .ver files.
# o Move command line and deps into their normal .*.cmd place.
define rule_cc_ver_c
$(if $($(quiet)cmd_cc_ver_c),echo ' $($(quiet)cmd_cc_ver_c)';) \
$(cmd_cc_ver_c); \
if [ ! -r $(depfile) ]; then exit 1; fi; \
scripts/fixdep $(depfile) $@ '$(cmd_cc_ver_c)' > $(@D)/.$(@F).tmp; \
rm -f $(depfile); \
if [ ! -r $@ ] || cmp -s $@ $@.tmp; then \
touch include/linux/modversions.h; \
fi; \
mv -f $@.tmp $@
mv -f $(@D)/.$(@F).tmp $(@D)/.$(@F).cmd
define rule_mkver_o_c
echo ' MKVER $@'; \
( echo "#include <linux/module.h>"; \
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
targets := $(addprefix $(MODVERDIR)/,$(export-objs:.o=.ver))
$(modules:.ko=.ver.c): %.ver.c: %.o .tmp_all-versions FORCE
$(call if_changed_rule,mkver_o_c)
$(MODVERDIR)/%.ver: %.c FORCE
@$(call if_changed_rule,cc_ver_c)
targets += $(modules:.ko=.ver.c))
modver: $(targets) $(subdir-ym)
@mkdir -p $(dir $(addprefix .tmp_export-objs/modules/,$(export-objs:.o=.ver)))
@touch $(addprefix .tmp_export-objs/modules/,$(export-objs:.o=.ver))
# Extract all checksums for all exported symbols
endif # export-objs
export-objs := $(shell for m in vmlinux $(modules:.ko=.o); do objdump -h $$m | grep -q __ksymtab && echo $$m; done)
# Descending
# ---------------------------------------------------------------------------
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)
.PHONY: $(subdir-ym)
$(subdir-ym):
$(Q)$(MAKE) -f scripts/Makefile.modver obj=$@
targets += .tmp_all-versions
# Add FORCE to the prequisites of a target to force it to be always rebuilt.
# ---------------------------------------------------------------------------
......
......@@ -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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment