bk://linux-sam.bkbits.net/kbuild sam@mars.ravnborg.org|ChangeSet|20040727223633|30043 sam # This is a BitKeeper generated diff -Nru style patch. # # ChangeSet # 2004/07/28 00:36:33+02:00 sam@mars.ravnborg.org # kbuild: Introduce source symlink in /lib/modules/.../ # # Traditionally when building a kernel the source and the # output files are mixed. # # When building a kernel using the O= syntax to save output # files in a separate directory a way is needed to locate # the kernel source. # The implemented solution is a new symlink 'source' being # added to /lib/modules/.../ # used to locate source for an installed kernel. # The original symlink build points to the directory # containing the output files. # # Please note that when the kernel is build with source and # output files mixed the two symlinks 'build' and 'source' # will point to the same directory, thus no changes # compared to before. # # Two options was considered: # a) Adding a new symlink pointing to the output files "object" # => All external modules have to specify O= to build # => External modules grepping in .config or .h files # in include/asm needs to be updated # => External modules that do grep in source code and # ordinary header files just works # # b) Let the build symlink point to the output files and introduce a new # symlink "source" pointing to the kernel source # => External module can be build without specifying O= # => External modules grepping in .config or .h files # in include/asm just works # => External modules that do grep in source code and # ordinary header files needs to be updated # # Based on the above option b) is considered the least painfull alternative. # # So to sum up: # - If a distro does not use separate output dir => no change # - If a distro uses separate output dir => # - Trivial external module just builds # - Non-trivial (build-wise) external modules are probarly broken # # Without this patch # - If a distro does not use separate output dir => no change # - If a distro uses separate output dir => # - Trivial external modules had to specify O= to build, # and the directory being pointed at was not obvious # - grep in .config or include files in asm/ required # knowledge where to locate output files # # Preferred syntax for building external modules are the following: # # make -C /lib/modules/`uname -r`/build M=`pwd` # # [Substituting 'M=...' with 'SUBDIRS=... modules' give same effect]. # # When the kernel is built using separate output directory the above # invocation of make will invoke the generated Makefile located in the output # directory - that again will invoke the Makefile located in the kernel # source tree root. # # Patch includes contributions from: # Andreas Gruenbacher # # Signed-off-by: Sam Ravnborg # # Makefile # 2004/07/28 00:36:18+02:00 sam@mars.ravnborg.org +6 -2 # New symlink source, and modified old symlink build. # # ChangeSet # 2004/07/27 23:54:53+02:00 sam@mars.ravnborg.org # kbuild: Create Makefile in output directory if != kernel tree # # When building a kernel using the O= syntax to save output # files in a separate output directory now create a small Makefile in # that same dir. # This Makefile allow one to use make in the output directory without # the hassle of going back to the kernel source tree. # The O= option is added by this Makefile stub. # Please note that the Makefile silently overwrite an old one, so changes # will be lost if modified. # If there is a need to tweak a Makefile in the output directory it is recommended # to use the filename 'makefile', which GNU Make will try first. # # Signed-off-by: Sam Ravnborg # # scripts/mkmakefile # 2004/07/27 23:54:36+02:00 sam@mars.ravnborg.org +31 -0 # # scripts/mkmakefile # 2004/07/27 23:54:36+02:00 sam@mars.ravnborg.org +0 -0 # BitKeeper file /home/sam/bk/kbuild/scripts/mkmakefile # # Makefile # 2004/07/27 23:54:36+02:00 sam@mars.ravnborg.org +12 -2 # Create a Makefile in the output directory when building with a separate # output directory # # ChangeSet # 2004/07/27 23:44:01+02:00 sam@mars.ravnborg.org # drivers: move STANDALONE to drivers/base/Kconfig # # Move STANDALONE from init/Kconfig to drivers/base/Kconfig . # This way, it's besides PREVENT_FIRMWARE_BUILD. # # Signed-off-by: Adrian Bunk # Signed-off-by: Sam Ravnborg # # init/Kconfig # 2004/07/27 23:43:46+02:00 sam@mars.ravnborg.org +0 -9 # Removed STANDALONE # # drivers/base/Kconfig # 2004/07/27 23:43:46+02:00 sam@mars.ravnborg.org +9 -0 # Added STANDALONE # # ChangeSet # 2004/07/23 01:29:55+02:00 kkourt@cslab.ece.ntua.gr # kbuild: Two simple kbuild patches # # foo1.patch: spelling correction in Makefile # foo2.patch: replace SUBDIRS with M in Documentation/kbuild/modules.txt # # From: Kornilios Kourtis # Signed-off-by: Sam Ravnborg # # Makefile # 2004/07/22 13:31:04+02:00 kkourt@cslab.ece.ntua.gr +1 -1 # kbuild: Two simple kbuild patches # # Documentation/kbuild/modules.txt # 2004/07/22 13:39:39+02:00 kkourt@cslab.ece.ntua.gr +2 -2 # kbuild: Two simple kbuild patches # # ChangeSet # 2004/07/23 01:28:19+02:00 sam@mars.ravnborg.org # kbuild: Fix up moving of modpost # # A few small issues to fix the moving of modpost. # A few files was missing in the commit and one change needed. # Also bk ignored the files in their new location. # # Signed-off-by: Sam Ravnborg # # scripts/mod/Makefile # 2004/07/23 01:27:54+02:00 sam@mars.ravnborg.org +16 -0 # # scripts/mod/file2alias.c # 2004/07/23 01:27:54+02:00 sam@mars.ravnborg.org +1 -1 # Corrected include path # # scripts/mod/Makefile # 2004/07/23 01:27:54+02:00 sam@mars.ravnborg.org +0 -0 # BitKeeper file /home/sam/bk/kbuild/scripts/mod/Makefile # # scripts/Makefile # 2004/07/23 01:27:54+02:00 sam@mars.ravnborg.org +1 -1 # Renamed directory from modpost (original proposal) to new name mod. # # BitKeeper/etc/ignore # 2004/07/23 01:27:54+02:00 sam@mars.ravnborg.org +3 -4 # Ignore files in scripts/mod # # ChangeSet # 2004/07/23 00:59:36+02:00 bgerst@didntduck.org # kbuild: Move modpost files to a new subdir scripts/mod # # Move modpost and support files to scripts/mod. # Directory named mod by Sam. # # From: Brian Gerst # Signed-off-by: Sam Ravnborg # # scripts/Makefile # 2004/07/18 18:37:25+02:00 bgerst@didntduck.org +3 -16 # kbuild: Move modpost files to a new subdir scripts/mod # # scripts/Makefile.modpost # 2004/07/18 18:45:50+02:00 bgerst@didntduck.org +1 -1 # kbuild: Move modpost files to a new subdir scripts/mod # # scripts/mod/sumversion.c # 2004/07/23 00:51:31+02:00 sam@mars.ravnborg.org +0 -0 # Rename: scripts/sumversion.c -> scripts/mod/sumversion.c # # scripts/mod/modpost.h # 2004/07/23 00:51:17+02:00 sam@mars.ravnborg.org +0 -0 # Rename: scripts/modpost.h -> scripts/mod/modpost.h # # scripts/mod/modpost.c # 2004/07/23 00:51:17+02:00 sam@mars.ravnborg.org +0 -0 # Rename: scripts/modpost.c -> scripts/mod/modpost.c # # scripts/mod/mk_elfconfig.c # 2004/07/23 00:50:55+02:00 sam@mars.ravnborg.org +0 -0 # Rename: scripts/mk_elfconfig.c -> scripts/mod/mk_elfconfig.c # # scripts/mod/file2alias.c # 2004/07/23 00:50:26+02:00 sam@mars.ravnborg.org +0 -0 # Rename: scripts/file2alias.c -> scripts/mod/file2alias.c # # scripts/mod/empty.c # 2004/07/23 00:49:41+02:00 sam@mars.ravnborg.org +0 -0 # Rename: scripts/empty.c -> scripts/mod/empty.c # # ChangeSet # 2004/07/23 00:39:37+02:00 schwab@suse.de # kbuild: scripts/genksyms/parse.c_shipped needs to be rebuilt # # parse.c_shipped has never been regenerated after parse.y has been modified # 4 months ago. # # Signed-off-by: Andreas Schwab # Signed-off-by: Sam Ravnborg # # scripts/genksyms/parse.c_shipped # 2003/10/09 15:28:30+02:00 schwab@suse.de +131 -123 # kbuild: scripts/genksyms/parse.c_shipped needs to be rebuilt # # ChangeSet # 2004/07/23 00:32:23+02:00 sam@mars.ravnborg.org # kbuild: Less intrusive LANG override, fixes menuconfig # # The locale override caused problems for some people with locale setiings # different from 'C'. make menuconfig was looking bad / unuseable. # This patch limit the override of locales to the part where we actually descend the kernel # doing the full build of the kernel. # The speed improvement is the same. # # make menuconfig should now be useable for all locale settings again. # Thanks to Marcel Sebek for pointing out this problem and being # paitent in testing. # # Signed-off-by: Sam Ravnborg # # Makefile # 2004/07/23 00:32:09+02:00 sam@mars.ravnborg.org +11 -12 # Limit LANG override to the part where we descend the kernel tree. # # ChangeSet # 2004/07/21 00:14:47+02:00 sam@mars.ravnborg.org # kbuild: Rebuild .spec file when kernel version changes # # Make a dependency in scripts/package/Makefile to top-level Makefile forcing # .spec file to be generated when kernel version changes. # # Signed-off-by: Sam Ravnborg # # scripts/package/Makefile # 2004/07/21 00:14:31+02:00 sam@mars.ravnborg.org +2 -2 # Add dependency on top-level Makefile to .spec files. # This forces .spec files to be generated when kernel version changes. # # ChangeSet # 2004/07/21 00:03:20+02:00 gdavis@mvista.com # kbuild: Allow `make O= {cscope,tags}` to work # # Allow `make O= {cscope,tags}` to work # # Makefile # 2004/07/19 20:24:43+02:00 gdavis@mvista.com +6 -6 # kbuild: Allow `make O= {cscope,tags}` to work # # ChangeSet # 2004/07/20 23:57:07+02:00 edwardsg@sgi.com # kbuild: build binary rpm from pre-built tree # # Many times it would be nice to quickly package up a kernel tree you're # working on, without having to rebuild the whole thing again from a clean # source tree (like the current rpm-pkg target does). The patch below # adds an "binrpm-pkg" target which uses your existing (already built) # tree. # Modified by me to always do a make and use binrpm-pkg. # # Signed-off-by: Greg Edwards # Signed-off-by: Sam Ravnborg # # scripts/package/mkspec # 2004/07/20 23:10:11+02:00 edwardsg@sgi.com +19 -0 # kbuild: build binary rpm from pre-built tree # # scripts/package/Makefile # 2004/07/20 23:32:10+02:00 edwardsg@sgi.com +18 -0 # kbuild: build binary rpm from pre-built tree # diff -Nru a/Documentation/kbuild/modules.txt b/Documentation/kbuild/modules.txt --- a/Documentation/kbuild/modules.txt 2004-07-27 18:41:47 -07:00 +++ b/Documentation/kbuild/modules.txt 2004-07-27 18:41:47 -07:00 @@ -23,7 +23,7 @@ module outside the kernel is to use the kernel build system, kbuild. Use the following command-line: -make -C path/to/kernel/src SUBDIRS=$PWD modules +make -C path/to/kernel/src M=$PWD modules This requires that a makefile exits made in accordance to Documentation/kbuild/makefiles.txt. Read that file for more details on @@ -65,4 +65,4 @@ # Invokes the kernel build system to come back to the current # directory and build yourmodule.ko. default: - make -C ${KERNEL_SOURCE} SUBDIRS=`pwd` modules + make -C ${KERNEL_SOURCE} M=`pwd` modules diff -Nru a/Makefile b/Makefile --- a/Makefile 2004-07-27 18:41:47 -07:00 +++ b/Makefile 2004-07-27 18:41:47 -07:00 @@ -53,7 +53,7 @@ KBUILD_CHECKSRC = 0 endif -# Use make M=dir to specify direcotry of external module to build +# Use make M=dir to specify directory of external module to build # Old syntax make ... SUBDIRS=$PWD is still supported # Setting the environment variable KBUILD_EXTMOD take precedence ifdef SUBDIRS @@ -130,16 +130,6 @@ _all: modules endif -# Make sure we're not wasting cpu-cycles doing locale handling, yet do make -# sure error messages appear in the user-desired language -ifdef LC_ALL -LANG := $(LC_ALL) -LC_ALL := -endif -LC_COLLATE := C -LC_CTYPE := C -export LANG LC_ALL LC_COLLATE LC_CTYPE - srctree := $(if $(KBUILD_SRC),$(KBUILD_SRC),$(CURDIR)) TOPDIR := $(srctree) # FIXME - TOPDIR is obsolete, use srctree/objtree @@ -621,25 +611,44 @@ $(sort $(vmlinux-objs)) arch/$(ARCH)/kernel/vmlinux.lds.s: $(vmlinux-dirs) ; -# Handle descending into subdirectories listed in $(vmlinux-dirs) +# Handle descending into subdirectories listed in $(vmlinux-dirs) +# Preset locale variables to speed up the build process. Limit locale +# tweaks to this spot to avoid wrong language settings when running +# make menuconfig etc. +# Error messages still appears in the original language .PHONY: $(vmlinux-dirs) $(vmlinux-dirs): prepare-all scripts - $(Q)$(MAKE) $(build)=$@ + $(Q)if [ ! -z $$LC_ALL ]; then \ + export LANG=$$LC_ALL; \ + export LC_ALL= ; \ + fi; \ + export LC_COLLATE=C; export LC_CTYPE=C; \ + $(MAKE) $(build)=$@ # Things we need to do before we recursively start building the kernel # or the modules are listed in "prepare-all". # A multi level approach is used. prepare1 is updated first, then prepare0. # prepare-all is the collection point for the prepare targets. -.PHONY: prepare-all prepare prepare0 prepare1 +.PHONY: prepare-all prepare prepare0 prepare1 prepare2 + +# prepare 2 generate Makefile to be placed in output directory, if +# using a seperate output directory. This allows convinient use +# of make in output directory +prepare2: + $(Q)if [ ! $(srctree) -ef $(objtree) ]; then \ + $(CONFIG_SHELL) $(srctree)/scripts/mkmakefile \ + $(srctree) $(objtree) $(VERSION) $(PATCHLEVEL) \ + > $(objtree)/Makefile; \ + fi # prepare1 is used to check if we are building in a separate output directory, # and if so do: # 1) Check that make has not been executed in the kernel src $(srctree) # 2) Create the include2 directory, used for the second asm symlink -prepare1: +prepare1: prepare2 ifneq ($(KBUILD_SRC),) @echo ' Using $(srctree) as source for kernel' $(Q)if [ -h $(srctree)/include/asm -o -f $(srctree)/.config ]; then \ @@ -760,9 +769,13 @@ sleep 1; \ fi @rm -rf $(MODLIB)/kernel - @rm -f $(MODLIB)/build + @rm -f $(MODLIB)/source @mkdir -p $(MODLIB)/kernel - @ln -s $(TOPDIR) $(MODLIB)/build + @ln -s $(srctree) $(MODLIB)/source + @if [ ! $(objtree) -ef $(MODLIB)/build ]; then \ + rm -f $(MODLIB)/build ; \ + ln -s $(objtree) $(MODLIB)/build ; \ + fi $(Q)$(MAKE) -rR -f $(srctree)/scripts/Makefile.modinst # If System.map exists, run depmod. This deliberately does not have a @@ -1009,19 +1022,19 @@ # --------------------------------------------------------------------------- define all-sources - ( find . $(RCS_FIND_IGNORE) \ + ( find $(srctree) $(RCS_FIND_IGNORE) \ \( -name include -o -name arch \) -prune -o \ -name '*.[chS]' -print; \ - find arch/$(ARCH) $(RCS_FIND_IGNORE) \ + find $(srctree)/arch/$(ARCH) $(RCS_FIND_IGNORE) \ -name '*.[chS]' -print; \ - find security/selinux/include $(RCS_FIND_IGNORE) \ + find $(srctree)/security/selinux/include $(RCS_FIND_IGNORE) \ -name '*.[chS]' -print; \ - find include $(RCS_FIND_IGNORE) \ + find $(srctree)/include $(RCS_FIND_IGNORE) \ \( -name config -o -name 'asm-*' \) -prune \ -o -name '*.[chS]' -print; \ - find include/asm-$(ARCH) $(RCS_FIND_IGNORE) \ + find $(srctree)/include/asm-$(ARCH) $(RCS_FIND_IGNORE) \ -name '*.[chS]' -print; \ - find include/asm-generic $(RCS_FIND_IGNORE) \ + find $(srctree)/include/asm-generic $(RCS_FIND_IGNORE) \ -name '*.[chS]' -print ) endef diff -Nru a/drivers/base/Kconfig b/drivers/base/Kconfig --- a/drivers/base/Kconfig 2004-07-27 18:41:47 -07:00 +++ b/drivers/base/Kconfig 2004-07-27 18:41:47 -07:00 @@ -1,5 +1,14 @@ menu "Generic Driver Options" +config STANDALONE + bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL + default y + help + Select this option if you don't have magic firmware for drivers that + need it. + + If unsure, say Y. + config PREVENT_FIRMWARE_BUILD bool "Prevent firmware from being built" default y diff -Nru a/init/Kconfig b/init/Kconfig --- a/init/Kconfig 2004-07-27 18:41:47 -07:00 +++ b/init/Kconfig 2004-07-27 18:41:47 -07:00 @@ -41,15 +41,6 @@ If unsure, say Y -config STANDALONE - bool "Select only drivers that don't need compile-time external firmware" if EXPERIMENTAL - default y - help - Select this option if you don't have magic firmware for drivers that - need it. - - If unsure, say Y. - config BROKEN bool depends on !CLEAN_COMPILE diff -Nru a/scripts/Makefile b/scripts/Makefile --- a/scripts/Makefile 2004-07-27 18:41:47 -07:00 +++ b/scripts/Makefile 2004-07-27 18:41:47 -07:00 @@ -5,24 +5,11 @@ # docproc: Preprocess .tmpl file in order to generate .sgml docs # conmakehash: Create arrays for initializing the kernel console tables -host-progs := conmakehash kallsyms modpost mk_elfconfig pnmtologo bin2c -always := $(host-progs) empty.o - -modpost-objs := modpost.o file2alias.o sumversion.o +host-progs := conmakehash kallsyms pnmtologo bin2c +always := $(host-progs) subdir-$(CONFIG_MODVERSIONS) += genksyms +subdir-y += mod # Let clean descend into subdirs subdir- += basic lxdialog kconfig package - -# dependencies on generated files need to be listed explicitly - -$(obj)/modpost.o $(obj)/file2alias.o $(obj)/sumversion.o: $(obj)/elfconfig.h - -quiet_cmd_elfconfig = MKELF $@ - cmd_elfconfig = $(obj)/mk_elfconfig $(ARCH) < $< > $@ - -$(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE - $(call if_changed,elfconfig) - -targets += elfconfig.h diff -Nru a/scripts/Makefile.modpost b/scripts/Makefile.modpost --- a/scripts/Makefile.modpost 2004-07-27 18:41:47 -07:00 +++ b/scripts/Makefile.modpost 2004-07-27 18:41:47 -07:00 @@ -50,7 +50,7 @@ # Step 2), invoke modpost # Includes step 3,4 quiet_cmd_modpost = MODPOST - cmd_modpost = scripts/modpost \ + cmd_modpost = scripts/mod/modpost \ $(if $(KBUILD_EXTMOD),-i,-o) $(symverfile) \ $(filter-out FORCE,$^) diff -Nru a/scripts/empty.c b/scripts/empty.c --- a/scripts/empty.c 2004-07-27 18:41:47 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1 +0,0 @@ -/* empty file to figure out endianness / word size */ diff -Nru a/scripts/file2alias.c b/scripts/file2alias.c --- a/scripts/file2alias.c 2004-07-27 18:41:47 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,282 +0,0 @@ -/* 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); - - /* - * Some modules (visor) have empty slots as placeholder for - * run-time specification that results in catch-all alias - */ - if (!(id->idVendor | id->bDeviceClass | id->bInterfaceClass)) - return 1; - - 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: ieee1394:venNmoNspNverN */ -static int do_ieee1394_entry(const char *filename, - struct ieee1394_device_id *id, char *alias) -{ - id->match_flags = TO_NATIVE(id->match_flags); - id->vendor_id = TO_NATIVE(id->vendor_id); - id->model_id = TO_NATIVE(id->model_id); - id->specifier_id = TO_NATIVE(id->specifier_id); - id->version = TO_NATIVE(id->version); - - strcpy(alias, "ieee1394:"); - ADD(alias, "ven", id->match_flags & IEEE1394_MATCH_VENDOR_ID, - id->vendor_id); - ADD(alias, "mo", id->match_flags & IEEE1394_MATCH_MODEL_ID, - id->model_id); - ADD(alias, "sp", id->match_flags & IEEE1394_MATCH_SPECIFIER_ID, - id->specifier_id); - ADD(alias, "ver", id->match_flags & IEEE1394_MATCH_VERSION, - id->version); - - return 1; -} - -/* Looks like: pci:vNdNsvNsdNbcNscNiN. */ -static int do_pci_entry(const char *filename, - struct pci_device_id *id, char *alias) -{ - /* Class field can be divided into these three. */ - unsigned char baseclass, subclass, interface, - baseclass_mask, subclass_mask, interface_mask; - - 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); - - baseclass = (id->class) >> 16; - baseclass_mask = (id->class_mask) >> 16; - subclass = (id->class) >> 8; - subclass_mask = (id->class_mask) >> 8; - interface = id->class; - interface_mask = id->class_mask; - - if ((baseclass_mask != 0 && baseclass_mask != 0xFF) - || (subclass_mask != 0 && subclass_mask != 0xFF) - || (interface_mask != 0 && interface_mask != 0xFF)) { - fprintf(stderr, - "*** Warning: Can't handle masks in %s:%04X\n", - filename, id->class_mask); - return 0; - } - - ADD(alias, "bc", baseclass_mask == 0xFF, baseclass); - ADD(alias, "sc", subclass_mask == 0xFF, subclass); - ADD(alias, "i", interface_mask == 0xFF, interface); - return 1; -} - -/* looks like: "ccw:tNmNdtNdmN" */ -static int do_ccw_entry(const char *filename, - struct ccw_device_id *id, char *alias) -{ - id->match_flags = TO_NATIVE(id->match_flags); - id->cu_type = TO_NATIVE(id->cu_type); - id->cu_model = TO_NATIVE(id->cu_model); - id->dev_type = TO_NATIVE(id->dev_type); - id->dev_model = TO_NATIVE(id->dev_model); - - strcpy(alias, "ccw:"); - ADD(alias, "t", id->match_flags&CCW_DEVICE_ID_MATCH_CU_TYPE, - id->cu_type); - ADD(alias, "m", id->match_flags&CCW_DEVICE_ID_MATCH_CU_MODEL, - id->cu_model); - ADD(alias, "dt", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE, - id->dev_type); - ADD(alias, "dm", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE, - id->dev_model); - return 1; -} - -/* looks like: "pnp:dD" */ -static int do_pnp_entry(const char *filename, - struct pnp_device_id *id, char *alias) -{ - sprintf(alias, "pnp:d%s", id->id); - return 1; -} - -/* looks like: "pnp:cCdD..." */ -static int do_pnp_card_entry(const char *filename, - struct pnp_card_device_id *id, char *alias) -{ - int i; - - sprintf(alias, "pnp:c%s", id->id); - for (i = 0; i < PNP_MAX_DEVICES; i++) { - if (! *id->devs[i].id) - break; - sprintf(alias + strlen(alias), "d%s", id->devs[i].id); - } - 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); - else if (sym_is(symname, "__mod_ieee1394_device_table")) - do_table(symval, sym->st_size, sizeof(struct ieee1394_device_id), - do_ieee1394_entry, mod); - else if (sym_is(symname, "__mod_ccw_device_table")) - do_table(symval, sym->st_size, sizeof(struct ccw_device_id), - do_ccw_entry, mod); - else if (sym_is(symname, "__mod_pnp_device_table")) - do_table(symval, sym->st_size, sizeof(struct pnp_device_id), - do_pnp_entry, mod); - else if (sym_is(symname, "__mod_pnp_card_device_table")) - do_table(symval, sym->st_size, sizeof(struct pnp_card_device_id), - do_pnp_card_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); -} diff -Nru a/scripts/genksyms/parse.c_shipped b/scripts/genksyms/parse.c_shipped --- a/scripts/genksyms/parse.c_shipped 2004-07-27 18:41:47 -07:00 +++ b/scripts/genksyms/parse.c_shipped 2004-07-27 18:41:47 -07:00 @@ -156,7 +156,7 @@ 71, 94, 92, 82, 0, 0, 62, 0, 63, 0, 62, 63, 0, 64, 0, 65, 0, 5, 0, 16, 0, 20, 0, 11, 0, 13, 0, 66, 0, 70, - 0, 27, 46, 65, 47, 0, 21, 36, 0, 23, + 0, 27, 46, 62, 47, 0, 21, 36, 0, 23, 36, 0, 10, 36, 0, 21, 36, 84, 0, 23, 36, 84, 0, 10, 36, 31, 0, 10, 31, 0, 21, 84, 0, 23, 84, 0, 7, 0, 18, 0, @@ -291,142 +291,150 @@ }; static const short yypact[] = {-32768, - 19,-32768, 175,-32768, 32,-32768,-32768,-32768,-32768,-32768, + 15,-32768, 197,-32768, 23,-32768,-32768,-32768,-32768,-32768, -18,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, --32768, -30,-32768, -26,-32768,-32768,-32768, -32, -10, -2, --32768,-32768,-32768,-32768, 2, 428,-32768,-32768,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768, 34, 12, 79, --32768, 428, 12,-32768, 455, 33,-32768,-32768, 15, 14, - 35, 29,-32768, 2, -14, -21,-32768,-32768,-32768, 67, - 31, 37, 127,-32768,-32768, 2,-32768, 54, 60, 66, - 69,-32768, 14,-32768,-32768, 2,-32768,-32768,-32768, 84, --32768, 219,-32768,-32768, 70,-32768, 20, 91, 72, 84, - -20, 74, 81,-32768,-32768,-32768, 86,-32768, 102,-32768, - 106,-32768,-32768,-32768,-32768,-32768, 109, 108, 348, 112, - 126, 117,-32768,-32768, 118,-32768, 122,-32768,-32768,-32768, --32768, 262,-32768, 31,-32768, 131,-32768,-32768,-32768,-32768, --32768, 7, 120,-32768, -9,-32768,-32768, 392,-32768,-32768, - 125, 130,-32768,-32768, 132,-32768, 159,-32768,-32768, 305, --32768,-32768,-32768,-32768,-32768,-32768, 160, 161,-32768,-32768, - 174,-32768 +-32768, -28,-32768, -25,-32768,-32768,-32768, -26, -22, -12, +-32768,-32768,-32768,-32768, 49, 493,-32768,-32768,-32768,-32768, +-32768,-32768,-32768,-32768,-32768,-32768,-32768, 27, -8, 101, +-32768, 493, -8,-32768, 493, 10,-32768,-32768, 11, 9, + 18, 26,-32768, 49, -15, -13,-32768,-32768,-32768, 25, + 24, 48, 149,-32768,-32768, 49,-32768, 414, 39, 40, + 47,-32768, 9,-32768,-32768, 49,-32768,-32768,-32768, 66, +-32768, 241,-32768,-32768, 50,-32768, 5, 65, 42, 66, + 17, 56, 55,-32768,-32768,-32768, 60,-32768, 75,-32768, + 80,-32768,-32768,-32768,-32768,-32768, 81, 82, 370, 85, + 98, 89,-32768,-32768, 88,-32768, 91,-32768,-32768,-32768, +-32768, 284,-32768, 24,-32768, 103,-32768,-32768,-32768,-32768, +-32768, 8, 43,-32768, 30,-32768,-32768, 457,-32768,-32768, + 92, 93,-32768,-32768, 95,-32768, 96,-32768,-32768, 327, +-32768,-32768,-32768,-32768,-32768,-32768, 99, 104,-32768,-32768, + 148,-32768 }; static const short yypgoto[] = {-32768, - 208,-32768,-32768,-32768, 158,-32768,-32768, 128, 0, -90, - -36,-32768, 157,-32768, -70,-32768,-32768, -51, -31,-32768, - -40,-32768, -125,-32768,-32768, 65, -97,-32768,-32768,-32768, --32768, -19,-32768,-32768, 143,-32768,-32768, 83, 124, 141, + 152,-32768,-32768,-32768, 119,-32768,-32768, 94, 0, -55, + -35,-32768,-32768,-32768, -69,-32768,-32768, -56, -30,-32768, + -76,-32768, -122,-32768,-32768, 29, -62,-32768,-32768,-32768, +-32768, -17,-32768,-32768, 105,-32768,-32768, 52, 86, 83, -32768,-32768,-32768 }; -#define YYLAST 495 +#define YYLAST 533 -static const short yytable[] = { 67, - 99, 119, 35, 65, 54, 49, 152, 155, 84, 53, - 91, 131, 47, 55, 88, 80, 89, 48, 171, 50, - 125, 9, 159, 50, 92, 132, 99, 81, 99, 69, - 18, 114, 87, 77, 168, 56, 160, 58, -89, 27, - 57, 119, 140, 31, 157, 158, 156, 59, 143, 60, - 58, 76, 142, -89, 60, 126, 127, 119, 129, 96, - 59, 50, 60, 99, 68, 97, 95, 60, 79, 119, - 96, 143, 143, 86, 45, 46, 97, 85, 60, 70, - 106, 98, 67, 6, 7, 8, 9, 10, 11, 12, +static const short yytable[] = { 78, + 67, 99, 35, 84, 65, 125, 54, 49, 155, 152, + 53, 80, 47, 88, 171, 89, 9, 48, 91, 55, + 127, 50, 129, 56, 50, 18, 114, 99, 81, 99, + 57, 69, 92, 87, 27, 77, 119, 168, 31, -89, + 126, 50, 67, 140, 96, 79, 58, 156, 131, 143, + 97, 76, 60, 142, -89, 60, 59, 68, 60, 95, + 85, 159, 132, 96, 99, 45, 46, 93, 94, 97, + 86, 60, 143, 143, 98, 160, 119, 126, 140, 157, + 158, 96, 156, 67, 58, 111, 112, 97, 142, 60, + 60, 106, 119, 113, 59, 116, 60, 128, 133, 134, + 98, 70, 93, 88, 119, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 135, 24, 25, 26, 27, 28, 139, 136, + 31, 146, 147, 148, 149, 154, -19, 150, 163, 164, + 32, 165, 166, -19, -103, 169, -19, 172, -19, 107, + 170, -19, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 110, 24, 25, 26, 27, 28, 111, 126, 31, 93, - 94, 96, 112, 116, -19, 113, 133, 97, 32, 60, - 98, -19, -103, 128, -19, 134, -19, 107, 93, -19, - 88, 6, 7, 8, 9, 10, 11, 12, 13, 14, - 15, 16, 17, 18, 19, 20, 21, 22, 135, 24, - 25, 26, 27, 28, 139, 140, 31, 136, 146, 156, - 147, 148, -19, 154, 149, 142, 32, 60, 150, -19, - -104, 163, -19, 172, -19, 5, 164, -19, 165, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, - 27, 28, 29, 30, 31, 166, 169, 170, 4, 75, - -19, 78, 162, 115, 32, 108, 153, -19, 124, 118, - -19, 0, -19, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, - 130, 24, 25, 26, 27, 28, 0, 0, 31, 0, - 0, 0, 0, -82, 0, 0, 0, 0, 32, 0, - 0, 0, 151, 0, 0, -82, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 0, 24, 25, 26, 27, 28, 0, - 0, 31, 0, 0, 0, 0, -82, 0, 0, 0, - 0, 32, 0, 0, 0, 167, 0, 0, -82, 6, - 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, - 17, 18, 19, 20, 21, 22, 0, 24, 25, 26, - 27, 28, 0, 0, 31, 0, 0, 0, 0, -82, - 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, - 0, -82, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, - 24, 25, 26, 27, 28, 0, 0, 31, 0, 0, - 0, 0, 0, 140, 0, 0, 0, 141, 0, 0, - 0, 0, 0, 142, 0, 60, 6, 7, 8, 9, - 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, - 20, 21, 22, 0, 24, 25, 26, 27, 28, 0, - 0, 31, 0, 0, 0, 0, 161, 0, 0, 0, - 0, 32, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 22, 0, - 24, 25, 26, 27, 28, 0, 0, 31, 0, 0, - 7, 8, 9, 10, 11, 0, 13, 32, 15, 16, - 0, 18, 19, 20, 0, 22, 0, 24, 25, 26, - 27, 28, 0, 0, 31, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 32 + 75, 24, 25, 26, 27, 28, 162, 108, 31, 115, + 124, 0, 130, 0, -19, 153, 0, 0, 32, 0, + 0, -19, -104, 0, -19, 0, -19, 5, 0, -19, + 0, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, + 25, 26, 27, 28, 29, 30, 31, 0, 0, 0, + 0, 0, -19, 0, 0, 0, 32, 0, 0, -19, + 0, 118, -19, 0, -19, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, 22, 0, 24, 25, 26, 27, 28, 0, 0, + 31, 0, 0, 0, 0, -82, 0, 0, 0, 0, + 32, 0, 0, 0, 151, 0, 0, -82, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 0, 24, 25, 26, 27, + 28, 0, 0, 31, 0, 0, 0, 0, -82, 0, + 0, 0, 0, 32, 0, 0, 0, 167, 0, 0, + -82, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 0, 24, + 25, 26, 27, 28, 0, 0, 31, 0, 0, 0, + 0, -82, 0, 0, 0, 0, 32, 0, 0, 0, + 0, 0, 0, -82, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, + 22, 0, 24, 25, 26, 27, 28, 0, 0, 31, + 0, 0, 0, 0, 0, 140, 0, 0, 0, 141, + 0, 0, 0, 0, 0, 142, 0, 60, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, 22, 0, 24, 25, 26, 27, + 28, 0, 0, 31, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, + 110, 6, 7, 8, 9, 10, 11, 12, 13, 14, + 15, 16, 17, 18, 19, 20, 21, 22, 0, 24, + 25, 26, 27, 28, 0, 0, 31, 0, 0, 0, + 0, 161, 0, 0, 0, 0, 32, 6, 7, 8, + 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, + 19, 20, 21, 22, 0, 24, 25, 26, 27, 28, + 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 32 }; -static const short yycheck[] = { 36, - 71, 92, 3, 35, 24, 36, 132, 1, 60, 36, - 32, 32, 31, 46, 29, 1, 31, 36, 0, 50, - 1, 8, 32, 50, 46, 46, 97, 59, 99, 49, - 17, 83, 64, 53, 160, 46, 46, 36, 32, 26, - 43, 132, 36, 30, 142, 143, 40, 46, 119, 48, - 36, 52, 46, 47, 48, 36, 97, 148, 99, 40, - 46, 50, 48, 134, 31, 46, 36, 48, 36, 160, - 40, 142, 143, 45, 43, 44, 46, 43, 48, 1, - 44, 51, 119, 5, 6, 7, 8, 9, 10, 11, - 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 47, 23, 24, 25, 26, 27, 47, 36, 30, 43, - 44, 40, 47, 30, 36, 47, 43, 46, 40, 48, - 51, 43, 44, 33, 46, 45, 48, 1, 43, 51, - 29, 5, 6, 7, 8, 9, 10, 11, 12, 13, - 14, 15, 16, 17, 18, 19, 20, 21, 43, 23, - 24, 25, 26, 27, 47, 36, 30, 49, 47, 40, - 35, 45, 36, 33, 47, 46, 40, 48, 47, 43, - 44, 47, 46, 0, 48, 1, 47, 51, 47, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, - 26, 27, 28, 29, 30, 47, 47, 47, 1, 52, - 36, 55, 148, 86, 40, 73, 134, 43, 95, 1, - 46, -1, 48, 5, 6, 7, 8, 9, 10, 11, +static const short yycheck[] = { 55, + 36, 71, 3, 60, 35, 1, 24, 36, 1, 132, + 36, 1, 31, 29, 0, 31, 8, 36, 32, 46, + 97, 50, 99, 46, 50, 17, 83, 97, 59, 99, + 43, 49, 46, 64, 26, 53, 92, 160, 30, 32, + 36, 50, 78, 36, 40, 36, 36, 40, 32, 119, + 46, 52, 48, 46, 47, 48, 46, 31, 48, 36, + 43, 32, 46, 40, 134, 43, 44, 43, 44, 46, + 45, 48, 142, 143, 51, 46, 132, 36, 36, 142, + 143, 40, 40, 119, 36, 47, 47, 46, 46, 48, + 48, 44, 148, 47, 46, 30, 48, 33, 43, 45, + 51, 1, 43, 29, 160, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 43, 23, 24, 25, 26, 27, 47, 49, + 30, 47, 35, 45, 47, 33, 36, 47, 47, 47, + 40, 47, 47, 43, 44, 47, 46, 0, 48, 1, + 47, 51, 1, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, - 100, 23, 24, 25, 26, 27, -1, -1, 30, -1, - -1, -1, -1, 35, -1, -1, -1, -1, 40, -1, - -1, -1, 1, -1, -1, 47, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, -1, 23, 24, 25, 26, 27, -1, - -1, 30, -1, -1, -1, -1, 35, -1, -1, -1, - -1, 40, -1, -1, -1, 1, -1, -1, 47, 5, - 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, - 16, 17, 18, 19, 20, 21, -1, 23, 24, 25, - 26, 27, -1, -1, 30, -1, -1, -1, -1, 35, - -1, -1, -1, -1, 40, -1, -1, -1, -1, -1, - -1, 47, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, -1, - 23, 24, 25, 26, 27, -1, -1, 30, -1, -1, - -1, -1, -1, 36, -1, -1, -1, 40, -1, -1, - -1, -1, -1, 46, -1, 48, 5, 6, 7, 8, - 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, - 19, 20, 21, -1, 23, 24, 25, 26, 27, -1, - -1, 30, -1, -1, -1, -1, 35, -1, -1, -1, - -1, 40, 5, 6, 7, 8, 9, 10, 11, 12, - 13, 14, 15, 16, 17, 18, 19, 20, 21, -1, - 23, 24, 25, 26, 27, -1, -1, 30, -1, -1, - 6, 7, 8, 9, 10, -1, 12, 40, 14, 15, - -1, 17, 18, 19, -1, 21, -1, 23, 24, 25, - 26, 27, -1, -1, 30, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 40 + 52, 23, 24, 25, 26, 27, 148, 73, 30, 86, + 95, -1, 100, -1, 36, 134, -1, -1, 40, -1, + -1, 43, 44, -1, 46, -1, 48, 1, -1, 51, + -1, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, + 24, 25, 26, 27, 28, 29, 30, -1, -1, -1, + -1, -1, 36, -1, -1, -1, 40, -1, -1, 43, + -1, 1, 46, -1, 48, 5, 6, 7, 8, 9, + 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, -1, 23, 24, 25, 26, 27, -1, -1, + 30, -1, -1, -1, -1, 35, -1, -1, -1, -1, + 40, -1, -1, -1, 1, -1, -1, 47, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, -1, 23, 24, 25, 26, + 27, -1, -1, 30, -1, -1, -1, -1, 35, -1, + -1, -1, -1, 40, -1, -1, -1, 1, -1, -1, + 47, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, -1, 23, + 24, 25, 26, 27, -1, -1, 30, -1, -1, -1, + -1, 35, -1, -1, -1, -1, 40, -1, -1, -1, + -1, -1, -1, 47, 5, 6, 7, 8, 9, 10, + 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, + 21, -1, 23, 24, 25, 26, 27, -1, -1, 30, + -1, -1, -1, -1, -1, 36, -1, -1, -1, 40, + -1, -1, -1, -1, -1, 46, -1, 48, 5, 6, + 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, -1, 23, 24, 25, 26, + 27, -1, -1, 30, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 40, -1, -1, -1, -1, -1, -1, + 47, 5, 6, 7, 8, 9, 10, 11, 12, 13, + 14, 15, 16, 17, 18, 19, 20, 21, -1, 23, + 24, 25, 26, 27, -1, -1, 30, -1, -1, -1, + -1, 35, -1, -1, -1, -1, 40, 5, 6, 7, + 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, + 18, 19, 20, 21, -1, 23, 24, 25, 26, 27, + -1, -1, 30, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 40 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ #line 3 "/usr/lib/bison.simple" diff -Nru a/scripts/mk_elfconfig.c b/scripts/mk_elfconfig.c --- a/scripts/mk_elfconfig.c 2004-07-27 18:41:47 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,65 +0,0 @@ -#include -#include -#include -#include - -int -main(int argc, char **argv) -{ - unsigned char ei[EI_NIDENT]; - union { short s; char c[2]; } endian_test; - - if (argc != 2) { - fprintf(stderr, "Error: no arch\n"); - } - 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(); - - if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0)) - printf("#define MODULE_SYMBOL_PREFIX \"_\"\n"); - else - printf("#define MODULE_SYMBOL_PREFIX \"\"\n"); - - return 0; -} - diff -Nru a/scripts/mkmakefile b/scripts/mkmakefile --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/scripts/mkmakefile 2004-07-27 18:41:47 -07:00 @@ -0,0 +1,31 @@ +#!/bin/sh +# Generates a small Makefile used in the root of the output +# directory, to allow make to be started from there. +# The Makefile also allow for more convinient build of external modules + +# Usage +# $1 - Kernel src directory +# $2 - Output directory +# $3 - version +# $4 - patchlevel + + +cat << EOF +# Automatically generated by $0: don't edit + +VERSION = $3 +PATCHLEVEL = $4 + +KERNELSRC := $1 +KERNELOUTPUT := $2 + +MAKEFLAGS += --no-print-directory + +all: + \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) + +%:: + \$(MAKE) -C \$(KERNELSRC) O=\$(KERNELOUTPUT) \$@ + +EOF + diff -Nru a/scripts/mod/Makefile b/scripts/mod/Makefile --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/scripts/mod/Makefile 2004-07-27 18:41:47 -07:00 @@ -0,0 +1,16 @@ +host-progs := modpost mk_elfconfig +always := $(host-progs) empty.o + +modpost-objs := modpost.o file2alias.o sumversion.o + +# dependencies on generated files need to be listed explicitly + +$(obj)/modpost.o $(obj)/file2alias.o $(obj)/sumversion.o: $(obj)/elfconfig.h + +quiet_cmd_elfconfig = MKELF $@ + cmd_elfconfig = $(obj)/mk_elfconfig $(ARCH) < $< > $@ + +$(obj)/elfconfig.h: $(obj)/empty.o $(obj)/mk_elfconfig FORCE + $(call if_changed,elfconfig) + +targets += elfconfig.h diff -Nru a/scripts/mod/empty.c b/scripts/mod/empty.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/scripts/mod/empty.c 2004-07-27 18:41:47 -07:00 @@ -0,0 +1 @@ +/* empty file to figure out endianness / word size */ diff -Nru a/scripts/mod/file2alias.c b/scripts/mod/file2alias.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/scripts/mod/file2alias.c 2004-07-27 18:41:47 -07:00 @@ -0,0 +1,282 @@ +/* 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); + + /* + * Some modules (visor) have empty slots as placeholder for + * run-time specification that results in catch-all alias + */ + if (!(id->idVendor | id->bDeviceClass | id->bInterfaceClass)) + return 1; + + 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: ieee1394:venNmoNspNverN */ +static int do_ieee1394_entry(const char *filename, + struct ieee1394_device_id *id, char *alias) +{ + id->match_flags = TO_NATIVE(id->match_flags); + id->vendor_id = TO_NATIVE(id->vendor_id); + id->model_id = TO_NATIVE(id->model_id); + id->specifier_id = TO_NATIVE(id->specifier_id); + id->version = TO_NATIVE(id->version); + + strcpy(alias, "ieee1394:"); + ADD(alias, "ven", id->match_flags & IEEE1394_MATCH_VENDOR_ID, + id->vendor_id); + ADD(alias, "mo", id->match_flags & IEEE1394_MATCH_MODEL_ID, + id->model_id); + ADD(alias, "sp", id->match_flags & IEEE1394_MATCH_SPECIFIER_ID, + id->specifier_id); + ADD(alias, "ver", id->match_flags & IEEE1394_MATCH_VERSION, + id->version); + + return 1; +} + +/* Looks like: pci:vNdNsvNsdNbcNscNiN. */ +static int do_pci_entry(const char *filename, + struct pci_device_id *id, char *alias) +{ + /* Class field can be divided into these three. */ + unsigned char baseclass, subclass, interface, + baseclass_mask, subclass_mask, interface_mask; + + 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); + + baseclass = (id->class) >> 16; + baseclass_mask = (id->class_mask) >> 16; + subclass = (id->class) >> 8; + subclass_mask = (id->class_mask) >> 8; + interface = id->class; + interface_mask = id->class_mask; + + if ((baseclass_mask != 0 && baseclass_mask != 0xFF) + || (subclass_mask != 0 && subclass_mask != 0xFF) + || (interface_mask != 0 && interface_mask != 0xFF)) { + fprintf(stderr, + "*** Warning: Can't handle masks in %s:%04X\n", + filename, id->class_mask); + return 0; + } + + ADD(alias, "bc", baseclass_mask == 0xFF, baseclass); + ADD(alias, "sc", subclass_mask == 0xFF, subclass); + ADD(alias, "i", interface_mask == 0xFF, interface); + return 1; +} + +/* looks like: "ccw:tNmNdtNdmN" */ +static int do_ccw_entry(const char *filename, + struct ccw_device_id *id, char *alias) +{ + id->match_flags = TO_NATIVE(id->match_flags); + id->cu_type = TO_NATIVE(id->cu_type); + id->cu_model = TO_NATIVE(id->cu_model); + id->dev_type = TO_NATIVE(id->dev_type); + id->dev_model = TO_NATIVE(id->dev_model); + + strcpy(alias, "ccw:"); + ADD(alias, "t", id->match_flags&CCW_DEVICE_ID_MATCH_CU_TYPE, + id->cu_type); + ADD(alias, "m", id->match_flags&CCW_DEVICE_ID_MATCH_CU_MODEL, + id->cu_model); + ADD(alias, "dt", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE, + id->dev_type); + ADD(alias, "dm", id->match_flags&CCW_DEVICE_ID_MATCH_DEVICE_TYPE, + id->dev_model); + return 1; +} + +/* looks like: "pnp:dD" */ +static int do_pnp_entry(const char *filename, + struct pnp_device_id *id, char *alias) +{ + sprintf(alias, "pnp:d%s", id->id); + return 1; +} + +/* looks like: "pnp:cCdD..." */ +static int do_pnp_card_entry(const char *filename, + struct pnp_card_device_id *id, char *alias) +{ + int i; + + sprintf(alias, "pnp:c%s", id->id); + for (i = 0; i < PNP_MAX_DEVICES; i++) { + if (! *id->devs[i].id) + break; + sprintf(alias + strlen(alias), "d%s", id->devs[i].id); + } + 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); + else if (sym_is(symname, "__mod_ieee1394_device_table")) + do_table(symval, sym->st_size, sizeof(struct ieee1394_device_id), + do_ieee1394_entry, mod); + else if (sym_is(symname, "__mod_ccw_device_table")) + do_table(symval, sym->st_size, sizeof(struct ccw_device_id), + do_ccw_entry, mod); + else if (sym_is(symname, "__mod_pnp_device_table")) + do_table(symval, sym->st_size, sizeof(struct pnp_device_id), + do_pnp_entry, mod); + else if (sym_is(symname, "__mod_pnp_card_device_table")) + do_table(symval, sym->st_size, sizeof(struct pnp_card_device_id), + do_pnp_card_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); +} diff -Nru a/scripts/mod/mk_elfconfig.c b/scripts/mod/mk_elfconfig.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/scripts/mod/mk_elfconfig.c 2004-07-27 18:41:47 -07:00 @@ -0,0 +1,65 @@ +#include +#include +#include +#include + +int +main(int argc, char **argv) +{ + unsigned char ei[EI_NIDENT]; + union { short s; char c[2]; } endian_test; + + if (argc != 2) { + fprintf(stderr, "Error: no arch\n"); + } + 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(); + + if ((strcmp(argv[1], "v850") == 0) || (strcmp(argv[1], "h8300") == 0)) + printf("#define MODULE_SYMBOL_PREFIX \"_\"\n"); + else + printf("#define MODULE_SYMBOL_PREFIX \"\"\n"); + + return 0; +} + diff -Nru a/scripts/mod/modpost.c b/scripts/mod/modpost.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/scripts/mod/modpost.c 2004-07-27 18:41:47 -07:00 @@ -0,0 +1,739 @@ +/* Postprocess module symbol versions + * + * Copyright 2003 Kai Germaschewski + * 2002-2003 Rusty Russell, IBM Corporation + * + * Based in part on module-init-tools/depmod.c,file2alias + * + * This software may be used and distributed according to the terms + * of the GNU General Public License, incorporated herein by reference. + * + * Usage: modpost vmlinux module1.o module2.o ... + */ + +#include +#include "modpost.h" + +/* Are we using CONFIG_MODVERSIONS? */ +int modversions = 0; +/* Warn about undefined symbols? (do so if we have vmlinux) */ +int have_vmlinux = 0; + +void +fatal(const char *fmt, ...) +{ + va_list arglist; + + fprintf(stderr, "FATAL: "); + + va_start(arglist, fmt); + vfprintf(stderr, fmt, arglist); + va_end(arglist); + + exit(1); +} + +void +warn(const char *fmt, ...) +{ + va_list arglist; + + fprintf(stderr, "WARNING: "); + + va_start(arglist, fmt); + vfprintf(stderr, fmt, arglist); + va_end(arglist); +} + +void *do_nofail(void *ptr, const char *file, int line, const char *expr) +{ + if (!ptr) { + fatal("Memory allocation failure %s line %d: %s.\n", + file, line, expr); + } + return ptr; +} + +/* A list of all modules we processed */ + +static struct module *modules; + +struct module * +find_module(char *modname) +{ + struct module *mod; + + for (mod = modules; mod; mod = mod->next) + if (strcmp(mod->name, modname) == 0) + break; + return mod; +} + +struct module * +new_module(char *modname) +{ + struct module *mod; + char *p, *s; + + mod = NOFAIL(malloc(sizeof(*mod))); + memset(mod, 0, sizeof(*mod)); + p = NOFAIL(strdup(modname)); + + /* strip trailing .o */ + if ((s = strrchr(p, '.')) != NULL) + if (strcmp(s, ".o") == 0) + *s = '\0'; + + /* add to list */ + mod->name = p; + mod->next = modules; + modules = mod; + + return mod; +} + +/* A hash of all exported symbols, + * struct symbol is also used for lists of unresolved symbols */ + +#define SYMBOL_HASH_SIZE 1024 + +struct symbol { + struct symbol *next; + struct module *module; + unsigned int crc; + int crc_valid; + char name[0]; +}; + +static struct symbol *symbolhash[SYMBOL_HASH_SIZE]; + +/* This is based on the hash agorithm from gdbm, via tdb */ +static inline unsigned int tdb_hash(const char *name) +{ + unsigned value; /* Used to compute the hash value. */ + unsigned i; /* Used to cycle through random values. */ + + /* Set the initial value from the key size. */ + for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++) + value = (value + (((unsigned char *)name)[i] << (i*5 % 24))); + + return (1103515243 * value + 12345); +} + +/* Allocate a new symbols for use in the hash of exported symbols or + * the list of unresolved symbols per module */ + +struct symbol * +alloc_symbol(const char *name, struct symbol *next) +{ + struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1)); + + memset(s, 0, sizeof(*s)); + strcpy(s->name, name); + s->next = next; + return s; +} + +/* For the hash of exported symbols */ + +void +new_symbol(const char *name, struct module *module, unsigned int *crc) +{ + unsigned int hash; + struct symbol *new; + + hash = tdb_hash(name) % SYMBOL_HASH_SIZE; + new = symbolhash[hash] = alloc_symbol(name, symbolhash[hash]); + new->module = module; + if (crc) { + new->crc = *crc; + new->crc_valid = 1; + } +} + +struct symbol * +find_symbol(const char *name) +{ + struct symbol *s; + + /* For our purposes, .foo matches foo. PPC64 needs this. */ + if (name[0] == '.') + name++; + + for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) { + if (strcmp(s->name, name) == 0) + return s; + } + return NULL; +} + +/* Add an exported symbol - it may have already been added without a + * CRC, in this case just update the CRC */ +void +add_exported_symbol(const char *name, struct module *module, unsigned int *crc) +{ + struct symbol *s = find_symbol(name); + + if (!s) { + new_symbol(name, module, crc); + return; + } + if (crc) { + s->crc = *crc; + s->crc_valid = 1; + } +} + +void * +grab_file(const char *filename, unsigned long *size) +{ + struct stat st; + void *map; + int fd; + + fd = open(filename, O_RDONLY); + if (fd < 0 || fstat(fd, &st) != 0) + return NULL; + + *size = st.st_size; + map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); + close(fd); + + if (map == MAP_FAILED) + return NULL; + return map; +} + +/* + Return a copy of the next line in a mmap'ed file. + spaces in the beginning of the line is trimmed away. + Return a pointer to a static buffer. +*/ +char* +get_next_line(unsigned long *pos, void *file, unsigned long size) +{ + static char line[4096]; + int skip = 1; + size_t len = 0; + char *p = (char *)file + *pos; + char *s = line; + + for (; *pos < size ; (*pos)++) + { + if (skip && isspace(*p)) { + p++; + continue; + } + skip = 0; + if (*p != '\n' && (*pos < size)) { + len++; + *s++ = *p++; + if (len > 4095) + break; /* Too long, stop */ + } else { + /* End of string */ + *s = '\0'; + return line; + } + } + /* End of buffer */ + return NULL; +} + +void +release_file(void *file, unsigned long size) +{ + munmap(file, size); +} + +void +parse_elf(struct elf_info *info, const char *filename) +{ + unsigned int i; + Elf_Ehdr *hdr = info->hdr; + Elf_Shdr *sechdrs; + Elf_Sym *sym; + + hdr = grab_file(filename, &info->size); + if (!hdr) { + perror(filename); + abort(); + } + info->hdr = hdr; + if (info->size < sizeof(*hdr)) + goto truncated; + + /* Fix endianness in ELF header */ + hdr->e_shoff = TO_NATIVE(hdr->e_shoff); + hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); + hdr->e_shnum = TO_NATIVE(hdr->e_shnum); + hdr->e_machine = TO_NATIVE(hdr->e_machine); + sechdrs = (void *)hdr + hdr->e_shoff; + info->sechdrs = sechdrs; + + /* Fix endianness in section headers */ + for (i = 0; i < hdr->e_shnum; i++) { + sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type); + sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset); + sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size); + sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link); + sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); + } + /* Find symbol table. */ + for (i = 1; i < hdr->e_shnum; i++) { + const char *secstrings + = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; + + if (sechdrs[i].sh_offset > info->size) + goto truncated; + if (strcmp(secstrings+sechdrs[i].sh_name, ".modinfo") == 0) { + info->modinfo = (void *)hdr + sechdrs[i].sh_offset; + info->modinfo_len = sechdrs[i].sh_size; + } + if (sechdrs[i].sh_type != SHT_SYMTAB) + continue; + + info->symtab_start = (void *)hdr + sechdrs[i].sh_offset; + info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset + + sechdrs[i].sh_size; + info->strtab = (void *)hdr + + sechdrs[sechdrs[i].sh_link].sh_offset; + } + if (!info->symtab_start) { + fprintf(stderr, "modpost: %s no symtab?\n", filename); + abort(); + } + /* Fix endianness in symbols */ + for (sym = info->symtab_start; sym < info->symtab_stop; sym++) { + sym->st_shndx = TO_NATIVE(sym->st_shndx); + sym->st_name = TO_NATIVE(sym->st_name); + sym->st_value = TO_NATIVE(sym->st_value); + sym->st_size = TO_NATIVE(sym->st_size); + } + return; + + truncated: + fprintf(stderr, "modpost: %s is truncated.\n", filename); + abort(); +} + +void +parse_elf_finish(struct elf_info *info) +{ + release_file(info->hdr, info->size); +} + +#define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_" +#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_" + +void +handle_modversions(struct module *mod, struct elf_info *info, + Elf_Sym *sym, const char *symname) +{ + unsigned int crc; + + switch (sym->st_shndx) { + case SHN_COMMON: + fprintf(stderr, "*** Warning: \"%s\" [%s] is COMMON symbol\n", + symname, mod->name); + break; + case SHN_ABS: + /* CRC'd symbol */ + if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { + crc = (unsigned int) sym->st_value; + add_exported_symbol(symname + strlen(CRC_PFX), + mod, &crc); + modversions = 1; + } + break; + case SHN_UNDEF: + /* undefined symbol */ + if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL) + break; + /* ignore global offset table */ + if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0) + break; + /* ignore __this_module, it will be resolved shortly */ + if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0) + break; +#ifdef STT_REGISTER + if (info->hdr->e_machine == EM_SPARC || + info->hdr->e_machine == EM_SPARCV9) { + /* Ignore register directives. */ + if (ELF_ST_TYPE(sym->st_info) == STT_REGISTER) + break; + } +#endif + + if (memcmp(symname, MODULE_SYMBOL_PREFIX, + strlen(MODULE_SYMBOL_PREFIX)) == 0) + mod->unres = alloc_symbol(symname + + strlen(MODULE_SYMBOL_PREFIX), + mod->unres); + break; + default: + /* All exported symbols */ + if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { + add_exported_symbol(symname + strlen(KSYMTAB_PFX), + mod, NULL); + } + break; + } +} + +int +is_vmlinux(const char *modname) +{ + const char *myname; + + if ((myname = strrchr(modname, '/'))) + myname++; + else + myname = modname; + + return strcmp(myname, "vmlinux") == 0; +} + +void +read_symbols(char *modname) +{ + const char *symname; + struct module *mod; + struct elf_info info = { }; + Elf_Sym *sym; + + parse_elf(&info, modname); + + mod = new_module(modname); + + /* When there's no vmlinux, don't print warnings about + * unresolved symbols (since there'll be too many ;) */ + if (is_vmlinux(modname)) { + unsigned int fake_crc = 0; + have_vmlinux = 1; + /* May not have this if !CONFIG_MODULE_UNLOAD: fake it. + If it appears, we'll get the real CRC. */ + add_exported_symbol("cleanup_module", mod, &fake_crc); + add_exported_symbol("struct_module", mod, &fake_crc); + mod->skip = 1; + } + + for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { + symname = info.strtab + sym->st_name; + + handle_modversions(mod, &info, sym, symname); + handle_moddevtable(mod, &info, sym, symname); + } + maybe_frob_version(modname, info.modinfo, info.modinfo_len, + (void *)info.modinfo - (void *)info.hdr); + parse_elf_finish(&info); + + /* Our trick to get versioning for struct_module - it's + * never passed as an argument to an exported function, so + * the automatic versioning doesn't pick it up, but it's really + * important anyhow */ + if (modversions) { + mod->unres = alloc_symbol("struct_module", mod->unres); + + /* Always version init_module and cleanup_module, in + * case module doesn't have its own. */ + mod->unres = alloc_symbol("init_module", mod->unres); + mod->unres = alloc_symbol("cleanup_module", mod->unres); + } +} + +#define SZ 500 + +/* We first write the generated file into memory using the + * following helper, then compare to the file on disk and + * only update the later if anything changed */ + +void __attribute__((format(printf, 2, 3))) +buf_printf(struct buffer *buf, const char *fmt, ...) +{ + char tmp[SZ]; + int len; + va_list ap; + + va_start(ap, fmt); + len = vsnprintf(tmp, SZ, fmt, ap); + if (buf->size - buf->pos < len + 1) { + buf->size += 128; + buf->p = realloc(buf->p, buf->size); + } + strncpy(buf->p + buf->pos, tmp, len + 1); + buf->pos += len; + va_end(ap); +} + +void +buf_write(struct buffer *buf, const char *s, int len) +{ + if (buf->size - buf->pos < len) { + buf->size += len; + buf->p = realloc(buf->p, buf->size); + } + strncpy(buf->p + buf->pos, s, len); + buf->pos += len; +} + +/* Header for the generated file */ + +void +add_header(struct buffer *b) +{ + buf_printf(b, "#include \n"); + buf_printf(b, "#include \n"); + buf_printf(b, "#include \n"); + buf_printf(b, "\n"); + buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); + buf_printf(b, "\n"); + buf_printf(b, "#undef unix\n"); /* We have a module called "unix" */ + buf_printf(b, "struct module __this_module\n"); + buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n"); + buf_printf(b, " .name = __stringify(KBUILD_MODNAME),\n"); + buf_printf(b, " .init = init_module,\n"); + buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"); + buf_printf(b, " .exit = cleanup_module,\n"); + buf_printf(b, "#endif\n"); + buf_printf(b, "};\n"); +} + +/* Record CRCs for unresolved symbols */ + +void +add_versions(struct buffer *b, struct module *mod) +{ + struct symbol *s, *exp; + + for (s = mod->unres; s; s = s->next) { + exp = find_symbol(s->name); + if (!exp || exp->module == mod) { + if (have_vmlinux) + fprintf(stderr, "*** Warning: \"%s\" [%s.ko] " + "undefined!\n", s->name, mod->name); + continue; + } + s->module = exp->module; + s->crc_valid = exp->crc_valid; + s->crc = exp->crc; + } + + if (!modversions) + return; + + buf_printf(b, "\n"); + buf_printf(b, "static const struct modversion_info ____versions[]\n"); + buf_printf(b, "__attribute_used__\n"); + buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n"); + + for (s = mod->unres; s; s = s->next) { + if (!s->module) { + continue; + } + if (!s->crc_valid) { + fprintf(stderr, "*** Warning: \"%s\" [%s.ko] " + "has no CRC!\n", + s->name, mod->name); + continue; + } + buf_printf(b, "\t{ %#8x, \"%s\" },\n", s->crc, s->name); + } + + buf_printf(b, "};\n"); +} + +void +add_depends(struct buffer *b, struct module *mod, struct module *modules) +{ + struct symbol *s; + struct module *m; + int first = 1; + + for (m = modules; m; m = m->next) { + m->seen = is_vmlinux(m->name); + } + + buf_printf(b, "\n"); + buf_printf(b, "static const char __module_depends[]\n"); + buf_printf(b, "__attribute_used__\n"); + buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n"); + buf_printf(b, "\"depends="); + for (s = mod->unres; s; s = s->next) { + if (!s->module) + continue; + + if (s->module->seen) + continue; + + s->module->seen = 1; + buf_printf(b, "%s%s", first ? "" : ",", + strrchr(s->module->name, '/') + 1); + first = 0; + } + buf_printf(b, "\";\n"); +} + +void +write_if_changed(struct buffer *b, const char *fname) +{ + char *tmp; + FILE *file; + struct stat st; + + file = fopen(fname, "r"); + if (!file) + goto write; + + if (fstat(fileno(file), &st) < 0) + goto close_write; + + if (st.st_size != b->pos) + goto close_write; + + tmp = NOFAIL(malloc(b->pos)); + if (fread(tmp, 1, b->pos, file) != b->pos) + goto free_write; + + if (memcmp(tmp, b->p, b->pos) != 0) + goto free_write; + + free(tmp); + fclose(file); + return; + + free_write: + free(tmp); + close_write: + fclose(file); + write: + file = fopen(fname, "w"); + if (!file) { + perror(fname); + exit(1); + } + if (fwrite(b->p, 1, b->pos, file) != b->pos) { + perror(fname); + exit(1); + } + fclose(file); +} + +void +read_dump(const char *fname) +{ + unsigned long size, pos = 0; + void *file = grab_file(fname, &size); + char *line; + + if (!file) + /* No symbol versions, silently ignore */ + return; + + while ((line = get_next_line(&pos, file, size))) { + char *symname, *modname, *d; + unsigned int crc; + struct module *mod; + + if (!(symname = strchr(line, '\t'))) + goto fail; + *symname++ = '\0'; + if (!(modname = strchr(symname, '\t'))) + goto fail; + *modname++ = '\0'; + if (strchr(modname, '\t')) + goto fail; + crc = strtoul(line, &d, 16); + if (*symname == '\0' || *modname == '\0' || *d != '\0') + goto fail; + + if (!(mod = find_module(modname))) { + if (is_vmlinux(modname)) { + modversions = 1; + have_vmlinux = 1; + } + mod = new_module(NOFAIL(strdup(modname))); + mod->skip = 1; + } + add_exported_symbol(symname, mod, &crc); + } + return; +fail: + fatal("parse error in symbol dump file\n"); +} + +void +write_dump(const char *fname) +{ + struct buffer buf = { }; + struct symbol *symbol; + int n; + + for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { + symbol = symbolhash[n]; + while (symbol) { + symbol = symbol->next; + } + } + + for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { + symbol = symbolhash[n]; + while (symbol) { + buf_printf(&buf, "0x%08x\t%s\t%s\n", symbol->crc, + symbol->name, symbol->module->name); + symbol = symbol->next; + } + } + write_if_changed(&buf, fname); +} + +int +main(int argc, char **argv) +{ + struct module *mod; + struct buffer buf = { }; + char fname[SZ]; + char *dump_read = NULL, *dump_write = NULL; + int opt; + + while ((opt = getopt(argc, argv, "i:o:")) != -1) { + switch(opt) { + case 'i': + dump_read = optarg; + break; + case 'o': + dump_write = optarg; + break; + default: + exit(1); + } + } + + if (dump_read) + read_dump(dump_read); + + while (optind < argc) { + read_symbols(argv[optind++]); + } + + for (mod = modules; mod; mod = mod->next) { + if (mod->skip) + continue; + + buf.pos = 0; + + add_header(&buf); + add_versions(&buf, mod); + add_depends(&buf, mod, modules); + add_moddevtable(&buf, mod); + + sprintf(fname, "%s.mod.c", mod->name); + write_if_changed(&buf, fname); + } + + if (dump_write) + write_dump(dump_write); + + return 0; +} + diff -Nru a/scripts/mod/modpost.h b/scripts/mod/modpost.h --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/scripts/mod/modpost.h 2004-07-27 18:41:47 -07:00 @@ -0,0 +1,103 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 +#define ELF_ST_TYPE ELF32_ST_TYPE + +#else + +#define Elf_Ehdr Elf64_Ehdr +#define Elf_Shdr Elf64_Shdr +#define Elf_Sym Elf64_Sym +#define ELF_ST_BIND ELF64_ST_BIND +#define ELF_ST_TYPE ELF64_ST_TYPE + +#endif + +#if KERNEL_ELFDATA != HOST_ELFDATA + +static inline 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 + +#define NOFAIL(ptr) do_nofail((ptr), __FILE__, __LINE__, #ptr) +void *do_nofail(void *ptr, const char *file, int line, const char *expr); + +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; + int skip; + 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; + char *modinfo; + unsigned int modinfo_len; +}; + +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); + +void maybe_frob_version(const char *modfilename, + void *modinfo, + unsigned long modinfo_len, + unsigned long modinfo_offset); + +void *grab_file(const char *filename, unsigned long *size); +char* get_next_line(unsigned long *pos, void *file, unsigned long size); +void release_file(void *file, unsigned long size); diff -Nru a/scripts/mod/sumversion.c b/scripts/mod/sumversion.c --- /dev/null Wed Dec 31 16:00:00 196900 +++ b/scripts/mod/sumversion.c 2004-07-27 18:41:47 -07:00 @@ -0,0 +1,544 @@ +#include +#include +#include +#include +#include +#include "modpost.h" + +/* Parse tag=value strings from .modinfo section */ +static char *next_string(char *string, unsigned long *secsize) +{ + /* Skip non-zero chars */ + while (string[0]) { + string++; + if ((*secsize)-- <= 1) + return NULL; + } + + /* Skip any zero padding. */ + while (!string[0]) { + string++; + if ((*secsize)-- <= 1) + return NULL; + } + return string; +} + +static char *get_modinfo(void *modinfo, unsigned long modinfo_len, + const char *tag) +{ + char *p; + unsigned int taglen = strlen(tag); + unsigned long size = modinfo_len; + + for (p = modinfo; p; p = next_string(p, &size)) { + if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=') + return p + taglen + 1; + } + return NULL; +} + +/* + * Stolen form Cryptographic API. + * + * MD4 Message Digest Algorithm (RFC1320). + * + * Implementation derived from Andrew Tridgell and Steve French's + * CIFS MD4 implementation, and the cryptoapi implementation + * originally based on the public domain implementation written + * by Colin Plumb in 1993. + * + * Copyright (c) Andrew Tridgell 1997-1998. + * Modified by Steve French (sfrench@us.ibm.com) 2002 + * Copyright (c) Cryptoapi developers. + * Copyright (c) 2002 David S. Miller (davem@redhat.com) + * Copyright (c) 2002 James Morris + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ +#define MD4_DIGEST_SIZE 16 +#define MD4_HMAC_BLOCK_SIZE 64 +#define MD4_BLOCK_WORDS 16 +#define MD4_HASH_WORDS 4 + +struct md4_ctx { + uint32_t hash[MD4_HASH_WORDS]; + uint32_t block[MD4_BLOCK_WORDS]; + uint64_t byte_count; +}; + +static inline uint32_t lshift(uint32_t x, unsigned int s) +{ + x &= 0xFFFFFFFF; + return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s)); +} + +static inline uint32_t F(uint32_t x, uint32_t y, uint32_t z) +{ + return (x & y) | ((~x) & z); +} + +static inline uint32_t G(uint32_t x, uint32_t y, uint32_t z) +{ + return (x & y) | (x & z) | (y & z); +} + +static inline uint32_t H(uint32_t x, uint32_t y, uint32_t z) +{ + return x ^ y ^ z; +} + +#define ROUND1(a,b,c,d,k,s) (a = lshift(a + F(b,c,d) + k, s)) +#define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (uint32_t)0x5A827999,s)) +#define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (uint32_t)0x6ED9EBA1,s)) + +/* XXX: this stuff can be optimized */ +static inline void le32_to_cpu_array(uint32_t *buf, unsigned int words) +{ + while (words--) { + *buf = ntohl(*buf); + buf++; + } +} + +static inline void cpu_to_le32_array(uint32_t *buf, unsigned int words) +{ + while (words--) { + *buf = htonl(*buf); + buf++; + } +} + +static void md4_transform(uint32_t *hash, uint32_t const *in) +{ + uint32_t a, b, c, d; + + a = hash[0]; + b = hash[1]; + c = hash[2]; + d = hash[3]; + + ROUND1(a, b, c, d, in[0], 3); + ROUND1(d, a, b, c, in[1], 7); + ROUND1(c, d, a, b, in[2], 11); + ROUND1(b, c, d, a, in[3], 19); + ROUND1(a, b, c, d, in[4], 3); + ROUND1(d, a, b, c, in[5], 7); + ROUND1(c, d, a, b, in[6], 11); + ROUND1(b, c, d, a, in[7], 19); + ROUND1(a, b, c, d, in[8], 3); + ROUND1(d, a, b, c, in[9], 7); + ROUND1(c, d, a, b, in[10], 11); + ROUND1(b, c, d, a, in[11], 19); + ROUND1(a, b, c, d, in[12], 3); + ROUND1(d, a, b, c, in[13], 7); + ROUND1(c, d, a, b, in[14], 11); + ROUND1(b, c, d, a, in[15], 19); + + ROUND2(a, b, c, d,in[ 0], 3); + ROUND2(d, a, b, c, in[4], 5); + ROUND2(c, d, a, b, in[8], 9); + ROUND2(b, c, d, a, in[12], 13); + ROUND2(a, b, c, d, in[1], 3); + ROUND2(d, a, b, c, in[5], 5); + ROUND2(c, d, a, b, in[9], 9); + ROUND2(b, c, d, a, in[13], 13); + ROUND2(a, b, c, d, in[2], 3); + ROUND2(d, a, b, c, in[6], 5); + ROUND2(c, d, a, b, in[10], 9); + ROUND2(b, c, d, a, in[14], 13); + ROUND2(a, b, c, d, in[3], 3); + ROUND2(d, a, b, c, in[7], 5); + ROUND2(c, d, a, b, in[11], 9); + ROUND2(b, c, d, a, in[15], 13); + + ROUND3(a, b, c, d,in[ 0], 3); + ROUND3(d, a, b, c, in[8], 9); + ROUND3(c, d, a, b, in[4], 11); + ROUND3(b, c, d, a, in[12], 15); + ROUND3(a, b, c, d, in[2], 3); + ROUND3(d, a, b, c, in[10], 9); + ROUND3(c, d, a, b, in[6], 11); + ROUND3(b, c, d, a, in[14], 15); + ROUND3(a, b, c, d, in[1], 3); + ROUND3(d, a, b, c, in[9], 9); + ROUND3(c, d, a, b, in[5], 11); + ROUND3(b, c, d, a, in[13], 15); + ROUND3(a, b, c, d, in[3], 3); + ROUND3(d, a, b, c, in[11], 9); + ROUND3(c, d, a, b, in[7], 11); + ROUND3(b, c, d, a, in[15], 15); + + hash[0] += a; + hash[1] += b; + hash[2] += c; + hash[3] += d; +} + +static inline void md4_transform_helper(struct md4_ctx *ctx) +{ + le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(uint32_t)); + md4_transform(ctx->hash, ctx->block); +} + +static void md4_init(struct md4_ctx *mctx) +{ + mctx->hash[0] = 0x67452301; + mctx->hash[1] = 0xefcdab89; + mctx->hash[2] = 0x98badcfe; + mctx->hash[3] = 0x10325476; + mctx->byte_count = 0; +} + +static void md4_update(struct md4_ctx *mctx, + const unsigned char *data, unsigned int len) +{ + const uint32_t avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f); + + mctx->byte_count += len; + + if (avail > len) { + memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), + data, len); + return; + } + + memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), + data, avail); + + md4_transform_helper(mctx); + data += avail; + len -= avail; + + while (len >= sizeof(mctx->block)) { + memcpy(mctx->block, data, sizeof(mctx->block)); + md4_transform_helper(mctx); + data += sizeof(mctx->block); + len -= sizeof(mctx->block); + } + + memcpy(mctx->block, data, len); +} + +static void md4_final_ascii(struct md4_ctx *mctx, char *out, unsigned int len) +{ + const unsigned int offset = mctx->byte_count & 0x3f; + char *p = (char *)mctx->block + offset; + int padding = 56 - (offset + 1); + + *p++ = 0x80; + if (padding < 0) { + memset(p, 0x00, padding + sizeof (uint64_t)); + md4_transform_helper(mctx); + p = (char *)mctx->block; + padding = 56; + } + + memset(p, 0, padding); + mctx->block[14] = mctx->byte_count << 3; + mctx->block[15] = mctx->byte_count >> 29; + le32_to_cpu_array(mctx->block, (sizeof(mctx->block) - + sizeof(uint64_t)) / sizeof(uint32_t)); + md4_transform(mctx->hash, mctx->block); + cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(uint32_t)); + + snprintf(out, len, "%08X%08X%08X%08X", + mctx->hash[0], mctx->hash[1], mctx->hash[2], mctx->hash[3]); +} + +static inline void add_char(unsigned char c, struct md4_ctx *md) +{ + md4_update(md, &c, 1); +} + +static int parse_string(const char *file, unsigned long len, + struct md4_ctx *md) +{ + unsigned long i; + + add_char(file[0], md); + for (i = 1; i < len; i++) { + add_char(file[i], md); + if (file[i] == '"' && file[i-1] != '\\') + break; + } + return i; +} + +static int parse_comment(const char *file, unsigned long len) +{ + unsigned long i; + + for (i = 2; i < len; i++) { + if (file[i-1] == '*' && file[i] == '/') + break; + } + return i; +} + +/* FIXME: Handle .s files differently (eg. # starts comments) --RR */ +static int parse_file(const char *fname, struct md4_ctx *md) +{ + char *file; + unsigned long i, len; + + file = grab_file(fname, &len); + if (!file) + return 0; + + for (i = 0; i < len; i++) { + /* Collapse and ignore \ and CR. */ + if (file[i] == '\\' && (i+1 < len) && file[i+1] == '\n') { + i++; + continue; + } + + /* Ignore whitespace */ + if (isspace(file[i])) + continue; + + /* Handle strings as whole units */ + if (file[i] == '"') { + i += parse_string(file+i, len - i, md); + continue; + } + + /* Comments: ignore */ + if (file[i] == '/' && file[i+1] == '*') { + i += parse_comment(file+i, len - i); + continue; + } + + add_char(file[i], md); + } + release_file(file, len); + return 1; +} + +/* We have dir/file.o. Open dir/.file.o.cmd, look for deps_ line to + * figure out source file. */ +static int parse_source_files(const char *objfile, struct md4_ctx *md) +{ + char *cmd, *file, *line, *dir; + const char *base; + unsigned long flen, pos = 0; + int dirlen, ret = 0, check_files = 0; + + cmd = NOFAIL(malloc(strlen(objfile) + sizeof("..cmd"))); + + base = strrchr(objfile, '/'); + if (base) { + base++; + dirlen = base - objfile; + sprintf(cmd, "%.*s.%s.cmd", dirlen, objfile, base); + } else { + dirlen = 0; + sprintf(cmd, ".%s.cmd", objfile); + } + dir = NOFAIL(malloc(dirlen + 1)); + strncpy(dir, objfile, dirlen); + dir[dirlen] = '\0'; + + file = grab_file(cmd, &flen); + if (!file) { + fprintf(stderr, "Warning: could not find %s for %s\n", + cmd, objfile); + goto out; + } + + /* There will be a line like so: + deps_drivers/net/dummy.o := \ + drivers/net/dummy.c \ + $(wildcard include/config/net/fastroute.h) \ + include/linux/config.h \ + $(wildcard include/config/h.h) \ + include/linux/module.h \ + + Sum all files in the same dir or subdirs. + */ + while ((line = get_next_line(&pos, file, flen)) != NULL) { + char* p = line; + if (strncmp(line, "deps_", sizeof("deps_")-1) == 0) { + check_files = 1; + continue; + } + if (!check_files) + continue; + + /* Continue until line does not end with '\' */ + if ( *(p + strlen(p)-1) != '\\') + break; + /* Terminate line at first space, to get rid of final ' \' */ + while (*p) { + if (isspace(*p)) { + *p = '\0'; + break; + } + p++; + } + + /* Check if this file is in same dir as objfile */ + if ((strstr(line, dir)+strlen(dir)-1) == strrchr(line, '/')) { + if (!parse_file(line, md)) { + fprintf(stderr, + "Warning: could not open %s: %s\n", + line, strerror(errno)); + goto out_file; + } + + } + + } + + /* Everyone parsed OK */ + ret = 1; +out_file: + release_file(file, flen); +out: + free(dir); + free(cmd); + return ret; +} + +static int get_version(const char *modname, char sum[]) +{ + void *file; + unsigned long len; + int ret = 0; + struct md4_ctx md; + char *sources, *end, *fname; + const char *basename; + char filelist[sizeof(".tmp_versions/%s.mod") + strlen(modname)]; + + /* Source files for module are in .tmp_versions/modname.mod, + after the first line. */ + if (strrchr(modname, '/')) + basename = strrchr(modname, '/') + 1; + else + basename = modname; + sprintf(filelist, ".tmp_versions/%s", basename); + /* Truncate .o, add .mod */ + strcpy(filelist + strlen(filelist)-2, ".mod"); + + file = grab_file(filelist, &len); + if (!file) { + fprintf(stderr, "Warning: could not find versions for %s\n", + filelist); + return 0; + } + + sources = strchr(file, '\n'); + if (!sources) { + fprintf(stderr, "Warning: malformed versions file for %s\n", + modname); + goto release; + } + + sources++; + end = strchr(sources, '\n'); + if (!end) { + fprintf(stderr, "Warning: bad ending versions file for %s\n", + modname); + goto release; + } + *end = '\0'; + + md4_init(&md); + for (fname = strtok(sources, " "); fname; fname = strtok(NULL, " ")) { + if (!parse_source_files(fname, &md)) + goto release; + } + + /* sum is of form \0. */ + md4_final_ascii(&md, sum, 1 + strlen(sum+1)); + ret = 1; +release: + release_file(file, len); + return ret; +} + +static void write_version(const char *filename, const char *sum, + unsigned long offset) +{ + int fd; + + fd = open(filename, O_RDWR); + if (fd < 0) { + fprintf(stderr, "Warning: changing sum in %s failed: %s\n", + filename, strerror(errno)); + return; + } + + if (lseek(fd, offset, SEEK_SET) == (off_t)-1) { + fprintf(stderr, "Warning: changing sum in %s:%lu failed: %s\n", + filename, offset, strerror(errno)); + goto out; + } + + if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) { + fprintf(stderr, "Warning: writing sum in %s failed: %s\n", + filename, strerror(errno)); + goto out; + } +out: + close(fd); +} + +void strip_rcs_crap(char *version) +{ + unsigned int len, full_len; + + if (strncmp(version, "$Revision", strlen("$Revision")) != 0) + return; + + /* Space for version string follows. */ + full_len = strlen(version) + strlen(version + strlen(version) + 1) + 2; + + /* Move string to start with version number: prefix will be + * $Revision$ or $Revision: */ + len = strlen("$Revision"); + if (version[len] == ':' || version[len] == '$') + len++; + while (isspace(version[len])) + len++; + memmove(version, version+len, full_len-len); + full_len -= len; + + /* Preserve up to next whitespace. */ + len = 0; + while (version[len] && !isspace(version[len])) + len++; + memmove(version + len, version + strlen(version), + full_len - strlen(version)); +} + +/* If the modinfo contains a "version" value, then set this. */ +void maybe_frob_version(const char *modfilename, + void *modinfo, + unsigned long modinfo_len, + unsigned long modinfo_offset) +{ + char *version, *csum; + + version = get_modinfo(modinfo, modinfo_len, "version"); + if (!version) + return; + + /* RCS $Revision gets stripped out. */ + strip_rcs_crap(version); + + /* Check against double sumversion */ + if (strchr(version, ' ')) + return; + + /* Version contains embedded NUL: second half has space for checksum */ + csum = version + strlen(version); + *(csum++) = ' '; + if (get_version(modfilename, csum)) + write_version(modfilename, version, + modinfo_offset + (version - (char *)modinfo)); +} diff -Nru a/scripts/modpost.c b/scripts/modpost.c --- a/scripts/modpost.c 2004-07-27 18:41:47 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,739 +0,0 @@ -/* Postprocess module symbol versions - * - * Copyright 2003 Kai Germaschewski - * 2002-2003 Rusty Russell, IBM Corporation - * - * Based in part on module-init-tools/depmod.c,file2alias - * - * This software may be used and distributed according to the terms - * of the GNU General Public License, incorporated herein by reference. - * - * Usage: modpost vmlinux module1.o module2.o ... - */ - -#include -#include "modpost.h" - -/* Are we using CONFIG_MODVERSIONS? */ -int modversions = 0; -/* Warn about undefined symbols? (do so if we have vmlinux) */ -int have_vmlinux = 0; - -void -fatal(const char *fmt, ...) -{ - va_list arglist; - - fprintf(stderr, "FATAL: "); - - va_start(arglist, fmt); - vfprintf(stderr, fmt, arglist); - va_end(arglist); - - exit(1); -} - -void -warn(const char *fmt, ...) -{ - va_list arglist; - - fprintf(stderr, "WARNING: "); - - va_start(arglist, fmt); - vfprintf(stderr, fmt, arglist); - va_end(arglist); -} - -void *do_nofail(void *ptr, const char *file, int line, const char *expr) -{ - if (!ptr) { - fatal("Memory allocation failure %s line %d: %s.\n", - file, line, expr); - } - return ptr; -} - -/* A list of all modules we processed */ - -static struct module *modules; - -struct module * -find_module(char *modname) -{ - struct module *mod; - - for (mod = modules; mod; mod = mod->next) - if (strcmp(mod->name, modname) == 0) - break; - return mod; -} - -struct module * -new_module(char *modname) -{ - struct module *mod; - char *p, *s; - - mod = NOFAIL(malloc(sizeof(*mod))); - memset(mod, 0, sizeof(*mod)); - p = NOFAIL(strdup(modname)); - - /* strip trailing .o */ - if ((s = strrchr(p, '.')) != NULL) - if (strcmp(s, ".o") == 0) - *s = '\0'; - - /* add to list */ - mod->name = p; - mod->next = modules; - modules = mod; - - return mod; -} - -/* A hash of all exported symbols, - * struct symbol is also used for lists of unresolved symbols */ - -#define SYMBOL_HASH_SIZE 1024 - -struct symbol { - struct symbol *next; - struct module *module; - unsigned int crc; - int crc_valid; - char name[0]; -}; - -static struct symbol *symbolhash[SYMBOL_HASH_SIZE]; - -/* This is based on the hash agorithm from gdbm, via tdb */ -static inline unsigned int tdb_hash(const char *name) -{ - unsigned value; /* Used to compute the hash value. */ - unsigned i; /* Used to cycle through random values. */ - - /* Set the initial value from the key size. */ - for (value = 0x238F13AF * strlen(name), i=0; name[i]; i++) - value = (value + (((unsigned char *)name)[i] << (i*5 % 24))); - - return (1103515243 * value + 12345); -} - -/* Allocate a new symbols for use in the hash of exported symbols or - * the list of unresolved symbols per module */ - -struct symbol * -alloc_symbol(const char *name, struct symbol *next) -{ - struct symbol *s = NOFAIL(malloc(sizeof(*s) + strlen(name) + 1)); - - memset(s, 0, sizeof(*s)); - strcpy(s->name, name); - s->next = next; - return s; -} - -/* For the hash of exported symbols */ - -void -new_symbol(const char *name, struct module *module, unsigned int *crc) -{ - unsigned int hash; - struct symbol *new; - - hash = tdb_hash(name) % SYMBOL_HASH_SIZE; - new = symbolhash[hash] = alloc_symbol(name, symbolhash[hash]); - new->module = module; - if (crc) { - new->crc = *crc; - new->crc_valid = 1; - } -} - -struct symbol * -find_symbol(const char *name) -{ - struct symbol *s; - - /* For our purposes, .foo matches foo. PPC64 needs this. */ - if (name[0] == '.') - name++; - - for (s = symbolhash[tdb_hash(name) % SYMBOL_HASH_SIZE]; s; s=s->next) { - if (strcmp(s->name, name) == 0) - return s; - } - return NULL; -} - -/* Add an exported symbol - it may have already been added without a - * CRC, in this case just update the CRC */ -void -add_exported_symbol(const char *name, struct module *module, unsigned int *crc) -{ - struct symbol *s = find_symbol(name); - - if (!s) { - new_symbol(name, module, crc); - return; - } - if (crc) { - s->crc = *crc; - s->crc_valid = 1; - } -} - -void * -grab_file(const char *filename, unsigned long *size) -{ - struct stat st; - void *map; - int fd; - - fd = open(filename, O_RDONLY); - if (fd < 0 || fstat(fd, &st) != 0) - return NULL; - - *size = st.st_size; - map = mmap(NULL, *size, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0); - close(fd); - - if (map == MAP_FAILED) - return NULL; - return map; -} - -/* - Return a copy of the next line in a mmap'ed file. - spaces in the beginning of the line is trimmed away. - Return a pointer to a static buffer. -*/ -char* -get_next_line(unsigned long *pos, void *file, unsigned long size) -{ - static char line[4096]; - int skip = 1; - size_t len = 0; - char *p = (char *)file + *pos; - char *s = line; - - for (; *pos < size ; (*pos)++) - { - if (skip && isspace(*p)) { - p++; - continue; - } - skip = 0; - if (*p != '\n' && (*pos < size)) { - len++; - *s++ = *p++; - if (len > 4095) - break; /* Too long, stop */ - } else { - /* End of string */ - *s = '\0'; - return line; - } - } - /* End of buffer */ - return NULL; -} - -void -release_file(void *file, unsigned long size) -{ - munmap(file, size); -} - -void -parse_elf(struct elf_info *info, const char *filename) -{ - unsigned int i; - Elf_Ehdr *hdr = info->hdr; - Elf_Shdr *sechdrs; - Elf_Sym *sym; - - hdr = grab_file(filename, &info->size); - if (!hdr) { - perror(filename); - abort(); - } - info->hdr = hdr; - if (info->size < sizeof(*hdr)) - goto truncated; - - /* Fix endianness in ELF header */ - hdr->e_shoff = TO_NATIVE(hdr->e_shoff); - hdr->e_shstrndx = TO_NATIVE(hdr->e_shstrndx); - hdr->e_shnum = TO_NATIVE(hdr->e_shnum); - hdr->e_machine = TO_NATIVE(hdr->e_machine); - sechdrs = (void *)hdr + hdr->e_shoff; - info->sechdrs = sechdrs; - - /* Fix endianness in section headers */ - for (i = 0; i < hdr->e_shnum; i++) { - sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type); - sechdrs[i].sh_offset = TO_NATIVE(sechdrs[i].sh_offset); - sechdrs[i].sh_size = TO_NATIVE(sechdrs[i].sh_size); - sechdrs[i].sh_link = TO_NATIVE(sechdrs[i].sh_link); - sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name); - } - /* Find symbol table. */ - for (i = 1; i < hdr->e_shnum; i++) { - const char *secstrings - = (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset; - - if (sechdrs[i].sh_offset > info->size) - goto truncated; - if (strcmp(secstrings+sechdrs[i].sh_name, ".modinfo") == 0) { - info->modinfo = (void *)hdr + sechdrs[i].sh_offset; - info->modinfo_len = sechdrs[i].sh_size; - } - if (sechdrs[i].sh_type != SHT_SYMTAB) - continue; - - info->symtab_start = (void *)hdr + sechdrs[i].sh_offset; - info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset - + sechdrs[i].sh_size; - info->strtab = (void *)hdr + - sechdrs[sechdrs[i].sh_link].sh_offset; - } - if (!info->symtab_start) { - fprintf(stderr, "modpost: %s no symtab?\n", filename); - abort(); - } - /* Fix endianness in symbols */ - for (sym = info->symtab_start; sym < info->symtab_stop; sym++) { - sym->st_shndx = TO_NATIVE(sym->st_shndx); - sym->st_name = TO_NATIVE(sym->st_name); - sym->st_value = TO_NATIVE(sym->st_value); - sym->st_size = TO_NATIVE(sym->st_size); - } - return; - - truncated: - fprintf(stderr, "modpost: %s is truncated.\n", filename); - abort(); -} - -void -parse_elf_finish(struct elf_info *info) -{ - release_file(info->hdr, info->size); -} - -#define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_" -#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_" - -void -handle_modversions(struct module *mod, struct elf_info *info, - Elf_Sym *sym, const char *symname) -{ - unsigned int crc; - - switch (sym->st_shndx) { - case SHN_COMMON: - fprintf(stderr, "*** Warning: \"%s\" [%s] is COMMON symbol\n", - symname, mod->name); - break; - case SHN_ABS: - /* CRC'd symbol */ - if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) { - crc = (unsigned int) sym->st_value; - add_exported_symbol(symname + strlen(CRC_PFX), - mod, &crc); - modversions = 1; - } - break; - case SHN_UNDEF: - /* undefined symbol */ - if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL) - break; - /* ignore global offset table */ - if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0) - break; - /* ignore __this_module, it will be resolved shortly */ - if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0) - break; -#ifdef STT_REGISTER - if (info->hdr->e_machine == EM_SPARC || - info->hdr->e_machine == EM_SPARCV9) { - /* Ignore register directives. */ - if (ELF_ST_TYPE(sym->st_info) == STT_REGISTER) - break; - } -#endif - - if (memcmp(symname, MODULE_SYMBOL_PREFIX, - strlen(MODULE_SYMBOL_PREFIX)) == 0) - mod->unres = alloc_symbol(symname + - strlen(MODULE_SYMBOL_PREFIX), - mod->unres); - break; - default: - /* All exported symbols */ - if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) { - add_exported_symbol(symname + strlen(KSYMTAB_PFX), - mod, NULL); - } - break; - } -} - -int -is_vmlinux(const char *modname) -{ - const char *myname; - - if ((myname = strrchr(modname, '/'))) - myname++; - else - myname = modname; - - return strcmp(myname, "vmlinux") == 0; -} - -void -read_symbols(char *modname) -{ - const char *symname; - struct module *mod; - struct elf_info info = { }; - Elf_Sym *sym; - - parse_elf(&info, modname); - - mod = new_module(modname); - - /* When there's no vmlinux, don't print warnings about - * unresolved symbols (since there'll be too many ;) */ - if (is_vmlinux(modname)) { - unsigned int fake_crc = 0; - have_vmlinux = 1; - /* May not have this if !CONFIG_MODULE_UNLOAD: fake it. - If it appears, we'll get the real CRC. */ - add_exported_symbol("cleanup_module", mod, &fake_crc); - add_exported_symbol("struct_module", mod, &fake_crc); - mod->skip = 1; - } - - for (sym = info.symtab_start; sym < info.symtab_stop; sym++) { - symname = info.strtab + sym->st_name; - - handle_modversions(mod, &info, sym, symname); - handle_moddevtable(mod, &info, sym, symname); - } - maybe_frob_version(modname, info.modinfo, info.modinfo_len, - (void *)info.modinfo - (void *)info.hdr); - parse_elf_finish(&info); - - /* Our trick to get versioning for struct_module - it's - * never passed as an argument to an exported function, so - * the automatic versioning doesn't pick it up, but it's really - * important anyhow */ - if (modversions) { - mod->unres = alloc_symbol("struct_module", mod->unres); - - /* Always version init_module and cleanup_module, in - * case module doesn't have its own. */ - mod->unres = alloc_symbol("init_module", mod->unres); - mod->unres = alloc_symbol("cleanup_module", mod->unres); - } -} - -#define SZ 500 - -/* We first write the generated file into memory using the - * following helper, then compare to the file on disk and - * only update the later if anything changed */ - -void __attribute__((format(printf, 2, 3))) -buf_printf(struct buffer *buf, const char *fmt, ...) -{ - char tmp[SZ]; - int len; - va_list ap; - - va_start(ap, fmt); - len = vsnprintf(tmp, SZ, fmt, ap); - if (buf->size - buf->pos < len + 1) { - buf->size += 128; - buf->p = realloc(buf->p, buf->size); - } - strncpy(buf->p + buf->pos, tmp, len + 1); - buf->pos += len; - va_end(ap); -} - -void -buf_write(struct buffer *buf, const char *s, int len) -{ - if (buf->size - buf->pos < len) { - buf->size += len; - buf->p = realloc(buf->p, buf->size); - } - strncpy(buf->p + buf->pos, s, len); - buf->pos += len; -} - -/* Header for the generated file */ - -void -add_header(struct buffer *b) -{ - buf_printf(b, "#include \n"); - buf_printf(b, "#include \n"); - buf_printf(b, "#include \n"); - buf_printf(b, "\n"); - buf_printf(b, "MODULE_INFO(vermagic, VERMAGIC_STRING);\n"); - buf_printf(b, "\n"); - buf_printf(b, "#undef unix\n"); /* We have a module called "unix" */ - buf_printf(b, "struct module __this_module\n"); - buf_printf(b, "__attribute__((section(\".gnu.linkonce.this_module\"))) = {\n"); - buf_printf(b, " .name = __stringify(KBUILD_MODNAME),\n"); - buf_printf(b, " .init = init_module,\n"); - buf_printf(b, "#ifdef CONFIG_MODULE_UNLOAD\n"); - buf_printf(b, " .exit = cleanup_module,\n"); - buf_printf(b, "#endif\n"); - buf_printf(b, "};\n"); -} - -/* Record CRCs for unresolved symbols */ - -void -add_versions(struct buffer *b, struct module *mod) -{ - struct symbol *s, *exp; - - for (s = mod->unres; s; s = s->next) { - exp = find_symbol(s->name); - if (!exp || exp->module == mod) { - if (have_vmlinux) - fprintf(stderr, "*** Warning: \"%s\" [%s.ko] " - "undefined!\n", s->name, mod->name); - continue; - } - s->module = exp->module; - s->crc_valid = exp->crc_valid; - s->crc = exp->crc; - } - - if (!modversions) - return; - - buf_printf(b, "\n"); - buf_printf(b, "static const struct modversion_info ____versions[]\n"); - buf_printf(b, "__attribute_used__\n"); - buf_printf(b, "__attribute__((section(\"__versions\"))) = {\n"); - - for (s = mod->unres; s; s = s->next) { - if (!s->module) { - continue; - } - if (!s->crc_valid) { - fprintf(stderr, "*** Warning: \"%s\" [%s.ko] " - "has no CRC!\n", - s->name, mod->name); - continue; - } - buf_printf(b, "\t{ %#8x, \"%s\" },\n", s->crc, s->name); - } - - buf_printf(b, "};\n"); -} - -void -add_depends(struct buffer *b, struct module *mod, struct module *modules) -{ - struct symbol *s; - struct module *m; - int first = 1; - - for (m = modules; m; m = m->next) { - m->seen = is_vmlinux(m->name); - } - - buf_printf(b, "\n"); - buf_printf(b, "static const char __module_depends[]\n"); - buf_printf(b, "__attribute_used__\n"); - buf_printf(b, "__attribute__((section(\".modinfo\"))) =\n"); - buf_printf(b, "\"depends="); - for (s = mod->unres; s; s = s->next) { - if (!s->module) - continue; - - if (s->module->seen) - continue; - - s->module->seen = 1; - buf_printf(b, "%s%s", first ? "" : ",", - strrchr(s->module->name, '/') + 1); - first = 0; - } - buf_printf(b, "\";\n"); -} - -void -write_if_changed(struct buffer *b, const char *fname) -{ - char *tmp; - FILE *file; - struct stat st; - - file = fopen(fname, "r"); - if (!file) - goto write; - - if (fstat(fileno(file), &st) < 0) - goto close_write; - - if (st.st_size != b->pos) - goto close_write; - - tmp = NOFAIL(malloc(b->pos)); - if (fread(tmp, 1, b->pos, file) != b->pos) - goto free_write; - - if (memcmp(tmp, b->p, b->pos) != 0) - goto free_write; - - free(tmp); - fclose(file); - return; - - free_write: - free(tmp); - close_write: - fclose(file); - write: - file = fopen(fname, "w"); - if (!file) { - perror(fname); - exit(1); - } - if (fwrite(b->p, 1, b->pos, file) != b->pos) { - perror(fname); - exit(1); - } - fclose(file); -} - -void -read_dump(const char *fname) -{ - unsigned long size, pos = 0; - void *file = grab_file(fname, &size); - char *line; - - if (!file) - /* No symbol versions, silently ignore */ - return; - - while ((line = get_next_line(&pos, file, size))) { - char *symname, *modname, *d; - unsigned int crc; - struct module *mod; - - if (!(symname = strchr(line, '\t'))) - goto fail; - *symname++ = '\0'; - if (!(modname = strchr(symname, '\t'))) - goto fail; - *modname++ = '\0'; - if (strchr(modname, '\t')) - goto fail; - crc = strtoul(line, &d, 16); - if (*symname == '\0' || *modname == '\0' || *d != '\0') - goto fail; - - if (!(mod = find_module(modname))) { - if (is_vmlinux(modname)) { - modversions = 1; - have_vmlinux = 1; - } - mod = new_module(NOFAIL(strdup(modname))); - mod->skip = 1; - } - add_exported_symbol(symname, mod, &crc); - } - return; -fail: - fatal("parse error in symbol dump file\n"); -} - -void -write_dump(const char *fname) -{ - struct buffer buf = { }; - struct symbol *symbol; - int n; - - for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { - symbol = symbolhash[n]; - while (symbol) { - symbol = symbol->next; - } - } - - for (n = 0; n < SYMBOL_HASH_SIZE ; n++) { - symbol = symbolhash[n]; - while (symbol) { - buf_printf(&buf, "0x%08x\t%s\t%s\n", symbol->crc, - symbol->name, symbol->module->name); - symbol = symbol->next; - } - } - write_if_changed(&buf, fname); -} - -int -main(int argc, char **argv) -{ - struct module *mod; - struct buffer buf = { }; - char fname[SZ]; - char *dump_read = NULL, *dump_write = NULL; - int opt; - - while ((opt = getopt(argc, argv, "i:o:")) != -1) { - switch(opt) { - case 'i': - dump_read = optarg; - break; - case 'o': - dump_write = optarg; - break; - default: - exit(1); - } - } - - if (dump_read) - read_dump(dump_read); - - while (optind < argc) { - read_symbols(argv[optind++]); - } - - for (mod = modules; mod; mod = mod->next) { - if (mod->skip) - continue; - - buf.pos = 0; - - add_header(&buf); - add_versions(&buf, mod); - add_depends(&buf, mod, modules); - add_moddevtable(&buf, mod); - - sprintf(fname, "%s.mod.c", mod->name); - write_if_changed(&buf, fname); - } - - if (dump_write) - write_dump(dump_write); - - return 0; -} - diff -Nru a/scripts/modpost.h b/scripts/modpost.h --- a/scripts/modpost.h 2004-07-27 18:41:47 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,103 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#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 -#define ELF_ST_TYPE ELF32_ST_TYPE - -#else - -#define Elf_Ehdr Elf64_Ehdr -#define Elf_Shdr Elf64_Shdr -#define Elf_Sym Elf64_Sym -#define ELF_ST_BIND ELF64_ST_BIND -#define ELF_ST_TYPE ELF64_ST_TYPE - -#endif - -#if KERNEL_ELFDATA != HOST_ELFDATA - -static inline 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 - -#define NOFAIL(ptr) do_nofail((ptr), __FILE__, __LINE__, #ptr) -void *do_nofail(void *ptr, const char *file, int line, const char *expr); - -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; - int skip; - 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; - char *modinfo; - unsigned int modinfo_len; -}; - -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); - -void maybe_frob_version(const char *modfilename, - void *modinfo, - unsigned long modinfo_len, - unsigned long modinfo_offset); - -void *grab_file(const char *filename, unsigned long *size); -char* get_next_line(unsigned long *pos, void *file, unsigned long size); -void release_file(void *file, unsigned long size); diff -Nru a/scripts/package/Makefile b/scripts/package/Makefile --- a/scripts/package/Makefile 2004-07-27 18:41:47 -07:00 +++ b/scripts/package/Makefile 2004-07-27 18:41:47 -07:00 @@ -31,9 +31,10 @@ MKSPEC := $(srctree)/scripts/package/mkspec PREV := set -e; cd ..; +# rpm-pkg .PHONY: rpm-pkg rpm -$(objtree)/kernel.spec: $(MKSPEC) +$(objtree)/kernel.spec: $(MKSPEC) $(srctree)/Makefile $(CONFIG_SHELL) $(MKSPEC) > $@ rpm-pkg rpm: $(objtree)/kernel.spec @@ -52,6 +53,22 @@ clean-rule += rm -f $(objtree)/kernel.spec +# binrpm-pkg +.PHONY: binrpm-pkg +$(objtree)/binkernel.spec: $(MKSPEC) $(srctree)/Makefile + $(CONFIG_SHELL) $(MKSPEC) prebuilt > $@ + +binrpm-pkg: $(objtree)/binkernel.spec + $(MAKE) + set -e; \ + $(CONFIG_SHELL) $(srctree)/scripts/mkversion > $(objtree)/.tmp_version + set -e; \ + mv -f $(objtree)/.tmp_version $(objtree)/.version + + $(RPM) --define "_builddir $(srctree)" --target $(UTS_MACHINE) -bb $< + +clean-rule += rm -f $(objtree)/binkernel.spec + # Deb target # --------------------------------------------------------------------------- # @@ -67,5 +84,6 @@ # --------------------------------------------------------------------------- help: @echo ' rpm-pkg - Build the kernel as an RPM package' + @echo ' binrpm-pkg - Build an rpm package containing the compiled kernel & modules' @echo ' deb-pkg - Build the kernel as an deb package' diff -Nru a/scripts/package/mkspec b/scripts/package/mkspec --- a/scripts/package/mkspec 2004-07-27 18:41:47 -07:00 +++ b/scripts/package/mkspec 2004-07-27 18:41:47 -07:00 @@ -9,6 +9,13 @@ # Patched for non-x86 by Opencon (L) 2002 # +# how we were called determines which rpms we build and how we build them +if [ "$1" = "prebuilt" ]; then + PREBUILT=true +else + PREBUILT=false +fi + # starting to output the spec if [ "`grep CONFIG_DRM=y .config | cut -f2 -d\=`" = "y" ]; then PROVIDES=kernel-drm @@ -26,8 +33,12 @@ echo "Group: System Environment/Kernel" echo "Vendor: The Linux Community" echo "URL: http://www.kernel.org" + +if ! $PREBUILT; then echo -n "Source: kernel-$VERSION.$PATCHLEVEL.$SUBLEVEL" echo "$EXTRAVERSION.tar.gz" | sed -e "s/-//g" +fi + echo "BuildRoot: /var/tmp/%{name}-%{PACKAGE_VERSION}-root" echo "Provides: $PROVIDES" echo "%define __spec_install_post /usr/lib/rpm/brp-compress || :" @@ -36,12 +47,20 @@ echo "%description" echo "The Linux Kernel, the operating system core itself" echo "" + +if ! $PREBUILT; then echo "%prep" echo "%setup -q" echo "" +fi + echo "%build" + +if ! $PREBUILT; then echo "make clean && make" echo "" +fi + echo "%install" echo 'mkdir -p $RPM_BUILD_ROOT/boot $RPM_BUILD_ROOT/lib $RPM_BUILD_ROOT/lib/modules' diff -Nru a/scripts/sumversion.c b/scripts/sumversion.c --- a/scripts/sumversion.c 2004-07-27 18:41:47 -07:00 +++ /dev/null Wed Dec 31 16:00:00 196900 @@ -1,544 +0,0 @@ -#include -#include -#include -#include -#include -#include "modpost.h" - -/* Parse tag=value strings from .modinfo section */ -static char *next_string(char *string, unsigned long *secsize) -{ - /* Skip non-zero chars */ - while (string[0]) { - string++; - if ((*secsize)-- <= 1) - return NULL; - } - - /* Skip any zero padding. */ - while (!string[0]) { - string++; - if ((*secsize)-- <= 1) - return NULL; - } - return string; -} - -static char *get_modinfo(void *modinfo, unsigned long modinfo_len, - const char *tag) -{ - char *p; - unsigned int taglen = strlen(tag); - unsigned long size = modinfo_len; - - for (p = modinfo; p; p = next_string(p, &size)) { - if (strncmp(p, tag, taglen) == 0 && p[taglen] == '=') - return p + taglen + 1; - } - return NULL; -} - -/* - * Stolen form Cryptographic API. - * - * MD4 Message Digest Algorithm (RFC1320). - * - * Implementation derived from Andrew Tridgell and Steve French's - * CIFS MD4 implementation, and the cryptoapi implementation - * originally based on the public domain implementation written - * by Colin Plumb in 1993. - * - * Copyright (c) Andrew Tridgell 1997-1998. - * Modified by Steve French (sfrench@us.ibm.com) 2002 - * Copyright (c) Cryptoapi developers. - * Copyright (c) 2002 David S. Miller (davem@redhat.com) - * Copyright (c) 2002 James Morris - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2 of the License, or - * (at your option) any later version. - * - */ -#define MD4_DIGEST_SIZE 16 -#define MD4_HMAC_BLOCK_SIZE 64 -#define MD4_BLOCK_WORDS 16 -#define MD4_HASH_WORDS 4 - -struct md4_ctx { - uint32_t hash[MD4_HASH_WORDS]; - uint32_t block[MD4_BLOCK_WORDS]; - uint64_t byte_count; -}; - -static inline uint32_t lshift(uint32_t x, unsigned int s) -{ - x &= 0xFFFFFFFF; - return ((x << s) & 0xFFFFFFFF) | (x >> (32 - s)); -} - -static inline uint32_t F(uint32_t x, uint32_t y, uint32_t z) -{ - return (x & y) | ((~x) & z); -} - -static inline uint32_t G(uint32_t x, uint32_t y, uint32_t z) -{ - return (x & y) | (x & z) | (y & z); -} - -static inline uint32_t H(uint32_t x, uint32_t y, uint32_t z) -{ - return x ^ y ^ z; -} - -#define ROUND1(a,b,c,d,k,s) (a = lshift(a + F(b,c,d) + k, s)) -#define ROUND2(a,b,c,d,k,s) (a = lshift(a + G(b,c,d) + k + (uint32_t)0x5A827999,s)) -#define ROUND3(a,b,c,d,k,s) (a = lshift(a + H(b,c,d) + k + (uint32_t)0x6ED9EBA1,s)) - -/* XXX: this stuff can be optimized */ -static inline void le32_to_cpu_array(uint32_t *buf, unsigned int words) -{ - while (words--) { - *buf = ntohl(*buf); - buf++; - } -} - -static inline void cpu_to_le32_array(uint32_t *buf, unsigned int words) -{ - while (words--) { - *buf = htonl(*buf); - buf++; - } -} - -static void md4_transform(uint32_t *hash, uint32_t const *in) -{ - uint32_t a, b, c, d; - - a = hash[0]; - b = hash[1]; - c = hash[2]; - d = hash[3]; - - ROUND1(a, b, c, d, in[0], 3); - ROUND1(d, a, b, c, in[1], 7); - ROUND1(c, d, a, b, in[2], 11); - ROUND1(b, c, d, a, in[3], 19); - ROUND1(a, b, c, d, in[4], 3); - ROUND1(d, a, b, c, in[5], 7); - ROUND1(c, d, a, b, in[6], 11); - ROUND1(b, c, d, a, in[7], 19); - ROUND1(a, b, c, d, in[8], 3); - ROUND1(d, a, b, c, in[9], 7); - ROUND1(c, d, a, b, in[10], 11); - ROUND1(b, c, d, a, in[11], 19); - ROUND1(a, b, c, d, in[12], 3); - ROUND1(d, a, b, c, in[13], 7); - ROUND1(c, d, a, b, in[14], 11); - ROUND1(b, c, d, a, in[15], 19); - - ROUND2(a, b, c, d,in[ 0], 3); - ROUND2(d, a, b, c, in[4], 5); - ROUND2(c, d, a, b, in[8], 9); - ROUND2(b, c, d, a, in[12], 13); - ROUND2(a, b, c, d, in[1], 3); - ROUND2(d, a, b, c, in[5], 5); - ROUND2(c, d, a, b, in[9], 9); - ROUND2(b, c, d, a, in[13], 13); - ROUND2(a, b, c, d, in[2], 3); - ROUND2(d, a, b, c, in[6], 5); - ROUND2(c, d, a, b, in[10], 9); - ROUND2(b, c, d, a, in[14], 13); - ROUND2(a, b, c, d, in[3], 3); - ROUND2(d, a, b, c, in[7], 5); - ROUND2(c, d, a, b, in[11], 9); - ROUND2(b, c, d, a, in[15], 13); - - ROUND3(a, b, c, d,in[ 0], 3); - ROUND3(d, a, b, c, in[8], 9); - ROUND3(c, d, a, b, in[4], 11); - ROUND3(b, c, d, a, in[12], 15); - ROUND3(a, b, c, d, in[2], 3); - ROUND3(d, a, b, c, in[10], 9); - ROUND3(c, d, a, b, in[6], 11); - ROUND3(b, c, d, a, in[14], 15); - ROUND3(a, b, c, d, in[1], 3); - ROUND3(d, a, b, c, in[9], 9); - ROUND3(c, d, a, b, in[5], 11); - ROUND3(b, c, d, a, in[13], 15); - ROUND3(a, b, c, d, in[3], 3); - ROUND3(d, a, b, c, in[11], 9); - ROUND3(c, d, a, b, in[7], 11); - ROUND3(b, c, d, a, in[15], 15); - - hash[0] += a; - hash[1] += b; - hash[2] += c; - hash[3] += d; -} - -static inline void md4_transform_helper(struct md4_ctx *ctx) -{ - le32_to_cpu_array(ctx->block, sizeof(ctx->block) / sizeof(uint32_t)); - md4_transform(ctx->hash, ctx->block); -} - -static void md4_init(struct md4_ctx *mctx) -{ - mctx->hash[0] = 0x67452301; - mctx->hash[1] = 0xefcdab89; - mctx->hash[2] = 0x98badcfe; - mctx->hash[3] = 0x10325476; - mctx->byte_count = 0; -} - -static void md4_update(struct md4_ctx *mctx, - const unsigned char *data, unsigned int len) -{ - const uint32_t avail = sizeof(mctx->block) - (mctx->byte_count & 0x3f); - - mctx->byte_count += len; - - if (avail > len) { - memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), - data, len); - return; - } - - memcpy((char *)mctx->block + (sizeof(mctx->block) - avail), - data, avail); - - md4_transform_helper(mctx); - data += avail; - len -= avail; - - while (len >= sizeof(mctx->block)) { - memcpy(mctx->block, data, sizeof(mctx->block)); - md4_transform_helper(mctx); - data += sizeof(mctx->block); - len -= sizeof(mctx->block); - } - - memcpy(mctx->block, data, len); -} - -static void md4_final_ascii(struct md4_ctx *mctx, char *out, unsigned int len) -{ - const unsigned int offset = mctx->byte_count & 0x3f; - char *p = (char *)mctx->block + offset; - int padding = 56 - (offset + 1); - - *p++ = 0x80; - if (padding < 0) { - memset(p, 0x00, padding + sizeof (uint64_t)); - md4_transform_helper(mctx); - p = (char *)mctx->block; - padding = 56; - } - - memset(p, 0, padding); - mctx->block[14] = mctx->byte_count << 3; - mctx->block[15] = mctx->byte_count >> 29; - le32_to_cpu_array(mctx->block, (sizeof(mctx->block) - - sizeof(uint64_t)) / sizeof(uint32_t)); - md4_transform(mctx->hash, mctx->block); - cpu_to_le32_array(mctx->hash, sizeof(mctx->hash) / sizeof(uint32_t)); - - snprintf(out, len, "%08X%08X%08X%08X", - mctx->hash[0], mctx->hash[1], mctx->hash[2], mctx->hash[3]); -} - -static inline void add_char(unsigned char c, struct md4_ctx *md) -{ - md4_update(md, &c, 1); -} - -static int parse_string(const char *file, unsigned long len, - struct md4_ctx *md) -{ - unsigned long i; - - add_char(file[0], md); - for (i = 1; i < len; i++) { - add_char(file[i], md); - if (file[i] == '"' && file[i-1] != '\\') - break; - } - return i; -} - -static int parse_comment(const char *file, unsigned long len) -{ - unsigned long i; - - for (i = 2; i < len; i++) { - if (file[i-1] == '*' && file[i] == '/') - break; - } - return i; -} - -/* FIXME: Handle .s files differently (eg. # starts comments) --RR */ -static int parse_file(const char *fname, struct md4_ctx *md) -{ - char *file; - unsigned long i, len; - - file = grab_file(fname, &len); - if (!file) - return 0; - - for (i = 0; i < len; i++) { - /* Collapse and ignore \ and CR. */ - if (file[i] == '\\' && (i+1 < len) && file[i+1] == '\n') { - i++; - continue; - } - - /* Ignore whitespace */ - if (isspace(file[i])) - continue; - - /* Handle strings as whole units */ - if (file[i] == '"') { - i += parse_string(file+i, len - i, md); - continue; - } - - /* Comments: ignore */ - if (file[i] == '/' && file[i+1] == '*') { - i += parse_comment(file+i, len - i); - continue; - } - - add_char(file[i], md); - } - release_file(file, len); - return 1; -} - -/* We have dir/file.o. Open dir/.file.o.cmd, look for deps_ line to - * figure out source file. */ -static int parse_source_files(const char *objfile, struct md4_ctx *md) -{ - char *cmd, *file, *line, *dir; - const char *base; - unsigned long flen, pos = 0; - int dirlen, ret = 0, check_files = 0; - - cmd = NOFAIL(malloc(strlen(objfile) + sizeof("..cmd"))); - - base = strrchr(objfile, '/'); - if (base) { - base++; - dirlen = base - objfile; - sprintf(cmd, "%.*s.%s.cmd", dirlen, objfile, base); - } else { - dirlen = 0; - sprintf(cmd, ".%s.cmd", objfile); - } - dir = NOFAIL(malloc(dirlen + 1)); - strncpy(dir, objfile, dirlen); - dir[dirlen] = '\0'; - - file = grab_file(cmd, &flen); - if (!file) { - fprintf(stderr, "Warning: could not find %s for %s\n", - cmd, objfile); - goto out; - } - - /* There will be a line like so: - deps_drivers/net/dummy.o := \ - drivers/net/dummy.c \ - $(wildcard include/config/net/fastroute.h) \ - include/linux/config.h \ - $(wildcard include/config/h.h) \ - include/linux/module.h \ - - Sum all files in the same dir or subdirs. - */ - while ((line = get_next_line(&pos, file, flen)) != NULL) { - char* p = line; - if (strncmp(line, "deps_", sizeof("deps_")-1) == 0) { - check_files = 1; - continue; - } - if (!check_files) - continue; - - /* Continue until line does not end with '\' */ - if ( *(p + strlen(p)-1) != '\\') - break; - /* Terminate line at first space, to get rid of final ' \' */ - while (*p) { - if (isspace(*p)) { - *p = '\0'; - break; - } - p++; - } - - /* Check if this file is in same dir as objfile */ - if ((strstr(line, dir)+strlen(dir)-1) == strrchr(line, '/')) { - if (!parse_file(line, md)) { - fprintf(stderr, - "Warning: could not open %s: %s\n", - line, strerror(errno)); - goto out_file; - } - - } - - } - - /* Everyone parsed OK */ - ret = 1; -out_file: - release_file(file, flen); -out: - free(dir); - free(cmd); - return ret; -} - -static int get_version(const char *modname, char sum[]) -{ - void *file; - unsigned long len; - int ret = 0; - struct md4_ctx md; - char *sources, *end, *fname; - const char *basename; - char filelist[sizeof(".tmp_versions/%s.mod") + strlen(modname)]; - - /* Source files for module are in .tmp_versions/modname.mod, - after the first line. */ - if (strrchr(modname, '/')) - basename = strrchr(modname, '/') + 1; - else - basename = modname; - sprintf(filelist, ".tmp_versions/%s", basename); - /* Truncate .o, add .mod */ - strcpy(filelist + strlen(filelist)-2, ".mod"); - - file = grab_file(filelist, &len); - if (!file) { - fprintf(stderr, "Warning: could not find versions for %s\n", - filelist); - return 0; - } - - sources = strchr(file, '\n'); - if (!sources) { - fprintf(stderr, "Warning: malformed versions file for %s\n", - modname); - goto release; - } - - sources++; - end = strchr(sources, '\n'); - if (!end) { - fprintf(stderr, "Warning: bad ending versions file for %s\n", - modname); - goto release; - } - *end = '\0'; - - md4_init(&md); - for (fname = strtok(sources, " "); fname; fname = strtok(NULL, " ")) { - if (!parse_source_files(fname, &md)) - goto release; - } - - /* sum is of form \0. */ - md4_final_ascii(&md, sum, 1 + strlen(sum+1)); - ret = 1; -release: - release_file(file, len); - return ret; -} - -static void write_version(const char *filename, const char *sum, - unsigned long offset) -{ - int fd; - - fd = open(filename, O_RDWR); - if (fd < 0) { - fprintf(stderr, "Warning: changing sum in %s failed: %s\n", - filename, strerror(errno)); - return; - } - - if (lseek(fd, offset, SEEK_SET) == (off_t)-1) { - fprintf(stderr, "Warning: changing sum in %s:%lu failed: %s\n", - filename, offset, strerror(errno)); - goto out; - } - - if (write(fd, sum, strlen(sum)+1) != strlen(sum)+1) { - fprintf(stderr, "Warning: writing sum in %s failed: %s\n", - filename, strerror(errno)); - goto out; - } -out: - close(fd); -} - -void strip_rcs_crap(char *version) -{ - unsigned int len, full_len; - - if (strncmp(version, "$Revision", strlen("$Revision")) != 0) - return; - - /* Space for version string follows. */ - full_len = strlen(version) + strlen(version + strlen(version) + 1) + 2; - - /* Move string to start with version number: prefix will be - * $Revision$ or $Revision: */ - len = strlen("$Revision"); - if (version[len] == ':' || version[len] == '$') - len++; - while (isspace(version[len])) - len++; - memmove(version, version+len, full_len-len); - full_len -= len; - - /* Preserve up to next whitespace. */ - len = 0; - while (version[len] && !isspace(version[len])) - len++; - memmove(version + len, version + strlen(version), - full_len - strlen(version)); -} - -/* If the modinfo contains a "version" value, then set this. */ -void maybe_frob_version(const char *modfilename, - void *modinfo, - unsigned long modinfo_len, - unsigned long modinfo_offset) -{ - char *version, *csum; - - version = get_modinfo(modinfo, modinfo_len, "version"); - if (!version) - return; - - /* RCS $Revision gets stripped out. */ - strip_rcs_crap(version); - - /* Check against double sumversion */ - if (strchr(version, ' ')) - return; - - /* Version contains embedded NUL: second half has space for checksum */ - csum = version + strlen(version); - *(csum++) = ' '; - if (get_version(modfilename, csum)) - write_version(modfilename, version, - modinfo_offset + (version - (char *)modinfo)); -}