Commit 87353814 authored by Kai Germaschewski's avatar Kai Germaschewski

Merge tp1.ruhr-uni-bochum.de:/scratch/kai/kernel/v2.5/linux-2.5

into tp1.ruhr-uni-bochum.de:/scratch/kai/kernel/v2.5/linux-2.5.make
parents e00b99de 2763b6bc
......@@ -405,30 +405,17 @@ $(SUBDIRS): 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)
$(Q)mkdir $(MODVERDIR)
else
@echo '*** Warning: Overriding SUBDIRS on the command line can cause'
@echo '*** inconsistencies with module symbol versions'
endif
@echo '*** inconsistencies'
endif
$(Q)mkdir -p $(MODVERDIR)
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
# (*.ko) need it already
ifdef CONFIG_MODULES
prepare: init/vermagic.o
init/vermagic.o: include/linux/version.h
endif
# This can be used by arch/$ARCH/Makefile to preprocess
# their vmlinux.lds.S file
......@@ -518,21 +505,15 @@ all: modules
# Build modules
.PHONY: modules __modversions
modules: $(SUBDIRS) __modversions
ifdef CONFIG_MODVERSIONS
__modversions: vmlinux $(SUBDIRS)
@echo ' Recording module symbol versions.';
$(Q)$(MAKE) -rR -f scripts/Makefile.modver
endif
.PHONY: modules
modules: $(SUBDIRS) $(if $(CONFIG_MODVERSIONS),vmlinux)
@echo ' Building modules, stage 2.';
$(Q)$(MAKE) -rR -f scripts/Makefile.modpost
# Install modules
.PHONY: modules_install
modules_install: _modinst_ $(patsubst %, _modinst_%, $(SUBDIRS)) _modinst_post
modules_install: _modinst_ _modinst_post
.PHONY: _modinst_
_modinst_:
......@@ -540,6 +521,7 @@ _modinst_:
@rm -f $(MODLIB)/build
@mkdir -p $(MODLIB)/kernel
@ln -s $(TOPDIR) $(MODLIB)/build
$(Q)$(MAKE) -rR -f scripts/Makefile.modinst
# If System.map exists, run depmod. This deliberately does not have a
# dependency on System.map since that would run the dependency tree on
......@@ -552,13 +534,9 @@ else
depmod_opts := -b $(INSTALL_MOD_PATH) -r
endif
.PHONY: _modinst_post
_modinst_post:
_modinst_post: _modinst_
if [ -r System.map ]; then $(DEPMOD) -ae -F System.map $(depmod_opts) $(KERNELRELEASE); fi
.PHONY: $(patsubst %, _modinst_%, $(SUBDIRS))
$(patsubst %, _modinst_%, $(SUBDIRS)) :
$(Q)$(MAKE) -rR -f scripts/Makefile.modinst obj=$(patsubst _modinst_%,%,$@)
else # CONFIG_MODULES
# Modules not configured
......
/*
* Device tables which are exported to userspace via
* scripts/table2alias.c. You must keep that file in sync with this
* header.
*/
#ifndef LINUX_MOD_DEVICETABLE_H
#define LINUX_MOD_DEVICETABLE_H
#ifdef __KERNEL__
#include <linux/types.h>
typedef unsigned long kernel_ulong_t;
#endif
#define PCI_ANY_ID (~0)
struct pci_device_id {
__u32 vendor, device; /* Vendor and device ID or PCI_ANY_ID*/
__u32 subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
__u32 class, class_mask; /* (class,subclass,prog-if) triplet */
kernel_ulong_t driver_data; /* Data private to the driver */
};
/*
* Device table entry for "new style" table-driven USB drivers.
* User mode code can read these tables to choose which modules to load.
* Declare the table as a MODULE_DEVICE_TABLE.
*
* A probe() parameter will point to a matching entry from this table.
* Use the driver_info field for each match to hold information tied
* to that match: device quirks, etc.
*
* Terminate the driver's table with an all-zeroes entry.
* Use the flag values to control which fields are compared.
*/
/**
* struct usb_device_id - identifies USB devices for probing and hotplugging
* @match_flags: Bit mask controlling of the other fields are used to match
* against new devices. Any field except for driver_info may be used,
* although some only make sense in conjunction with other fields.
* This is usually set by a USB_DEVICE_*() macro, which sets all
* other fields in this structure except for driver_info.
* @idVendor: USB vendor ID for a device; numbers are assigned
* by the USB forum to its members.
* @idProduct: Vendor-assigned product ID.
* @bcdDevice_lo: Low end of range of vendor-assigned product version numbers.
* This is also used to identify individual product versions, for
* a range consisting of a single device.
* @bcdDevice_hi: High end of version number range. The range of product
* versions is inclusive.
* @bDeviceClass: Class of device; numbers are assigned
* by the USB forum. Products may choose to implement classes,
* or be vendor-specific. Device classes specify behavior of all
* the interfaces on a devices.
* @bDeviceSubClass: Subclass of device; associated with bDeviceClass.
* @bDeviceProtocol: Protocol of device; associated with bDeviceClass.
* @bInterfaceClass: Class of interface; numbers are assigned
* by the USB forum. Products may choose to implement classes,
* or be vendor-specific. Interface classes specify behavior only
* of a given interface; other interfaces may support other classes.
* @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass.
* @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass.
* @driver_info: Holds information used by the driver. Usually it holds
* a pointer to a descriptor understood by the driver, or perhaps
* device flags.
*
* In most cases, drivers will create a table of device IDs by using
* USB_DEVICE(), or similar macros designed for that purpose.
* They will then export it to userspace using MODULE_DEVICE_TABLE(),
* and provide it to the USB core through their usb_driver structure.
*
* See the usb_match_id() function for information about how matches are
* performed. Briefly, you will normally use one of several macros to help
* construct these entries. Each entry you provide will either identify
* one or more specific products, or will identify a class of products
* which have agreed to behave the same. You should put the more specific
* matches towards the beginning of your table, so that driver_info can
* record quirks of specific products.
*/
struct usb_device_id {
/* which fields to match against? */
__u16 match_flags;
/* Used for product specific matches; range is inclusive */
__u16 idVendor;
__u16 idProduct;
__u16 bcdDevice_lo;
__u16 bcdDevice_hi;
/* Used for device class matches */
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
/* Used for interface class matches */
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
/* not matched against */
kernel_ulong_t driver_info;
};
/* Some useful macros to use to create struct usb_device_id */
#define USB_DEVICE_ID_MATCH_VENDOR 0x0001
#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002
#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004
#define USB_DEVICE_ID_MATCH_DEV_HI 0x0008
#define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010
#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020
#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040
#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080
#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100
#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
#endif /* LINUX_MOD_DEVICETABLE_H */
......@@ -57,13 +57,14 @@ search_extable(const struct exception_table_entry *first,
unsigned long value);
#ifdef MODULE
#define ___module_cat(a,b) a ## b
#define __module_cat(a,b) ___module_cat(a,b)
/* For userspace: you can also call me... */
#define MODULE_ALIAS(alias) \
static const char __module_cat(__alias_,__LINE__)[] \
__attribute__((section(".modinfo"),unused)) = "alias=" alias
/* For replacement modutils, use an alias not a pointer. */
#define MODULE_GENERIC_TABLE(gtype,name) \
static const unsigned long __module_##gtype##_size \
__attribute__ ((unused)) = sizeof(struct gtype##_id); \
static const struct gtype##_id * __module_##gtype##_table \
__attribute__ ((unused)) = name; \
extern const struct gtype##_id __mod_##gtype##_table \
__attribute__ ((unused, alias(__stringify(name))))
......@@ -103,6 +104,7 @@ extern const struct gtype##_id __mod_##gtype##_table \
#else /* !MODULE */
#define MODULE_ALIAS(alias)
#define MODULE_GENERIC_TABLE(gtype,name)
#define THIS_MODULE ((struct module *)0)
#define MOD_INC_USE_COUNT do { } while (0)
......
......@@ -17,6 +17,8 @@
#ifndef LINUX_PCI_H
#define LINUX_PCI_H
#include <linux/mod_devicetable.h>
/*
* Under PCI, each device has 256 bytes of configuration address space,
* of which the first 64 bytes are standardized as follows:
......@@ -359,8 +361,6 @@ enum pci_mmap_state {
#define DEVICE_COUNT_DMA 2
#define DEVICE_COUNT_RESOURCE 12
#define PCI_ANY_ID (~0)
/*
* The pci_dev structure is used to describe PCI devices.
*/
......@@ -491,13 +491,6 @@ struct pbus_set_ranges_data
unsigned long prefetch_start, prefetch_end;
};
struct pci_device_id {
unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */
unsigned int subvendor, subdevice; /* Subsystem ID's or PCI_ANY_ID */
unsigned int class, class_mask; /* (class,subclass,prog-if) triplet */
unsigned long driver_data; /* Data private to the driver */
};
struct pci_driver {
struct list_head node;
char *name;
......
#ifndef __LINUX_USB_H
#define __LINUX_USB_H
#include <linux/mod_devicetable.h>
#include <linux/usb_ch9.h>
#define USB_MAJOR 180
......@@ -314,99 +315,6 @@ static inline int usb_make_path (struct usb_device *dev, char *buf, size_t size)
/*-------------------------------------------------------------------------*/
/*
* Device table entry for "new style" table-driven USB drivers.
* User mode code can read these tables to choose which modules to load.
* Declare the table as a MODULE_DEVICE_TABLE.
*
* A probe() parameter will point to a matching entry from this table.
* Use the driver_info field for each match to hold information tied
* to that match: device quirks, etc.
*
* Terminate the driver's table with an all-zeroes entry.
* Use the flag values to control which fields are compared.
*/
/**
* struct usb_device_id - identifies USB devices for probing and hotplugging
* @match_flags: Bit mask controlling of the other fields are used to match
* against new devices. Any field except for driver_info may be used,
* although some only make sense in conjunction with other fields.
* This is usually set by a USB_DEVICE_*() macro, which sets all
* other fields in this structure except for driver_info.
* @idVendor: USB vendor ID for a device; numbers are assigned
* by the USB forum to its members.
* @idProduct: Vendor-assigned product ID.
* @bcdDevice_lo: Low end of range of vendor-assigned product version numbers.
* This is also used to identify individual product versions, for
* a range consisting of a single device.
* @bcdDevice_hi: High end of version number range. The range of product
* versions is inclusive.
* @bDeviceClass: Class of device; numbers are assigned
* by the USB forum. Products may choose to implement classes,
* or be vendor-specific. Device classes specify behavior of all
* the interfaces on a devices.
* @bDeviceSubClass: Subclass of device; associated with bDeviceClass.
* @bDeviceProtocol: Protocol of device; associated with bDeviceClass.
* @bInterfaceClass: Class of interface; numbers are assigned
* by the USB forum. Products may choose to implement classes,
* or be vendor-specific. Interface classes specify behavior only
* of a given interface; other interfaces may support other classes.
* @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass.
* @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass.
* @driver_info: Holds information used by the driver. Usually it holds
* a pointer to a descriptor understood by the driver, or perhaps
* device flags.
*
* In most cases, drivers will create a table of device IDs by using
* USB_DEVICE(), or similar macros designed for that purpose.
* They will then export it to userspace using MODULE_DEVICE_TABLE(),
* and provide it to the USB core through their usb_driver structure.
*
* See the usb_match_id() function for information about how matches are
* performed. Briefly, you will normally use one of several macros to help
* construct these entries. Each entry you provide will either identify
* one or more specific products, or will identify a class of products
* which have agreed to behave the same. You should put the more specific
* matches towards the beginning of your table, so that driver_info can
* record quirks of specific products.
*/
struct usb_device_id {
/* which fields to match against? */
__u16 match_flags;
/* Used for product specific matches; range is inclusive */
__u16 idVendor;
__u16 idProduct;
__u16 bcdDevice_lo;
__u16 bcdDevice_hi;
/* Used for device class matches */
__u8 bDeviceClass;
__u8 bDeviceSubClass;
__u8 bDeviceProtocol;
/* Used for interface class matches */
__u8 bInterfaceClass;
__u8 bInterfaceSubClass;
__u8 bInterfaceProtocol;
/* not matched against */
unsigned long driver_info;
};
/* Some useful macros to use to create struct usb_device_id */
#define USB_DEVICE_ID_MATCH_VENDOR 0x0001
#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002
#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004
#define USB_DEVICE_ID_MATCH_DEV_HI 0x0008
#define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010
#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020
#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040
#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080
#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100
#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
#define USB_DEVICE_ID_MATCH_DEVICE (USB_DEVICE_ID_MATCH_VENDOR | USB_DEVICE_ID_MATCH_PRODUCT)
#define USB_DEVICE_ID_MATCH_DEV_RANGE (USB_DEVICE_ID_MATCH_DEV_LO | USB_DEVICE_ID_MATCH_DEV_HI)
#define USB_DEVICE_ID_MATCH_DEVICE_AND_VERSION (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_RANGE)
......
......@@ -16,7 +16,8 @@
#define MODULE_ARCH_VERMAGIC ""
#endif
const char vermagic[] __attribute__((section("__vermagic"))) =
UTS_RELEASE " "
MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT MODULE_ARCH_VERMAGIC
"gcc-" __stringify(__GNUC__) "." __stringify(__GNUC_MINOR__);
#define VERMAGIC_STRING \
UTS_RELEASE " " \
MODULE_VERMAGIC_SMP MODULE_VERMAGIC_PREEMPT \
MODULE_ARCH_VERMAGIC \
"gcc-" __stringify(__GNUC__) "." __stringify(__GNUC_MINOR__)
......@@ -3,7 +3,6 @@
#
obj-y := main.o version.o do_mounts.o initramfs.o
obj-$(CONFIG_MODULES) += vermagic.o
# files to be removed upon make clean
clean-files := ../include/linux/compile.h
......
......@@ -30,6 +30,7 @@
#include <linux/moduleparam.h>
#include <linux/errno.h>
#include <linux/err.h>
#include <linux/vermagic.h>
#include <asm/uaccess.h>
#include <asm/semaphore.h>
#include <asm/pgalloc.h>
......@@ -725,6 +726,8 @@ static int obsolete_params(const char *name,
}
#endif /* CONFIG_OBSOLETE_MODPARM */
static const char vermagic[] = VERMAGIC_STRING;
#ifdef CONFIG_MODVERSIONS
static int check_version(Elf_Shdr *sechdrs,
unsigned int versindex,
......@@ -768,6 +771,18 @@ static int check_version(Elf_Shdr *sechdrs,
return 1;
}
static inline int check_modstruct_version(Elf_Shdr *sechdrs,
unsigned int versindex,
struct module *mod)
{
unsigned int i;
struct kernel_symbol_group *ksg;
if (!__find_symbol("struct_module", &ksg, &i, 1))
BUG();
return check_version(sechdrs, versindex, "struct_module", mod, ksg, i);
}
/* First part is kernel version, which we ignore. */
static inline int same_magic(const char *amagic, const char *bmagic)
{
......@@ -786,6 +801,13 @@ static inline int check_version(Elf_Shdr *sechdrs,
return 1;
}
static inline int check_modstruct_version(Elf_Shdr *sechdrs,
unsigned int versindex,
struct module *mod)
{
return 1;
}
static inline int same_magic(const char *amagic, const char *bmagic)
{
return strcmp(amagic, bmagic) == 0;
......@@ -1036,9 +1058,6 @@ static void set_license(struct module *mod, Elf_Shdr *sechdrs, int licenseidx)
}
}
/* From init/vermagic.o */
extern char vermagic[];
/* Allocate and load the module: note that size of section 0 is always
zero, and we rely on this for optional sections. */
static struct module *load_module(void *umod,
......@@ -1185,6 +1204,12 @@ static struct module *load_module(void *umod,
}
mod = (void *)sechdrs[modindex].sh_addr;
/* Check module struct version now, before we try to use module. */
if (!check_modstruct_version(sechdrs, versindex, mod)) {
err = -ENOEXEC;
goto free_hdr;
}
/* This is allowed: modprobe --force will invalidate it. */
if (!vmagindex) {
tainted |= TAINT_FORCED_MODULE;
......@@ -1455,9 +1480,9 @@ static const char *get_ksymbol(struct module *mod,
/* At worse, next value is at end of module */
if (within(addr, mod->module_init, mod->init_size))
nextval = (unsigned long)mod->module_core+mod->core_size;
nextval = (unsigned long)mod->module_init + mod->init_size;
else
nextval = (unsigned long)mod->module_init+mod->init_size;
nextval = (unsigned long)mod->module_core + mod->core_size;
/* Scan for closest preceeding symbol, and next symbol. (ELF
starts real symbols at 1). */
......@@ -1630,3 +1655,9 @@ static int __init symbols_init(void)
}
__initcall(symbols_init);
#ifdef CONFIG_MODVERSIONS
/* Generate the signature for struct module here, too, for modversions. */
void struct_module(struct module *mod) { return; }
EXPORT_SYMBOL(struct_module);
#endif
......@@ -8,11 +8,26 @@
# docproc: Preprocess .tmpl file in order to generate .sgml documentation
# conmakehash: Create arrays for initializing the kernel console tables
host-progs := fixdep split-include conmakehash docproc kallsyms
build-targets := $(host-progs)
host-progs := fixdep split-include conmakehash docproc kallsyms modpost \
mk_elfconfig
build-targets := $(host-progs) empty.o
modpost-objs := modpost.o file2alias.o
# Let clean descend into subdirs
subdir- := lxdialog kconfig
# fixdep is needed to compile other host programs
$(addprefix $(obj)/,$(filter-out fixdep,$(host-progs))): $(obj)/fixdep
# dependencies on generated files need to be listed explicitly
$(obj)/modpost.o $(obj)/file2alias.o: $(obj)/elfconfig.h
quiet_cmd_elfconfig = MKELF $@
cmd_elfconfig = $(obj)/mk_elfconfig < $< > $@
$(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE
$(call if_changed,elfconfig)
targets += $(obj)/elfconfig.h
......@@ -49,15 +49,12 @@ O_TARGET := $(obj)/built-in.o
endif
endif
ifdef CONFIG_MODVERSIONS
modules := $(obj-m)
touch-module = @echo $(@:.o=.ko) > .tmp_versions/$(@F:.o=.mod)
else
modules := $(obj-m:.o=.ko)
endif
# We keep a list of all modules in $(MODVERDIR)
touch-module = @echo $(@:.o=.ko) > $(MODVERDIR)/$(@F:.o=.mod)
__build: $(if $(KBUILD_BUILTIN),$(O_TARGET) $(L_TARGET) $(EXTRA_TARGETS)) \
$(if $(KBUILD_MODULES),$(modules)) \
$(if $(KBUILD_MODULES),$(obj-m)) \
$(subdir-ym) $(build-targets)
@:
......@@ -155,6 +152,8 @@ cmd_cc_i_c = $(CPP) $(c_flags) -o $@ $<
quiet_cmd_cc_o_c = CC $(quiet_modtag) $@
cmd_cc_o_c = $(CC) $(c_flags) -c -o $@ $<
# Built-in and composite module parts
%.o: %.c FORCE
ifdef CONFIG_MODVERSIONS
$(call if_changed_rule,vcc_o_c)
......@@ -162,13 +161,14 @@ else
$(call if_changed_dep,cc_o_c)
endif
# For modversioning, we need to special case single-part modules
# to mark them in $(MODVERDIR)
# Single-part modules are special since we need to mark them in $(MODVERDIR)
ifdef CONFIG_MODVERSIONS
$(single-used-m): %.o: %.c FORCE
$(touch-module)
ifdef CONFIG_MODVERSIONS
$(call if_changed_rule,vcc_o_c)
else
$(call if_changed_dep,cc_o_c)
endif
quiet_cmd_cc_lst_c = MKLST $@
......@@ -199,7 +199,8 @@ cmd_as_o_S = $(CC) $(a_flags) -c -o $@ $<
%.o: %.S FORCE
$(call if_changed_dep,as_o_S)
targets += $(real-objs-y) $(real-objs-m) $(EXTRA_TARGETS) $(MAKECMDGOALS)
targets += $(real-objs-y) $(real-objs-m) $(EXTRA_TARGETS) $(MAKECMDGOALS) \
$(build-targets)
# Build the compiled-in targets
# ---------------------------------------------------------------------------
......@@ -267,29 +268,6 @@ $(multi-used-m) : %.o: $(multi-objs-m) FORCE
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) $(ld_flags) $(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
$(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
# ===========================================================================
# host-progs := bin2hex
......
......@@ -2,33 +2,38 @@
# Installing modules
# ==========================================================================
src := $(obj)
.PHONY: __modinst
__modinst:
.PHONY: modules_install
modules_install:
include scripts/Makefile.lib
include .config
#
include $(obj)/Makefile
__modules := $(shell cd $(MODVERDIR); cat *.mod)
modules := $(patsubst %.o,%.ko,$(wildcard $(__modules:.ko=.o)))
include scripts/Makefile.lib
ifneq ($(filter-out $(modules),$(__modules)),)
$(warning *** Uh-oh, you have stale module entries. You messed with SUBDIRS, do not complain if something goes wrong.)
endif
# ==========================================================================
.PHONY: $(modules)
__modinst: $(modules)
@:
# Modules built within the kernel tree
quiet_cmd_modules_install = INSTALL $(obj-m:.o=.ko)
cmd_modules_install = mkdir -p $(MODLIB)/kernel/$(obj); \
cp $(obj-m:.o=.ko) $(MODLIB)/kernel/$(obj)
cmd_modules_install = mkdir -p $(MODLIB)/kernel/$(@D); \
cp $@ $(MODLIB)/kernel/$(@D)
modules_install: $(subdir-ym)
ifneq ($(obj-m:.o=.ko),)
$(filter-out ../% /%,$(modules)):
$(call cmd,modules_install)
else
@:
endif
# Descending
# ---------------------------------------------------------------------------
# Modules built outside just go into extra
quiet_cmd_modules_install_extra = INSTALL $(obj-m:.o=.ko)
cmd_modules_install_extra = mkdir -p $(MODLIB)/extra; \
cp $@ $(MODLIB)/extra
.PHONY: $(subdir-ym)
$(subdir-ym):
$(Q)$(MAKE) -rR -f scripts/Makefile.modinst obj=$@
$(filter ../% /%,$(modules)):
$(call cmd,modules_install_extra)
......@@ -5,6 +5,7 @@
.PHONY: __modversions
__modversions:
include .config
include scripts/Makefile.lib
#
......@@ -26,9 +27,7 @@ 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 %.ver.o init/vermagic.o FORCE
$(modules): %.ko :%.o %.mod.o FORCE
$(call if_changed,ld_ko_o)
targets += $(modules)
......@@ -36,54 +35,31 @@ targets += $(modules)
# Compile version info for unresolved symbols
quiet_cmd_cc_o_c = CC $@
cmd_cc_o_c = $(CC) $(CFLAGS) -c -o $@ $<
cmd_cc_o_c = $(CC) $(CFLAGS) $(CFLAGS_MODULE) -c -o $@ $<
$(modules:.ko=.ver.o): %.ver.o: %.ver.c FORCE
$(call if_changed,cc_o_c)
# We have a fake dependency on compile.h to make sure that we
# notice if the compiler version changes under us.
targets += $(modules:.ko=.ver.o)
$(modules:.ko=.mod.o): %.mod.o: %.mod.c include/linux/compile.h FORCE
$(call if_changed,cc_o_c)
# Generate C source with version info for unresolved symbols
targets += $(modules:.ko=.mod.o)
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
# All the .mod.c files are generated using the helper "modpost"
$(modules:.ko=.ver.c): %.ver.c: %.o .tmp_all-versions FORCE
$(call if_changed_rule,mkver_o_c)
.PHONY: __modpost
targets += $(modules:.ko=.ver.c))
$(modules:.ko=.mod.c): __modpost ;
# Extract all checksums for all exported symbols
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
quiet_cmd_modpost = MODPOST
cmd_modpost = scripts/modpost $^
.tmp_all-versions: $(export-objs) FORCE
$(call if_changed_rule,gen-all-versions)
__modpost: $(wildcard vmlinux) $(modules:.ko=.o)
$(call if_changed,modpost)
targets += .tmp_all-versions
targets += __modpost
# Add FORCE to the prequisites of a target to force it to be always rebuilt.
# ---------------------------------------------------------------------------
......
/* empty file to figure out endianness / word size */
/* Simple code to turn various tables in an ELF file into alias definitions.
* This deals with kernel datastructures where they should be
* dealt with: in the kernel source.
*
* Copyright 2002-2003 Rusty Russell, IBM Corporation
* 2003 Kai Germaschewski
*
*
* This software may be used and distributed according to the terms
* of the GNU General Public License, incorporated herein by reference.
*/
#include "modpost.h"
/* We use the ELF typedefs, since we can't rely on stdint.h being present. */
#if KERNEL_ELFCLASS == ELFCLASS32
typedef Elf32_Addr kernel_ulong_t;
#else
typedef Elf64_Addr kernel_ulong_t;
#endif
typedef Elf32_Word __u32;
typedef Elf32_Half __u16;
typedef unsigned char __u8;
/* Big exception to the "don't include kernel headers into userspace, which
* even potentially has different endianness and word sizes, since
* we handle those differences explicitly below */
#include "../include/linux/mod_devicetable.h"
#define ADD(str, sep, cond, field) \
do { \
strcat(str, sep); \
if (cond) \
sprintf(str + strlen(str), \
sizeof(field) == 1 ? "%02X" : \
sizeof(field) == 2 ? "%04X" : \
sizeof(field) == 4 ? "%08X" : "", \
field); \
else \
sprintf(str + strlen(str), "*"); \
} while(0)
/* Looks like "usb:vNpNdlNdhNdcNdscNdpNicNiscNipN" */
static int do_usb_entry(const char *filename,
struct usb_device_id *id, char *alias)
{
id->match_flags = TO_NATIVE(id->match_flags);
id->idVendor = TO_NATIVE(id->idVendor);
id->idProduct = TO_NATIVE(id->idProduct);
id->bcdDevice_lo = TO_NATIVE(id->bcdDevice_lo);
id->bcdDevice_hi = TO_NATIVE(id->bcdDevice_hi);
strcpy(alias, "usb:");
ADD(alias, "v", id->match_flags&USB_DEVICE_ID_MATCH_VENDOR,
id->idVendor);
ADD(alias, "p", id->match_flags&USB_DEVICE_ID_MATCH_PRODUCT,
id->idProduct);
ADD(alias, "dl", id->match_flags&USB_DEVICE_ID_MATCH_DEV_LO,
id->bcdDevice_lo);
ADD(alias, "dh", id->match_flags&USB_DEVICE_ID_MATCH_DEV_HI,
id->bcdDevice_hi);
ADD(alias, "dc", id->match_flags&USB_DEVICE_ID_MATCH_DEV_CLASS,
id->bDeviceClass);
ADD(alias, "dsc",
id->match_flags&USB_DEVICE_ID_MATCH_DEV_SUBCLASS,
id->bDeviceSubClass);
ADD(alias, "dp",
id->match_flags&USB_DEVICE_ID_MATCH_DEV_PROTOCOL,
id->bDeviceProtocol);
ADD(alias, "ic",
id->match_flags&USB_DEVICE_ID_MATCH_INT_CLASS,
id->bInterfaceClass);
ADD(alias, "isc",
id->match_flags&USB_DEVICE_ID_MATCH_INT_SUBCLASS,
id->bInterfaceSubClass);
ADD(alias, "ip",
id->match_flags&USB_DEVICE_ID_MATCH_INT_PROTOCOL,
id->bInterfaceProtocol);
return 1;
}
/* Looks like: pci:vNdNsvNsdNcN. */
static int do_pci_entry(const char *filename,
struct pci_device_id *id, char *alias)
{
id->vendor = TO_NATIVE(id->vendor);
id->device = TO_NATIVE(id->device);
id->subvendor = TO_NATIVE(id->subvendor);
id->subdevice = TO_NATIVE(id->subdevice);
id->class = TO_NATIVE(id->class);
id->class_mask = TO_NATIVE(id->class_mask);
strcpy(alias, "pci:");
ADD(alias, "v", id->vendor != PCI_ANY_ID, id->vendor);
ADD(alias, "d", id->device != PCI_ANY_ID, id->device);
ADD(alias, "sv", id->subvendor != PCI_ANY_ID, id->subvendor);
ADD(alias, "sd", id->subdevice != PCI_ANY_ID, id->subdevice);
if (id->class_mask != 0 && id->class_mask != ~0) {
fprintf(stderr,
"*** Warning: Can't handle class_mask in %s:%04X\n",
filename, id->class_mask);
return 0;
}
ADD(alias, "c", id->class_mask == ~0, id->class);
return 1;
}
/* Ignore any prefix, eg. v850 prepends _ */
static inline int sym_is(const char *symbol, const char *name)
{
const char *match;
match = strstr(symbol, name);
if (!match)
return 0;
return match[strlen(symbol)] == '\0';
}
static void do_table(void *symval, unsigned long size,
unsigned long id_size,
void *function,
struct module *mod)
{
unsigned int i;
char alias[500];
int (*do_entry)(const char *, void *entry, char *alias) = function;
if (size % id_size || size < id_size) {
fprintf(stderr, "*** Warning: %s ids %lu bad size "
"(each on %lu)\n", mod->name, size, id_size);
}
/* Leave last one: it's the terminator. */
size -= id_size;
for (i = 0; i < size; i += id_size) {
if (do_entry(mod->name, symval+i, alias)) {
/* Always end in a wildcard, for future extension */
if (alias[strlen(alias)-1] != '*')
strcat(alias, "*");
buf_printf(&mod->dev_table_buf,
"MODULE_ALIAS(\"%s\");\n", alias);
}
}
}
/* Create MODULE_ALIAS() statements.
* At this time, we cannot write the actual output C source yet,
* so we write into the mod->dev_table_buf buffer. */
void handle_moddevtable(struct module *mod, struct elf_info *info,
Elf_Sym *sym, const char *symname)
{
void *symval;
/* We're looking for a section relative symbol */
if (!sym->st_shndx || sym->st_shndx >= info->hdr->e_shnum)
return;
symval = (void *)info->hdr
+ info->sechdrs[sym->st_shndx].sh_offset
+ sym->st_value;
if (sym_is(symname, "__mod_pci_device_table"))
do_table(symval, sym->st_size, sizeof(struct pci_device_id),
do_pci_entry, mod);
else if (sym_is(symname, "__mod_usb_device_table"))
do_table(symval, sym->st_size, sizeof(struct usb_device_id),
do_usb_entry, mod);
}
/* Now add out buffered information to the generated C source */
void add_moddevtable(struct buffer *buf, struct module *mod)
{
buf_printf(buf, "\n");
buf_write(buf, mod->dev_table_buf.p, mod->dev_table_buf.pos);
free(mod->dev_table_buf.p);
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <elf.h>
int
main(int argc, char **argv)
{
unsigned char ei[EI_NIDENT];
union { short s; char c[2]; } endian_test;
if (fread(ei, 1, EI_NIDENT, stdin) != EI_NIDENT) {
fprintf(stderr, "Error: input truncated\n");
return 1;
}
if (memcmp(ei, ELFMAG, SELFMAG) != 0) {
fprintf(stderr, "Error: not ELF\n");
return 1;
}
switch (ei[EI_CLASS]) {
case ELFCLASS32:
printf("#define KERNEL_ELFCLASS ELFCLASS32\n");
break;
case ELFCLASS64:
printf("#define KERNEL_ELFCLASS ELFCLASS64\n");
break;
default:
abort();
}
switch (ei[EI_DATA]) {
case ELFDATA2LSB:
printf("#define KERNEL_ELFDATA ELFDATA2LSB\n");
break;
case ELFDATA2MSB:
printf("#define KERNEL_ELFDATA ELFDATA2MSB\n");
break;
default:
abort();
}
if (sizeof(unsigned long) == 4) {
printf("#define HOST_ELFCLASS ELFCLASS32\n");
} else if (sizeof(unsigned long) == 8) {
printf("#define HOST_ELFCLASS ELFCLASS64\n");
}
endian_test.s = 0x0102;
if (memcmp(endian_test.c, "\x01\x02", 2) == 0)
printf("#define HOST_ELFDATA ELFDATA2MSB\n");
else if (memcmp(endian_test.c, "\x02\x01", 2) == 0)
printf("#define HOST_ELFDATA ELFDATA2LSB\n");
else
abort();
return 0;
}
This diff is collapsed.
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#include <elf.h>
#include "elfconfig.h"
#if KERNEL_ELFCLASS == ELFCLASS32
#define Elf_Ehdr Elf32_Ehdr
#define Elf_Shdr Elf32_Shdr
#define Elf_Sym Elf32_Sym
#define ELF_ST_BIND ELF32_ST_BIND
#else
#define Elf_Ehdr Elf64_Ehdr
#define Elf_Shdr Elf64_Shdr
#define Elf_Sym Elf64_Sym
#define ELF_ST_BIND ELF64_ST_BIND
#endif
#if KERNEL_ELFDATA != HOST_ELFDATA
static void __endian(const void *src, void *dest, unsigned int size)
{
unsigned int i;
for (i = 0; i < size; i++)
((unsigned char*)dest)[i] = ((unsigned char*)src)[size - i-1];
}
#define TO_NATIVE(x) \
({ \
typeof(x) __x; \
__endian(&(x), &(__x), sizeof(__x)); \
__x; \
})
#else /* endianness matches */
#define TO_NATIVE(x) (x)
#endif
struct buffer {
char *p;
int pos;
int size;
};
void __attribute__((format(printf, 2, 3)))
buf_printf(struct buffer *buf, const char *fmt, ...);
void
buf_write(struct buffer *buf, const char *s, int len);
struct module {
struct module *next;
const char *name;
struct symbol *unres;
int seen;
struct buffer dev_table_buf;
};
struct elf_info {
unsigned long size;
Elf_Ehdr *hdr;
Elf_Shdr *sechdrs;
Elf_Sym *symtab_start;
Elf_Sym *symtab_stop;
const char *strtab;
};
void handle_moddevtable(struct module *mod, struct elf_info *info,
Elf_Sym *sym, const char *symname);
void add_moddevtable(struct buffer *buf, struct module *mod);
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