* 'misc' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6: (39 commits) Revert "namespace: add source file location exceptions" Coccinelle: Add contextual message Coccinelle: Fix documentation Coccinelle: Find doubled arguments to boolean or bit operators. Coccinelle: Find nested lock+irqsave functions that use the same flags variables. namespace: add source file location exceptions scripts/extract-ikconfig: add support for bzip2, lzma and lzo kbuild: check return value of asprintf() scripts/namespace.pl: improve to get more correct results scripts/namespace.pl: some bug fixes scripts/namespace.pl: update file exclusion list scripts/namespace.pl: fix wrong source path Coccinelle: Use the -no_show_diff option for org and report mode Coccinelle: Add a new mode named 'chain' Coccinelle: Use new comment format to explain kfree.cocci Coccinelle: Improve user information with a new kind of comment Coccinelle: Update documentation MAINTAINERS: Coccinelle: Update email address Documentation/kbuild: modules.txt cleanup Documentation/kbuild: major edit of modules.txt sections 5-8 ...
Unified · Split
| @@ -24,6 +24,9 @@ of many distributions, e.g. : · 23 unmodified lines | ||
| 24 | 24 | You can get the latest version released from the Coccinelle homepage at |
| 25 | 25 | http://coccinelle.lip6.fr/ |
| 26 | 26 | |
| 27 | +Information and tips about Coccinelle are also provided on the wiki | |
| 28 | +pages at http://cocci.ekstranet.diku.dk/wiki/doku.php | |
| 29 | + | |
| 27 | 30 | Once you have it, run the following command: |
| 28 | 31 | |
| 29 | 32 | ./configure |
| @@ -41,20 +44,22 @@ A Coccinelle-specific target is defined in the top level · 11 unmodified lines | ||
| 41 | 44 | Makefile. This target is named 'coccicheck' and calls the 'coccicheck' |
| 42 | 45 | front-end in the 'scripts' directory. |
| 43 | 46 | |
| 44 | −Four modes are defined: report, patch, context, and org. The mode to | |
| 47 | +Four modes are defined: patch, report, context, and org. The mode to | |
| 45 | 48 | use is specified by setting the MODE variable with 'MODE=<mode>'. |
| 46 | 49 | |
| 50 | +'patch' proposes a fix, when possible. | |
| 51 | + | |
| 47 | 52 | 'report' generates a list in the following format: |
| 48 | 53 | file:line:column-column: message |
| 49 | 54 | |
| 50 | −'patch' proposes a fix, when possible. | |
| 51 | − | |
| 52 | 55 | 'context' highlights lines of interest and their context in a |
| 53 | 56 | diff-like style.Lines of interest are indicated with '-'. |
| 54 | 57 | |
| 55 | 58 | 'org' generates a report in the Org mode format of Emacs. |
| 56 | 59 | |
| 57 | −Note that not all semantic patches implement all modes. | |
| 60 | +Note that not all semantic patches implement all modes. For easy use | |
| 61 | +of Coccinelle, the default mode is "chain" which tries the previous | |
| 62 | +modes in the order above until one succeeds. | |
| 58 | 63 | |
| 59 | 64 | To make a report for every semantic patch, run the following command: |
| 60 | 65 | |
| @@ -68,9 +73,9 @@ To produce patches, run: · 7 unmodified lines | ||
| 68 | 73 | |
| 69 | 74 | |
| 70 | 75 | The coccicheck target applies every semantic patch available in the |
| 71 | −subdirectories of 'scripts/coccinelle' to the entire Linux kernel. | |
| 76 | +sub-directories of 'scripts/coccinelle' to the entire Linux kernel. | |
| 72 | 77 | |
| 73 | −For each semantic patch, a changelog message is proposed. It gives a | |
| 78 | +For each semantic patch, a commit message is proposed. It gives a | |
| 74 | 79 | description of the problem being checked by the semantic patch, and |
| 75 | 80 | includes a reference to Coccinelle. |
| 76 | 81 | |
| @@ -93,12 +98,35 @@ or · 16 unmodified lines | ||
| 93 | 98 | make coccicheck COCCI=<my_SP.cocci> MODE=report |
| 94 | 99 | |
| 95 | 100 | |
| 101 | + Using Coccinelle on (modified) files | |
| 102 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
| 103 | + | |
| 104 | +To apply Coccinelle on a file basis, instead of a directory basis, the | |
| 105 | +following command may be used: | |
| 106 | + | |
| 107 | + make C=1 CHECK="scripts/coccicheck" | |
| 108 | + | |
| 109 | +To check only newly edited code, use the value 2 for the C flag, i.e. | |
| 110 | + | |
| 111 | + make C=2 CHECK="scripts/coccicheck" | |
| 112 | + | |
| 113 | +This runs every semantic patch in scripts/coccinelle by default. The | |
| 114 | +COCCI variable may additionally be used to only apply a single | |
| 115 | +semantic patch as shown in the previous section. | |
| 116 | + | |
| 117 | +The "chain" mode is the default. You can select another one with the | |
| 118 | +MODE variable explained above. | |
| 119 | + | |
| 120 | +In this mode, there is no information about semantic patches | |
| 121 | +displayed, and no commit message proposed. | |
| 122 | + | |
| 123 | + | |
| 96 | 124 | Proposing new semantic patches |
| 97 | 125 | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 98 | 126 | |
| 99 | 127 | New semantic patches can be proposed and submitted by kernel |
| 100 | 128 | developers. For sake of clarity, they should be organized in the |
| 101 | −subdirectories of 'scripts/coccinelle/'. | |
| 129 | +sub-directories of 'scripts/coccinelle/'. | |
| 102 | 130 | |
| 103 | 131 | |
| 104 | 132 | Detailed description of the 'report' mode |
| @@ -111,7 +139,7 @@ Example: · 6 unmodified lines | ||
| 111 | 139 | |
| 112 | 140 | Running |
| 113 | 141 | |
| 114 | − make coccicheck MODE=report COCCI=scripts/coccinelle/err_cast.cocci | |
| 142 | + make coccicheck MODE=report COCCI=scripts/coccinelle/api/err_cast.cocci | |
| 115 | 143 | |
| 116 | 144 | will execute the following part of the SmPL script. |
| 117 | 145 | |
| @@ -149,7 +177,7 @@ identified. · 31 unmodified lines | ||
| 149 | 177 | Example: |
| 150 | 178 | |
| 151 | 179 | Running |
| 152 | − make coccicheck MODE=patch COCCI=scripts/coccinelle/err_cast.cocci | |
| 180 | + make coccicheck MODE=patch COCCI=scripts/coccinelle/api/err_cast.cocci | |
| 153 | 181 | |
| 154 | 182 | will execute the following part of the SmPL script. |
| 155 | 183 | |
| @@ -193,7 +221,7 @@ NOTE: The diff-like output generated is NOT an applicable patch. The · 37 unmodified lines | ||
| 193 | 221 | Example: |
| 194 | 222 | |
| 195 | 223 | Running |
| 196 | − make coccicheck MODE=context COCCI=scripts/coccinelle/err_cast.cocci | |
| 224 | + make coccicheck MODE=context COCCI=scripts/coccinelle/api/err_cast.cocci | |
| 197 | 225 | |
| 198 | 226 | will execute the following part of the SmPL script. |
| 199 | 227 | |
| @@ -228,7 +256,7 @@ diff -u -p /home/user/linux/crypto/ctr.c /tmp/nothing · 28 unmodified lines | ||
| 228 | 256 | Example: |
| 229 | 257 | |
| 230 | 258 | Running |
| 231 | − make coccicheck MODE=org COCCI=scripts/coccinelle/err_cast.cocci | |
| 259 | + make coccicheck MODE=org COCCI=scripts/coccinelle/api/err_cast.cocci | |
| 232 | 260 | |
| 233 | 261 | will execute the following part of the SmPL script. |
| 234 | 262 | |
| @@ -1,215 +1,185 @@ | ||
| 1 | +Building External Modules | |
| 1 | 2 | |
| 2 | −In this document you will find information about: | |
| 3 | −- how to build external modules | |
| 4 | −- how to make your module use the kbuild infrastructure | |
| 5 | −- how kbuild will install a kernel | |
| 6 | −- how to install modules in a non-standard location | |
| 3 | +This document describes how to build an out-of-tree kernel module. | |
| 7 | 4 | |
| 8 | 5 | === Table of Contents |
| 9 | 6 | |
| 10 | 7 | === 1 Introduction |
| 11 | − === 2 How to build external modules | |
| 12 | − --- 2.1 Building external modules | |
| 13 | − --- 2.2 Available targets | |
| 14 | − --- 2.3 Available options | |
| 15 | − --- 2.4 Preparing the kernel tree for module build | |
| 16 | − --- 2.5 Building separate files for a module | |
| 17 | − === 3. Example commands | |
| 18 | − === 4. Creating a kbuild file for an external module | |
| 19 | − === 5. Include files | |
| 20 | − --- 5.1 How to include files from the kernel include dir | |
| 21 | − --- 5.2 External modules using an include/ dir | |
| 22 | − --- 5.3 External modules using several directories | |
| 23 | − === 6. Module installation | |
| 24 | − --- 6.1 INSTALL_MOD_PATH | |
| 25 | − --- 6.2 INSTALL_MOD_DIR | |
| 26 | − === 7. Module versioning & Module.symvers | |
| 27 | − --- 7.1 Symbols from the kernel (vmlinux + modules) | |
| 28 | − --- 7.2 Symbols and external modules | |
| 29 | − --- 7.3 Symbols from another external module | |
| 30 | − === 8. Tips & Tricks | |
| 31 | − --- 8.1 Testing for CONFIG_FOO_BAR | |
| 8 | + === 2 How to Build External Modules | |
| 9 | + --- 2.1 Command Syntax | |
| 10 | + --- 2.2 Options | |
| 11 | + --- 2.3 Targets | |
| 12 | + --- 2.4 Building Separate Files | |
| 13 | + === 3. Creating a Kbuild File for an External Module | |
| 14 | + --- 3.1 Shared Makefile | |
| 15 | + --- 3.2 Separate Kbuild file and Makefile | |
| 16 | + --- 3.3 Binary Blobs | |
| 17 | + --- 3.4 Building Multiple Modules | |
| 18 | + === 4. Include Files | |
| 19 | + --- 4.1 Kernel Includes | |
| 20 | + --- 4.2 Single Subdirectory | |
| 21 | + --- 4.3 Several Subdirectories | |
| 22 | + === 5. Module Installation | |
| 23 | + --- 5.1 INSTALL_MOD_PATH | |
| 24 | + --- 5.2 INSTALL_MOD_DIR | |
| 25 | + === 6. Module Versioning | |
| 26 | + --- 6.1 Symbols From the Kernel (vmlinux + modules) | |
| 27 | + --- 6.2 Symbols and External Modules | |
| 28 | + --- 6.3 Symbols From Another External Module | |
| 29 | + === 7. Tips & Tricks | |
| 30 | + --- 7.1 Testing for CONFIG_FOO_BAR | |
| 32 | 31 | |
| 33 | 32 | |
| 34 | 33 | |
| 35 | 34 | === 1. Introduction |
| 36 | 35 | |
| 37 | −kbuild includes functionality for building modules both | |
| 38 | −within the kernel source tree and outside the kernel source tree. | |
| 39 | −The latter is usually referred to as external or "out-of-tree" | |
| 40 | −modules and is used both during development and for modules that | |
| 41 | −are not planned to be included in the kernel tree. | |
| 36 | +"kbuild" is the build system used by the Linux kernel. Modules must use | |
| 37 | +kbuild to stay compatible with changes in the build infrastructure and | |
| 38 | +to pick up the right flags to "gcc." Functionality for building modules | |
| 39 | +both in-tree and out-of-tree is provided. The method for building | |
| 40 | +either is similar, and all modules are initially developed and built | |
| 41 | +out-of-tree. | |
| 42 | 42 | |
| 43 | −What is covered within this file is mainly information to authors | |
| 44 | −of modules. The author of an external module should supply | |
| 45 | −a makefile that hides most of the complexity, so one only has to type | |
| 46 | −'make' to build the module. A complete example will be presented in | |
| 47 | −chapter 4, "Creating a kbuild file for an external module". | |
| 43 | +Covered in this document is information aimed at developers interested | |
| 44 | +in building out-of-tree (or "external") modules. The author of an | |
| 45 | +external module should supply a makefile that hides most of the | |
| 46 | +complexity, so one only has to type "make" to build the module. This is | |
| 47 | +easily accomplished, and a complete example will be presented in | |
| 48 | +section 3. | |
| 48 | 49 | |
| 49 | 50 | |
| 50 | −=== 2. How to build external modules | |
| 51 | +=== 2. How to Build External Modules | |
| 51 | 52 | |
| 52 | −kbuild offers functionality to build external modules, with the | |
| 53 | −prerequisite that there is a pre-built kernel available with full source. | |
| 54 | −A subset of the targets available when building the kernel is available | |
| 55 | −when building an external module. | |
| 53 | +To build external modules, you must have a prebuilt kernel available | |
| 54 | +that contains the configuration and header files used in the build. | |
| 55 | +Also, the kernel must have been built with modules enabled. If you are | |
| 56 | +using a distribution kernel, there will be a package for the kernel you | |
| 57 | +are running provided by your distribution. | |
| 56 | 58 | |
| 57 | −--- 2.1 Building external modules | |
| 59 | +An alternative is to use the "make" target "modules_prepare." This will | |
| 60 | +make sure the kernel contains the information required. The target | |
| 61 | +exists solely as a simple way to prepare a kernel source tree for | |
| 62 | +building external modules. | |
| 58 | 63 | |
| 59 | − Use the following command to build an external module: | |
| 64 | +NOTE: "modules_prepare" will not build Module.symvers even if | |
| 65 | +CONFIG_MODVERSIONS is set; therefore, a full kernel build needs to be | |
| 66 | +executed to make module versioning work. | |
| 60 | 67 | |
| 61 | − make -C <path-to-kernel> M=`pwd` | |
| 68 | +--- 2.1 Command Syntax | |
| 62 | 69 | |
| 63 | − For the running kernel use: | |
| 70 | + The command to build an external module is: | |
| 64 | 71 | |
| 65 | − make -C /lib/modules/`uname -r`/build M=`pwd` | |
| 72 | + $ make -C <path_to_kernel_src> M=$PWD | |
| 66 | 73 | |
| 67 | − For the above command to succeed, the kernel must have been | |
| 68 | − built with modules enabled. | |
| 74 | + The kbuild system knows that an external module is being built | |
| 75 | + due to the "M=<dir>" option given in the command. | |
| 69 | 76 | |
| 70 | − To install the modules that were just built: | |
| 77 | + To build against the running kernel use: | |
| 71 | 78 | |
| 72 | − make -C <path-to-kernel> M=`pwd` modules_install | |
| 79 | + $ make -C /lib/modules/`uname -r`/build M=$PWD | |
| 73 | 80 | |
| 74 | − More complex examples will be shown later, the above should | |
| 75 | − be enough to get you started. | |
| 81 | + Then to install the module(s) just built, add the target | |
| 82 | + "modules_install" to the command: | |
| 76 | 83 | |
| 77 | −--- 2.2 Available targets | |
| 84 | + $ make -C /lib/modules/`uname -r`/build M=$PWD modules_install | |
| 78 | 85 | |
| 79 | − $KDIR refers to the path to the kernel source top-level directory | |
| 86 | +--- 2.2 Options | |
| 80 | 87 | |
| 81 | − make -C $KDIR M=`pwd` | |
| 82 | − Will build the module(s) located in current directory. | |
| 83 | − All output files will be located in the same directory | |
| 84 | − as the module source. | |
| 85 | − No attempts are made to update the kernel source, and it is | |
| 86 | − a precondition that a successful make has been executed | |
| 87 | − for the kernel. | |
| 88 | + ($KDIR refers to the path of the kernel source directory.) | |
| 88 | 89 | |
| 89 | − make -C $KDIR M=`pwd` modules | |
| 90 | − The modules target is implied when no target is given. | |
| 91 | − Same functionality as if no target was specified. | |
| 92 | − See description above. | |
| 90 | + make -C $KDIR M=$PWD | |
| 93 | 91 | |
| 94 | − make -C $KDIR M=`pwd` modules_install | |
| 95 | − Install the external module(s). | |
| 96 | − Installation default is in /lib/modules/<kernel-version>/extra, | |
| 97 | − but may be prefixed with INSTALL_MOD_PATH - see separate | |
| 98 | − chapter. | |
| 92 | + -C $KDIR | |
| 93 | + The directory where the kernel source is located. | |
| 94 | + "make" will actually change to the specified directory | |
| 95 | + when executing and will change back when finished. | |
| 99 | 96 | |
| 100 | − make -C $KDIR M=`pwd` clean | |
| 101 | − Remove all generated files for the module - the kernel | |
| 102 | − source directory is not modified. | |
| 97 | + M=$PWD | |
| 98 | + Informs kbuild that an external module is being built. | |
| 99 | + The value given to "M" is the absolute path of the | |
| 100 | + directory where the external module (kbuild file) is | |
| 101 | + located. | |
| 103 | 102 | |
| 104 | − make -C $KDIR M=`pwd` help | |
| 105 | − help will list the available target when building external | |
| 106 | − modules. | |
| 103 | +--- 2.3 Targets | |
| 107 | 104 | |
| 108 | −--- 2.3 Available options: | |
| 105 | + When building an external module, only a subset of the "make" | |
| 106 | + targets are available. | |
| 109 | 107 | |
| 110 | − $KDIR refers to the path to the kernel source top-level directory | |
| 108 | + make -C $KDIR M=$PWD [target] | |
| 111 | 109 | |
| 112 | − make -C $KDIR | |
| 113 | − Used to specify where to find the kernel source. | |
| 114 | − '$KDIR' represent the directory where the kernel source is. | |
| 115 | − Make will actually change directory to the specified directory | |
| 116 | − when executed but change back when finished. | |
| 110 | + The default will build the module(s) located in the current | |
| 111 | + directory, so a target does not need to be specified. All | |
| 112 | + output files will also be generated in this directory. No | |
| 113 | + attempts are made to update the kernel source, and it is a | |
| 114 | + precondition that a successful "make" has been executed for the | |
| 115 | + kernel. | |
| 117 | 116 | |
| 118 | − make -C $KDIR M=`pwd` | |
| 119 | − M= is used to tell kbuild that an external module is | |
| 120 | − being built. | |
| 121 | − The option given to M= is the directory where the external | |
| 122 | − module (kbuild file) is located. | |
| 123 | − When an external module is being built only a subset of the | |
| 124 | − usual targets are available. | |
| 117 | + modules | |
| 118 | + The default target for external modules. It has the | |
| 119 | + same functionality as if no target was specified. See | |
| 120 | + description above. | |
| 125 | 121 | |
| 126 | − make -C $KDIR SUBDIRS=`pwd` | |
| 127 | − Same as M=. The SUBDIRS= syntax is kept for backwards | |
| 128 | − compatibility. | |
| 122 | + modules_install | |
| 123 | + Install the external module(s). The default location is | |
| 124 | + /lib/modules/<kernel_release>/extra/, but a prefix may | |
| 125 | + be added with INSTALL_MOD_PATH (discussed in section 5). | |
| 129 | 126 | |
| 130 | −--- 2.4 Preparing the kernel tree for module build | |
| 127 | + clean | |
| 128 | + Remove all generated files in the module directory only. | |
| 131 | 129 | |
| 132 | − To make sure the kernel contains the information required to | |
| 133 | − build external modules the target 'modules_prepare' must be used. | |
| 134 | − 'modules_prepare' exists solely as a simple way to prepare | |
| 135 | − a kernel source tree for building external modules. | |
| 136 | − Note: modules_prepare will not build Module.symvers even if | |
| 137 | − CONFIG_MODVERSIONS is set. Therefore a full kernel build | |
| 138 | − needs to be executed to make module versioning work. | |
| 130 | + help | |
| 131 | + List the available targets for external modules. | |
| 139 | 132 | |
| 140 | −--- 2.5 Building separate files for a module | |
| 141 | − It is possible to build single files which are part of a module. | |
| 142 | − This works equally well for the kernel, a module and even for | |
| 143 | − external modules. | |
| 144 | − Examples (module foo.ko, consist of bar.o, baz.o): | |
| 145 | − make -C $KDIR M=`pwd` bar.lst | |
| 146 | − make -C $KDIR M=`pwd` bar.o | |
| 147 | − make -C $KDIR M=`pwd` foo.ko | |
| 148 | − make -C $KDIR M=`pwd` / | |
| 149 | − | |
| 150 | − | |
| 151 | −=== 3. Example commands | |
| 152 | − | |
| 153 | −This example shows the actual commands to be executed when building | |
| 154 | −an external module for the currently running kernel. | |
| 155 | −In the example below, the distribution is supposed to use the | |
| 156 | −facility to locate output files for a kernel compile in a different | |
| 157 | −directory than the kernel source - but the examples will also work | |
| 158 | −when the source and the output files are mixed in the same directory. | |
| 133 | +--- 2.4 Building Separate Files | |
| 159 | 134 | |
| 160 | −# Kernel source | |
| 161 | −/lib/modules/<kernel-version>/source -> /usr/src/linux-<version> | |
| 162 | − | |
| 163 | −# Output from kernel compile | |
| 164 | −/lib/modules/<kernel-version>/build -> /usr/src/linux-<version>-up | |
| 165 | − | |
| 166 | −Change to the directory where the kbuild file is located and execute | |
| 167 | −the following commands to build the module: | |
| 135 | + It is possible to build single files that are part of a module. | |
| 136 | + This works equally well for the kernel, a module, and even for | |
| 137 | + external modules. | |
| 168 | 138 | |
| 169 | − cd /home/user/src/module | |
| 170 | − make -C /usr/src/`uname -r`/source \ | |
| 171 | − O=/lib/modules/`uname-r`/build \ | |
| 172 | − M=`pwd` | |
| 139 | + Example (The module foo.ko, consist of bar.o and baz.o): | |
| 140 | + make -C $KDIR M=$PWD bar.lst | |
| 141 | + make -C $KDIR M=$PWD baz.o | |
| 142 | + make -C $KDIR M=$PWD foo.ko | |
| 143 | + make -C $KDIR M=$PWD / | |
| 173 | 144 | |
| 174 | −Then, to install the module use the following command: | |
| 175 | 145 | |
| 176 | − make -C /usr/src/`uname -r`/source \ | |
| 177 | − O=/lib/modules/`uname-r`/build \ | |
| 178 | − M=`pwd` \ | |
| 179 | − modules_install | |
| 146 | +=== 3. Creating a Kbuild File for an External Module | |
| 180 | 147 | |
| 181 | −If you look closely you will see that this is the same command as | |
| 182 | −listed before - with the directories spelled out. | |
| 148 | +In the last section we saw the command to build a module for the | |
| 149 | +running kernel. The module is not actually built, however, because a | |
| 150 | +build file is required. Contained in this file will be the name of | |
| 151 | +the module(s) being built, along with the list of requisite source | |
| 152 | +files. The file may be as simple as a single line: | |
| 183 | 153 | |
| 184 | −The above are rather long commands, and the following chapter | |
| 185 | −lists a few tricks to make it all easier. | |
| 154 | + obj-m := <module_name>.o | |
| 186 | 155 | |
| 156 | +The kbuild system will build <module_name>.o from <module_name>.c, | |
| 157 | +and, after linking, will result in the kernel module <module_name>.ko. | |
| 158 | +The above line can be put in either a "Kbuild" file or a "Makefile." | |
| 159 | +When the module is built from multiple sources, an additional line is | |
| 160 | +needed listing the files: | |
| 187 | 161 | |
| 188 | −=== 4. Creating a kbuild file for an external module | |
| 162 | + <module_name>-y := <src1>.o <src2>.o ... | |
| 189 | 163 | |
| 190 | −kbuild is the build system for the kernel, and external modules | |
| 191 | −must use kbuild to stay compatible with changes in the build system | |
| 192 | −and to pick up the right flags to gcc etc. | |
| 164 | +NOTE: Further documentation describing the syntax used by kbuild is | |
| 165 | +located in Documentation/kbuild/makefiles.txt. | |
| 193 | 166 | |
| 194 | −The kbuild file used as input shall follow the syntax described | |
| 195 | −in Documentation/kbuild/makefiles.txt. This chapter will introduce a few | |
| 196 | −more tricks to be used when dealing with external modules. | |
| 167 | +The examples below demonstrate how to create a build file for the | |
| 168 | +module 8123.ko, which is built from the following files: | |
| 197 | 169 | |
| 198 | −In the following a Makefile will be created for a module with the | |
| 199 | −following files: | |
| 200 | 170 | 8123_if.c |
| 201 | 171 | 8123_if.h |
| 202 | 172 | 8123_pci.c |
| 203 | 173 | 8123_bin.o_shipped <= Binary blob |
| 204 | 174 | |
| 205 | −--- 4.1 Shared Makefile for module and kernel | |
| 175 | +--- 3.1 Shared Makefile | |
| 206 | 176 | |
| 207 | − An external module always includes a wrapper Makefile supporting | |
| 208 | − building the module using 'make' with no arguments. | |
| 209 | − The Makefile provided will most likely include additional | |
| 210 | − functionality such as test targets etc. and this part shall | |
| 211 | − be filtered away from kbuild since it may impact kbuild if | |
| 212 | − name clashes occurs. | |
| 177 | + An external module always includes a wrapper makefile that | |
| 178 | + supports building the module using "make" with no arguments. | |
| 179 | + This target is not used by kbuild; it is only for convenience. | |
| 180 | + Additional functionality, such as test targets, can be included | |
| 181 | + but should be filtered out from kbuild due to possible name | |
| 182 | + clashes. | |
| 213 | 183 | |
| 214 | 184 | Example 1: |
| 215 | 185 | --> filename: Makefile |
| @@ -219,11 +189,11 @@ following files: · 3 unmodified lines | ||
| 219 | 189 | 8123-y := 8123_if.o 8123_pci.o 8123_bin.o |
| 220 | 190 | |
| 221 | 191 | else |
| 222 | − # Normal Makefile | |
| 192 | + # normal makefile | |
| 193 | + KDIR ?= /lib/modules/`uname -r`/build | |
| 223 | 194 | |
| 224 | − KERNELDIR := /lib/modules/`uname -r`/build | |
| 225 | − all:: | |
| 226 | − $(MAKE) -C $(KERNELDIR) M=`pwd` $@ | |
| 195 | + default: | |
| 196 | + $(MAKE) -C $(KDIR) M=$$PWD | |
| 227 | 197 | |
| 228 | 198 | # Module specific targets |
| 229 | 199 | genbin: |
| @@ -231,15 +201,20 @@ following files: · 1 unmodified line | ||
| 231 | 201 | |
| 232 | 202 | endif |
| 233 | 203 | |
| 234 | − In example 1, the check for KERNELRELEASE is used to separate | |
| 235 | − the two parts of the Makefile. kbuild will only see the two | |
| 236 | − assignments whereas make will see everything except the two | |
| 237 | − kbuild assignments. | |
| 204 | + The check for KERNELRELEASE is used to separate the two parts | |
| 205 | + of the makefile. In the example, kbuild will only see the two | |
| 206 | + assignments, whereas "make" will see everything except these | |
| 207 | + two assignments. This is due to two passes made on the file: | |
| 208 | + the first pass is by the "make" instance run on the command | |
| 209 | + line; the second pass is by the kbuild system, which is | |
| 210 | + initiated by the parameterized "make" in the default target. | |
| 211 | + | |
| 212 | +--- 3.2 Separate Kbuild File and Makefile | |
| 238 | 213 | |
| 239 | − In recent versions of the kernel, kbuild will look for a file named | |
| 240 | − Kbuild and as second option look for a file named Makefile. | |
| 241 | − Utilising the Kbuild file makes us split up the Makefile in example 1 | |
| 242 | − into two files as shown in example 2: | |
| 214 | + In newer versions of the kernel, kbuild will first look for a | |
| 215 | + file named "Kbuild," and only if that is not found, will it | |
| 216 | + then look for a makefile. Utilizing a "Kbuild" file allows us | |
| 217 | + to split up the makefile from example 1 into two files: | |
| 243 | 218 | |
| 244 | 219 | Example 2: |
| 245 | 220 | --> filename: Kbuild |
| @@ -247,20 +222,21 @@ following files: · 1 unmodified line | ||
| 247 | 222 | 8123-y := 8123_if.o 8123_pci.o 8123_bin.o |
| 248 | 223 | |
| 249 | 224 | --> filename: Makefile |
| 250 | − KERNELDIR := /lib/modules/`uname -r`/build | |
| 251 | − all:: | |
| 252 | − $(MAKE) -C $(KERNELDIR) M=`pwd` $@ | |
| 225 | + KDIR ?= /lib/modules/`uname -r`/build | |
| 226 | + | |
| 227 | + default: | |
| 228 | + $(MAKE) -C $(KDIR) M=$$PWD | |
| 253 | 229 | |
| 254 | 230 | # Module specific targets |
| 255 | 231 | genbin: |
| 256 | 232 | echo "X" > 8123_bin.o_shipped |
| 257 | 233 | |
| 234 | + The split in example 2 is questionable due to the simplicity of | |
| 235 | + each file; however, some external modules use makefiles | |
| 236 | + consisting of several hundred lines, and here it really pays | |
| 237 | + off to separate the kbuild part from the rest. | |
| 258 | 238 | |
| 259 | − In example 2, we are down to two fairly simple files and for simple | |
| 260 | − files as used in this example the split is questionable. But some | |
| 261 | − external modules use Makefiles of several hundred lines and here it | |
| 262 | − really pays off to separate the kbuild part from the rest. | |
| 263 | − Example 3 shows a backward compatible version. | |
| 239 | + The next example shows a backward compatible version. | |
| 264 | 240 | |
| 265 | 241 | Example 3: |
| 266 | 242 | --> filename: Kbuild |
| @@ -269,13 +245,15 @@ following files: · 2 unmodified lines | ||
| 269 | 245 | |
| 270 | 246 | --> filename: Makefile |
| 271 | 247 | ifneq ($(KERNELRELEASE),) |
| 248 | + # kbuild part of makefile | |
| 272 | 249 | include Kbuild |
| 250 | + | |
| 273 | 251 | else |
| 274 | − # Normal Makefile | |
| 252 | + # normal makefile | |
| 253 | + KDIR ?= /lib/modules/`uname -r`/build | |
| 275 | 254 | |
| 276 | − KERNELDIR := /lib/modules/`uname -r`/build | |
| 277 | − all:: | |
| 278 | − $(MAKE) -C $(KERNELDIR) M=`pwd` $@ | |
| 255 | + default: | |
| 256 | + $(MAKE) -C $(KDIR) M=$$PWD | |
| 279 | 257 | |
| 280 | 258 | # Module specific targets |
| 281 | 259 | genbin: |
| @@ -283,260 +261,271 @@ following files: · 1 unmodified line | ||
| 283 | 261 | |
| 284 | 262 | endif |
| 285 | 263 | |
| 286 | − The trick here is to include the Kbuild file from Makefile, so | |
| 287 | − if an older version of kbuild picks up the Makefile, the Kbuild | |
| 288 | − file will be included. | |
| 264 | + Here the "Kbuild" file is included from the makefile. This | |
| 265 | + allows an older version of kbuild, which only knows of | |
| 266 | + makefiles, to be used when the "make" and kbuild parts are | |
| 267 | + split into separate files. | |
| 289 | 268 | |
| 290 | −--- 4.2 Binary blobs included in a module | |
| 269 | +--- 3.3 Binary Blobs | |
| 291 | 270 | |
| 292 | − Some external modules needs to include a .o as a blob. kbuild | |
| 293 | − has support for this, but requires the blob file to be named | |
| 294 | − <filename>_shipped. In our example the blob is named | |
| 295 | − 8123_bin.o_shipped and when the kbuild rules kick in the file | |
| 296 | − 8123_bin.o is created as a simple copy off the 8213_bin.o_shipped file | |
| 297 | − with the _shipped part stripped of the filename. | |
| 298 | − This allows the 8123_bin.o filename to be used in the assignment to | |
| 299 | − the module. | |
| 271 | + Some external modules need to include an object file as a blob. | |
| 272 | + kbuild has support for this, but requires the blob file to be | |
| 273 | + named <filename>_shipped. When the kbuild rules kick in, a copy | |
| 274 | + of <filename>_shipped is created with _shipped stripped off, | |
| 275 | + giving us <filename>. This shortened filename can be used in | |
| 276 | + the assignment to the module. | |
| 277 | + | |
| 278 | + Throughout this section, 8123_bin.o_shipped has been used to | |
| 279 | + build the kernel module 8123.ko; it has been included as | |
| 280 | + 8123_bin.o. | |
| 300 | 281 | |
| 301 | − Example 4: | |
| 302 | − obj-m := 8123.o | |
| 303 | 282 | 8123-y := 8123_if.o 8123_pci.o 8123_bin.o |
| 304 | 283 | |
| 305 | − In example 4, there is no distinction between the ordinary .c/.h files | |
| 306 | − and the binary file. But kbuild will pick up different rules to create | |
| 307 | − the .o file. | |
| 284 | + Although there is no distinction between the ordinary source | |
| 285 | + files and the binary file, kbuild will pick up different rules | |
| 286 | + when creating the object file for the module. | |
| 287 | + | |
| 288 | +--- 3.4 Building Multiple Modules | |
| 308 | 289 | |
| 290 | + kbuild supports building multiple modules with a single build | |
| 291 | + file. For example, if you wanted to build two modules, foo.ko | |
| 292 | + and bar.ko, the kbuild lines would be: | |
| 309 | 293 | |
| 310 | −=== 5. Include files | |
| 294 | + obj-m := foo.o bar.o | |
| 295 | + foo-y := <foo_srcs> | |
| 296 | + bar-y := <bar_srcs> | |
| 311 | 297 | |
| 312 | −Include files are a necessity when a .c file uses something from other .c | |
| 313 | −files (not strictly in the sense of C, but if good programming practice is | |
| 314 | −used). Any module that consists of more than one .c file will have a .h file | |
| 315 | −for one of the .c files. | |
| 298 | + It is that simple! | |
| 316 | 299 | |
| 317 | −- If the .h file only describes a module internal interface, then the .h file | |
| 318 | − shall be placed in the same directory as the .c files. | |
| 319 | −- If the .h files describe an interface used by other parts of the kernel | |
| 320 | − located in different directories, the .h files shall be located in | |
| 321 | − include/linux/ or other include/ directories as appropriate. | |
| 322 | 300 | |
| 323 | −One exception for this rule is larger subsystems that have their own directory | |
| 324 | −under include/ such as include/scsi. Another exception is arch-specific | |
| 325 | −.h files which are located under include/asm-$(ARCH)/*. | |
| 301 | +=== 4. Include Files | |
| 326 | 302 | |
| 327 | −External modules have a tendency to locate include files in a separate include/ | |
| 328 | −directory and therefore need to deal with this in their kbuild file. | |
| 303 | +Within the kernel, header files are kept in standard locations | |
| 304 | +according to the following rule: | |
| 329 | 305 | |
| 330 | −--- 5.1 How to include files from the kernel include dir | |
| 306 | + * If the header file only describes the internal interface of a | |
| 307 | + module, then the file is placed in the same directory as the | |
| 308 | + source files. | |
| 309 | + * If the header file describes an interface used by other parts | |
| 310 | + of the kernel that are located in different directories, then | |
| 311 | + the file is placed in include/linux/. | |
| 331 | 312 | |
| 332 | − When a module needs to include a file from include/linux/, then one | |
| 333 | − just uses: | |
| 313 | + NOTE: There are two notable exceptions to this rule: larger | |
| 314 | + subsystems have their own directory under include/, such as | |
| 315 | + include/scsi; and architecture specific headers are located | |
| 316 | + under arch/$(ARCH)/include/. | |
| 334 | 317 | |
| 335 | − #include <linux/modules.h> | |
| 318 | +--- 4.1 Kernel Includes | |
| 336 | 319 | |
| 337 | − kbuild will make sure to add options to gcc so the relevant | |
| 338 | − directories are searched. | |
| 339 | − Likewise for .h files placed in the same directory as the .c file. | |
| 320 | + To include a header file located under include/linux/, simply | |
| 321 | + use: | |
| 340 | 322 | |
| 341 | − #include "8123_if.h" | |
| 323 | + #include <linux/module.h> | |
| 342 | 324 | |
| 343 | − will do the job. | |
| 325 | + kbuild will add options to "gcc" so the relevant directories | |
| 326 | + are searched. | |
| 344 | 327 | |
| 345 | −--- 5.2 External modules using an include/ dir | |
| 328 | +--- 4.2 Single Subdirectory | |
| 346 | 329 | |
| 347 | − External modules often locate their .h files in a separate include/ | |
| 348 | − directory although this is not usual kernel style. When an external | |
| 349 | − module uses an include/ dir then kbuild needs to be told so. | |
| 350 | − The trick here is to use either EXTRA_CFLAGS (take effect for all .c | |
| 351 | − files) or CFLAGS_$F.o (take effect only for a single file). | |
| 330 | + External modules tend to place header files in a separate | |
| 331 | + include/ directory where their source is located, although this | |
| 332 | + is not the usual kernel style. To inform kbuild of the | |
| 333 | + directory, use either ccflags-y or CFLAGS_<filename>.o. | |
| 352 | 334 | |
| 353 | − In our example, if we move 8123_if.h to a subdirectory named include/ | |
| 354 | − the resulting Kbuild file would look like: | |
| 335 | + Using the example from section 3, if we moved 8123_if.h to a | |
| 336 | + subdirectory named include, the resulting kbuild file would | |
| 337 | + look like: | |
| 355 | 338 | |
| 356 | 339 | --> filename: Kbuild |
| 357 | − obj-m := 8123.o | |
| 340 | + obj-m := 8123.o | |
| 358 | 341 | |
| 359 | − EXTRA_CFLAGS := -Iinclude | |
| 342 | + ccflags-y := -Iinclude | |
| 360 | 343 | 8123-y := 8123_if.o 8123_pci.o 8123_bin.o |
| 361 | 344 | |
| 362 | − Note that in the assignment there is no space between -I and the path. | |
| 363 | − This is a kbuild limitation: there must be no space present. | |
| 345 | + Note that in the assignment there is no space between -I and | |
| 346 | + the path. This is a limitation of kbuild: there must be no | |
| 347 | + space present. | |
| 364 | 348 | |
| 365 | −--- 5.3 External modules using several directories | |
| 366 | − | |
| 367 | − If an external module does not follow the usual kernel style, but | |
| 368 | − decides to spread files over several directories, then kbuild can | |
| 369 | − handle this too. | |
| 349 | +--- 4.3 Several Subdirectories | |
| 370 | 350 | |
| 351 | + kbuild can handle files that are spread over several directories. | |
| 371 | 352 | Consider the following example: |
| 372 | 353 | |
| 373 | − | | |
| 374 | − +- src/complex_main.c | |
| 375 | − | +- hal/hardwareif.c | |
| 376 | − | +- hal/include/hardwareif.h | |
| 377 | − +- include/complex.h | |
| 378 | − | |
| 379 | − To build a single module named complex.ko, we then need the following | |
| 354 | + . | |
| 355 | + |__ src | |
| 356 | + | |__ complex_main.c | |
| 357 | + | |__ hal | |
| 358 | + | |__ hardwareif.c | |
| 359 | + | |__ include | |
| 360 | + | |__ hardwareif.h | |
| 361 | + |__ include | |
| 362 | + |__ complex.h | |
| 363 | + | |
| 364 | + To build the module complex.ko, we then need the following | |
| 380 | 365 | kbuild file: |
| 381 | 366 | |
| 382 | − Kbuild: | |
| 367 | + --> filename: Kbuild | |
| 383 | 368 | obj-m := complex.o |
| 384 | 369 | complex-y := src/complex_main.o |
| 385 | 370 | complex-y += src/hal/hardwareif.o |
| 386 | 371 | |
| 387 | − EXTRA_CFLAGS := -I$(src)/include | |
| 388 | − EXTRA_CFLAGS += -I$(src)src/hal/include | |
| 372 | + ccflags-y := -I$(src)/include | |
| 373 | + ccflags-y += -I$(src)/src/hal/include | |
| 389 | 374 | |
| 375 | + As you can see, kbuild knows how to handle object files located | |
| 376 | + in other directories. The trick is to specify the directory | |
| 377 | + relative to the kbuild file's location. That being said, this | |
| 378 | + is NOT recommended practice. | |
| 390 | 379 | |
| 391 | − kbuild knows how to handle .o files located in another directory - | |
| 392 | − although this is NOT recommended practice. The syntax is to specify | |
| 393 | − the directory relative to the directory where the Kbuild file is | |
| 394 | − located. | |
| 380 | + For the header files, kbuild must be explicitly told where to | |
| 381 | + look. When kbuild executes, the current directory is always the | |
| 382 | + root of the kernel tree (the argument to "-C") and therefore an | |
| 383 | + absolute path is needed. $(src) provides the absolute path by | |
| 384 | + pointing to the directory where the currently executing kbuild | |
| 385 | + file is located. | |
| 395 | 386 | |
| 396 | − To find the .h files, we have to explicitly tell kbuild where to look | |
| 397 | − for the .h files. When kbuild executes, the current directory is always | |
| 398 | − the root of the kernel tree (argument to -C) and therefore we have to | |
| 399 | − tell kbuild how to find the .h files using absolute paths. | |
| 400 | − $(src) will specify the absolute path to the directory where the | |
| 401 | − Kbuild file are located when being build as an external module. | |
| 402 | − Therefore -I$(src)/ is used to point out the directory of the Kbuild | |
| 403 | − file and any additional path are just appended. | |
| 404 | 387 | |
| 405 | −=== 6. Module installation | |
| 388 | +=== 5. Module Installation | |
| 406 | 389 | |
| 407 | −Modules which are included in the kernel are installed in the directory: | |
| 390 | +Modules which are included in the kernel are installed in the | |
| 391 | +directory: | |
| 408 | 392 | |
| 409 | − /lib/modules/$(KERNELRELEASE)/kernel | |
| 393 | + /lib/modules/$(KERNELRELEASE)/kernel/ | |
| 410 | 394 | |
| 411 | −External modules are installed in the directory: | |
| 395 | +And external modules are installed in: | |
| 412 | 396 | |
| 413 | − /lib/modules/$(KERNELRELEASE)/extra | |
| 397 | + /lib/modules/$(KERNELRELEASE)/extra/ | |
| 414 | 398 | |
| 415 | −--- 6.1 INSTALL_MOD_PATH | |
| 399 | +--- 5.1 INSTALL_MOD_PATH | |
| 416 | 400 | |
| 417 | − Above are the default directories, but as always, some level of | |
| 418 | − customization is possible. One can prefix the path using the variable | |
| 419 | − INSTALL_MOD_PATH: | |
| 401 | + Above are the default directories but as always some level of | |
| 402 | + customization is possible. A prefix can be added to the | |
| 403 | + installation path using the variable INSTALL_MOD_PATH: | |
| 420 | 404 | |
| 421 | 405 | $ make INSTALL_MOD_PATH=/frodo modules_install |
| 422 | − => Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel | |
| 423 | − | |
| 424 | − INSTALL_MOD_PATH may be set as an ordinary shell variable or as in the | |
| 425 | − example above, can be specified on the command line when calling make. | |
| 426 | − INSTALL_MOD_PATH has effect both when installing modules included in | |
| 427 | − the kernel as well as when installing external modules. | |
| 406 | + => Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel/ | |
| 428 | 407 | |
| 429 | −--- 6.2 INSTALL_MOD_DIR | |
| 408 | + INSTALL_MOD_PATH may be set as an ordinary shell variable or, | |
| 409 | + as shown above, can be specified on the command line when | |
| 410 | + calling "make." This has effect when installing both in-tree | |
| 411 | + and out-of-tree modules. | |
| 430 | 412 | |
| 431 | − When installing external modules they are by default installed to a | |
| 432 | − directory under /lib/modules/$(KERNELRELEASE)/extra, but one may wish | |
| 433 | − to locate modules for a specific functionality in a separate | |
| 434 | − directory. For this purpose, one can use INSTALL_MOD_DIR to specify an | |
| 435 | − alternative name to 'extra'. | |
| 413 | +--- 5.2 INSTALL_MOD_DIR | |
| 436 | 414 | |
| 437 | − $ make INSTALL_MOD_DIR=gandalf -C KERNELDIR \ | |
| 438 | − M=`pwd` modules_install | |
| 439 | − => Install dir: /lib/modules/$(KERNELRELEASE)/gandalf | |
| 415 | + External modules are by default installed to a directory under | |
| 416 | + /lib/modules/$(KERNELRELEASE)/extra/, but you may wish to | |
| 417 | + locate modules for a specific functionality in a separate | |
| 418 | + directory. For this purpose, use INSTALL_MOD_DIR to specify an | |
| 419 | + alternative name to "extra." | |
| 440 | 420 | |
| 421 | + $ make INSTALL_MOD_DIR=gandalf -C $KDIR \ | |
| 422 | + M=$PWD modules_install | |
| 423 | + => Install dir: /lib/modules/$(KERNELRELEASE)/gandalf/ | |
| 441 | 424 | |
| 442 | −=== 7. Module versioning & Module.symvers | |
| 443 | 425 | |
| 444 | −Module versioning is enabled by the CONFIG_MODVERSIONS tag. | |
| 426 | +=== 6. Module Versioning | |
| 445 | 427 | |
| 446 | −Module versioning is used as a simple ABI consistency check. The Module | |
| 447 | −versioning creates a CRC value of the full prototype for an exported symbol and | |
| 448 | −when a module is loaded/used then the CRC values contained in the kernel are | |
| 449 | −compared with similar values in the module. If they are not equal, then the | |
| 450 | −kernel refuses to load the module. | |
| 428 | +Module versioning is enabled by the CONFIG_MODVERSIONS tag, and is used | |
| 429 | +as a simple ABI consistency check. A CRC value of the full prototype | |
| 430 | +for an exported symbol is created. When a module is loaded/used, the | |
| 431 | +CRC values contained in the kernel are compared with similar values in | |
| 432 | +the module; if they are not equal, the kernel refuses to load the | |
| 433 | +module. | |
| 451 | 434 | |
| 452 | −Module.symvers contains a list of all exported symbols from a kernel build. | |
| 435 | +Module.symvers contains a list of all exported symbols from a kernel | |
| 436 | +build. | |
| 453 | 437 | |
| 454 | −--- 7.1 Symbols from the kernel (vmlinux + modules) | |
| 438 | +--- 6.1 Symbols From the Kernel (vmlinux + modules) | |
| 455 | 439 | |
| 456 | − During a kernel build, a file named Module.symvers will be generated. | |
| 457 | − Module.symvers contains all exported symbols from the kernel and | |
| 458 | − compiled modules. For each symbols, the corresponding CRC value | |
| 459 | − is stored too. | |
| 440 | + During a kernel build, a file named Module.symvers will be | |
| 441 | + generated. Module.symvers contains all exported symbols from | |
| 442 | + the kernel and compiled modules. For each symbol, the | |
| 443 | + corresponding CRC value is also stored. | |
| 460 | 444 | |
| 461 | 445 | The syntax of the Module.symvers file is: |
| 462 | − <CRC> <Symbol> <module> | |
| 463 | − Sample: | |
| 446 | + <CRC> <Symbol> <module> | |
| 447 | + | |
| 464 | 448 | 0x2d036834 scsi_remove_host drivers/scsi/scsi_mod |
| 465 | 449 | |
| 466 | − For a kernel build without CONFIG_MODVERSIONS enabled, the crc | |
| 467 | − would read: 0x00000000 | |
| 450 | + For a kernel build without CONFIG_MODVERSIONS enabled, the CRC | |
| 451 | + would read 0x00000000. | |
| 468 | 452 | |
| 469 | 453 | Module.symvers serves two purposes: |
| 470 | − 1) It lists all exported symbols both from vmlinux and all modules | |
| 471 | − 2) It lists the CRC if CONFIG_MODVERSIONS is enabled | |
| 472 | − | |
| 473 | −--- 7.2 Symbols and external modules | |
| 474 | − | |
| 475 | − When building an external module, the build system needs access to | |
| 476 | − the symbols from the kernel to check if all external symbols are | |
| 477 | − defined. This is done in the MODPOST step and to obtain all | |
| 478 | − symbols, modpost reads Module.symvers from the kernel. | |
| 479 | − If a Module.symvers file is present in the directory where | |
| 480 | − the external module is being built, this file will be read too. | |
| 481 | − During the MODPOST step, a new Module.symvers file will be written | |
| 482 | − containing all exported symbols that were not defined in the kernel. | |
| 483 | − | |
| 484 | −--- 7.3 Symbols from another external module | |
| 485 | − | |
| 486 | − Sometimes, an external module uses exported symbols from another | |
| 487 | − external module. Kbuild needs to have full knowledge on all symbols | |
| 488 | − to avoid spitting out warnings about undefined symbols. | |
| 489 | − Three solutions exist to let kbuild know all symbols of more than | |
| 490 | − one external module. | |
| 491 | − The method with a top-level kbuild file is recommended but may be | |
| 492 | − impractical in certain situations. | |
| 493 | − | |
| 494 | − Use a top-level Kbuild file | |
| 495 | − If you have two modules: 'foo' and 'bar', and 'foo' needs | |
| 496 | − symbols from 'bar', then one can use a common top-level kbuild | |
| 497 | − file so both modules are compiled in same build. | |
| 498 | − | |
| 499 | − Consider following directory layout: | |
| 500 | − ./foo/ <= contains the foo module | |
| 501 | − ./bar/ <= contains the bar module | |
| 502 | − The top-level Kbuild file would then look like: | |
| 503 | − | |
| 504 | − #./Kbuild: (this file may also be named Makefile) | |
| 454 | + 1) It lists all exported symbols from vmlinux and all modules. | |
| 455 | + 2) It lists the CRC if CONFIG_MODVERSIONS is enabled. | |
| 456 | + | |
| 457 | +--- 6.2 Symbols and External Modules | |
| 458 | + | |
| 459 | + When building an external module, the build system needs access | |
| 460 | + to the symbols from the kernel to check if all external symbols | |
| 461 | + are defined. This is done in the MODPOST step. modpost obtains | |
| 462 | + the symbols by reading Module.symvers from the kernel source | |
| 463 | + tree. If a Module.symvers file is present in the directory | |
| 464 | + where the external module is being built, this file will be | |
| 465 | + read too. During the MODPOST step, a new Module.symvers file | |
| 466 | + will be written containing all exported symbols that were not | |
| 467 | + defined in the kernel. | |
| 468 | + | |
| 469 | +--- 6.3 Symbols From Another External Module | |
| 470 | + | |
| 471 | + Sometimes, an external module uses exported symbols from | |
| 472 | + another external module. kbuild needs to have full knowledge of | |
| 473 | + all symbols to avoid spitting out warnings about undefined | |
| 474 | + symbols. Three solutions exist for this situation. | |
| 475 | + | |
| 476 | + NOTE: The method with a top-level kbuild file is recommended | |
| 477 | + but may be impractical in certain situations. | |
| 478 | + | |
| 479 | + Use a top-level kbuild file | |
| 480 | + If you have two modules, foo.ko and bar.ko, where | |
| 481 | + foo.ko needs symbols from bar.ko, you can use a | |
| 482 | + common top-level kbuild file so both modules are | |
| 483 | + compiled in the same build. Consider the following | |
| 484 | + directory layout: | |
| 485 | + | |
| 486 | + ./foo/ <= contains foo.ko | |
| 487 | + ./bar/ <= contains bar.ko | |
| 488 | + | |
| 489 | + The top-level kbuild file would then look like: | |
| 490 | + | |
| 491 | + #./Kbuild (or ./Makefile): | |
| 505 | 492 | obj-y := foo/ bar/ |
| 506 | 493 | |
| 507 | − Executing: | |
| 508 | − make -C $KDIR M=`pwd` | |
| 494 | + And executing | |
| 495 | + | |
| 496 | + $ make -C $KDIR M=$PWD | |
| 509 | 497 | |
| 510 | − will then do the expected and compile both modules with full | |
| 511 | − knowledge on symbols from both modules. | |
| 498 | + will then do the expected and compile both modules with | |
| 499 | + full knowledge of symbols from either module. | |
| 512 | 500 | |
| 513 | 501 | Use an extra Module.symvers file |
| 514 | − When an external module is built, a Module.symvers file is | |
| 515 | − generated containing all exported symbols which are not | |
| 516 | − defined in the kernel. | |
| 517 | − To get access to symbols from module 'bar', one can copy the | |
| 518 | − Module.symvers file from the compilation of the 'bar' module | |
| 519 | − to the directory where the 'foo' module is built. | |
| 520 | − During the module build, kbuild will read the Module.symvers | |
| 521 | − file in the directory of the external module and when the | |
| 522 | − build is finished, a new Module.symvers file is created | |
| 523 | − containing the sum of all symbols defined and not part of the | |
| 524 | − kernel. | |
| 525 | − | |
| 526 | − Use make variable KBUILD_EXTRA_SYMBOLS in the Makefile | |
| 527 | − If it is impractical to copy Module.symvers from another | |
| 528 | − module, you can assign a space separated list of files to | |
| 529 | − KBUILD_EXTRA_SYMBOLS in your Makfile. These files will be | |
| 530 | − loaded by modpost during the initialisation of its symbol | |
| 531 | − tables. | |
| 532 | − | |
| 533 | −=== 8. Tips & Tricks | |
| 534 | − | |
| 535 | −--- 8.1 Testing for CONFIG_FOO_BAR | |
| 536 | − | |
| 537 | − Modules often need to check for certain CONFIG_ options to decide if | |
| 538 | − a specific feature shall be included in the module. When kbuild is used | |
| 539 | − this is done by referencing the CONFIG_ variable directly. | |
| 502 | + When an external module is built, a Module.symvers file | |
| 503 | + is generated containing all exported symbols which are | |
| 504 | + not defined in the kernel. To get access to symbols | |
| 505 | + from bar.ko, copy the Module.symvers file from the | |
| 506 | + compilation of bar.ko to the directory where foo.ko is | |
| 507 | + built. During the module build, kbuild will read the | |
| 508 | + Module.symvers file in the directory of the external | |
| 509 | + module, and when the build is finished, a new | |
| 510 | + Module.symvers file is created containing the sum of | |
| 511 | + all symbols defined and not part of the kernel. | |
| 512 | + | |
| 513 | + Use "make" variable KBUILD_EXTRA_SYMBOLS | |
| 514 | + If it is impractical to copy Module.symvers from | |
| 515 | + another module, you can assign a space separated list | |
| 516 | + of files to KBUILD_EXTRA_SYMBOLS in your build file. | |
| 517 | + These files will be loaded by modpost during the | |
| 518 | + initialization of its symbol tables. | |
| 519 | + | |
| 520 | + | |
| 521 | +=== 7. Tips & Tricks | |
| 522 | + | |
| 523 | +--- 7.1 Testing for CONFIG_FOO_BAR | |
| 524 | + | |
| 525 | + Modules often need to check for certain CONFIG_ options to | |
| 526 | + decide if a specific feature is included in the module. In | |
| 527 | + kbuild this is done by referencing the CONFIG_ variable | |
| 528 | + directly. | |
| 540 | 529 | |
| 541 | 530 | #fs/ext2/Makefile |
| 542 | 531 | obj-$(CONFIG_EXT2_FS) += ext2.o |
| @@ -544,9 +533,9 @@ Module.symvers contains a list of all exported symbols from a kernel build. · 1 unmodified line | ||
| 544 | 533 | ext2-y := balloc.o bitmap.o dir.o |
| 545 | 534 | ext2-$(CONFIG_EXT2_FS_XATTR) += xattr.o |
| 546 | 535 | |
| 547 | − External modules have traditionally used grep to check for specific | |
| 548 | − CONFIG_ settings directly in .config. This usage is broken. | |
| 549 | − As introduced before, external modules shall use kbuild when building | |
| 550 | − and therefore can use the same methods as in-kernel modules when | |
| 551 | − testing for CONFIG_ definitions. | |
| 536 | + External modules have traditionally used "grep" to check for | |
| 537 | + specific CONFIG_ settings directly in .config. This usage is | |
| 538 | + broken. As introduced before, external modules should use | |
| 539 | + kbuild for building and can therefore use the same methods as | |
| 540 | + in-tree modules when testing for CONFIG_ definitions. | |
| 552 | 541 | |
| @@ -1613,7 +1613,7 @@ F: drivers/platform/x86/classmate-laptop.c · 1612 unmodified lines | ||
| 1613 | 1613 | COCCINELLE/Semantic Patches (SmPL) |
| 1614 | 1614 | M: Julia Lawall <julia@diku.dk> |
| 1615 | 1615 | M: Gilles Muller <Gilles.Muller@lip6.fr> |
| 1616 | −M: Nicolas Palix <npalix@diku.dk> | |
| 1616 | +M: Nicolas Palix <npalix.work@gmail.com> | |
| 1617 | 1617 | L: cocci@diku.dk (moderated for non-subscribers) |
| 1618 | 1618 | W: http://coccinelle.lip6.fr/ |
| 1619 | 1619 | S: Supported |
| @@ -333,7 +333,10 @@ static void docsect(char *filename, char *line) · 332 unmodified lines | ||
| 333 | 333 | if (*s == '\n') |
| 334 | 334 | *s = '\0'; |
| 335 | 335 | |
| 336 | − asprintf(&s, "DOC: %s", line); | |
| 336 | + if (asprintf(&s, "DOC: %s", line) < 0) { | |
| 337 | + perror("asprintf"); | |
| 338 | + exit(1); | |
| 339 | + } | |
| 337 | 340 | consume_symbol(s); |
| 338 | 341 | free(s); |
| 339 | 342 | |
| @@ -16,6 +16,7 @@ if [ "$C" = "1" -o "$C" = "2" ]; then · 15 unmodified lines | ||
| 16 | 16 | else |
| 17 | 17 | ONLINE=0 |
| 18 | 18 | FLAGS="-very_quiet" |
| 19 | + OPTIONS="-dir $srctree" | |
| 19 | 20 | fi |
| 20 | 21 | |
| 21 | 22 | if [ ! -x "$SPATCH" ]; then |
| @@ -25,11 +26,13 @@ fi · 3 unmodified lines | ||
| 25 | 26 | |
| 26 | 27 | if [ "$MODE" = "" ] ; then |
| 27 | 28 | if [ "$ONLINE" = "0" ] ; then |
| 28 | − echo 'You have not explicitly specify the mode to use. Fallback to "report".' | |
| 29 | + echo 'You have not explicitly specified the mode to use. Using default "chain" mode.' | |
| 30 | + echo 'All available modes will be tried (in that order): patch, report, context, org' | |
| 29 | 31 | echo 'You can specify the mode with "make coccicheck MODE=<mode>"' |
| 30 | − echo 'Available modes are: report, patch, context, org' | |
| 31 | 32 | fi |
| 32 | − MODE="report" | |
| 33 | + MODE="chain" | |
| 34 | +elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then | |
| 35 | + FLAGS="$FLAGS -no_show_diff" | |
| 33 | 36 | fi |
| 34 | 37 | |
| 35 | 38 | if [ "$ONLINE" = "0" ] ; then |
| @@ -44,7 +47,7 @@ coccinelle () { · 8 unmodified lines | ||
| 44 | 47 | |
| 45 | 48 | OPT=`grep "Option" $COCCI | cut -d':' -f2` |
| 46 | 49 | |
| 47 | −# The option '-parse_cocci' can be used to syntaxically check the SmPL files. | |
| 50 | +# The option '-parse_cocci' can be used to syntactically check the SmPL files. | |
| 48 | 51 | # |
| 49 | 52 | # $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null |
| 50 | 53 | |
| @@ -52,21 +55,44 @@ coccinelle () { · 1 unmodified line | ||
| 52 | 55 | |
| 53 | 56 | FILE=`echo $COCCI | sed "s|$srctree/||"` |
| 54 | 57 | |
| 55 | − echo "Processing `basename $COCCI` with option(s) \"$OPT\"" | |
| 58 | + echo "Processing `basename $COCCI`" | |
| 59 | + echo "with option(s) \"$OPT\"" | |
| 60 | + echo '' | |
| 56 | 61 | echo 'Message example to submit a patch:' |
| 57 | 62 | |
| 58 | − sed -e '/\/\/\//!d' -e 's|^///||' $COCCI | |
| 59 | − | |
| 60 | − echo ' The semantic patch that makes this change is available' | |
| 63 | + sed -ne 's|^///||p' $COCCI | |
| 64 | + | |
| 65 | + if [ "$MODE" = "patch" ] ; then | |
| 66 | + echo ' The semantic patch that makes this change is available' | |
| 67 | + elif [ "$MODE" = "report" ] ; then | |
| 68 | + echo ' The semantic patch that makes this report is available' | |
| 69 | + elif [ "$MODE" = "context" ] ; then | |
| 70 | + echo ' The semantic patch that spots this code is available' | |
| 71 | + elif [ "$MODE" = "org" ] ; then | |
| 72 | + echo ' The semantic patch that makes this Org report is available' | |
| 73 | + else | |
| 74 | + echo ' The semantic patch that makes this output is available' | |
| 75 | + fi | |
| 61 | 76 | echo " in $FILE." |
| 62 | 77 | echo '' |
| 63 | 78 | echo ' More information about semantic patching is available at' |
| 64 | 79 | echo ' http://coccinelle.lip6.fr/' |
| 65 | 80 | echo '' |
| 66 | 81 | |
| 67 | − $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT -dir $srctree || exit 1 | |
| 82 | + if [ "`sed -ne 's|^//#||p' $COCCI`" ] ; then | |
| 83 | + echo 'Semantic patch information:' | |
| 84 | + sed -ne 's|^//#||p' $COCCI | |
| 85 | + echo '' | |
| 86 | + fi | |
| 87 | + fi | |
| 88 | + | |
| 89 | + if [ "$MODE" = "chain" ] ; then | |
| 90 | + $SPATCH -D patch $FLAGS -sp_file $COCCI $OPT $OPTIONS || \ | |
| 91 | + $SPATCH -D report $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || \ | |
| 92 | + $SPATCH -D context $FLAGS -sp_file $COCCI $OPT $OPTIONS || \ | |
| 93 | + $SPATCH -D org $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || exit 1 | |
| 68 | 94 | else |
| 69 | − $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1 | |
| 95 | + $SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1 | |
| 70 | 96 | fi |
| 71 | 97 | |
| 72 | 98 | } |
File renamed without changes.
| @@ -1,5 +1,9 @@ | ||
| 1 | 1 | /// |
| 2 | −/// kzalloc should be used rather than kmalloc followed by memset 0 | |
| 2 | +/// Use kzalloc rather than kmalloc followed by memset with 0 | |
| 3 | +/// | |
| 4 | +/// This considers some simple cases that are common and easy to validate | |
| 5 | +/// Note in particular that there are no ...s in the rule, so all of the | |
| 6 | +/// matched code has to be contiguous | |
| 3 | 7 | /// |
| 4 | 8 | // Confidence: High |
| 5 | 9 | // Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2. |
File renamed without changes.
| @@ -0,0 +1,39 @@ | ||
| 1 | +/// Use kstrdup rather than duplicating its implementation | |
| 2 | +/// | |
| 3 | +// Confidence: High | |
| 4 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 5 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 6 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 7 | +// URL: http://coccinelle.lip6.fr/ | |
| 8 | +// Comments: | |
| 9 | +// Options: -no_includes -include_headers | |
| 10 | + | |
| 11 | +virtual patch | |
| 12 | + | |
| 13 | +@@ | |
| 14 | +expression from,to; | |
| 15 | +expression flag,E1,E2; | |
| 16 | +statement S; | |
| 17 | +@@ | |
| 18 | + | |
| 19 | +- to = kmalloc(strlen(from) + 1,flag); | |
| 20 | ++ to = kstrdup(from, flag); | |
| 21 | + ... when != \(from = E1 \| to = E1 \) | |
| 22 | + if (to==NULL || ...) S | |
| 23 | + ... when != \(from = E2 \| to = E2 \) | |
| 24 | +- strcpy(to, from); | |
| 25 | + | |
| 26 | +@@ | |
| 27 | +expression x,from,to; | |
| 28 | +expression flag,E1,E2,E3; | |
| 29 | +statement S; | |
| 30 | +@@ | |
| 31 | + | |
| 32 | +- x = strlen(from) + 1; | |
| 33 | + ... when != \( x = E1 \| from = E1 \) | |
| 34 | +- to = \(kmalloc\|kzalloc\)(x,flag); | |
| 35 | ++ to = kstrdup(from, flag); | |
| 36 | + ... when != \(x = E2 \| from = E2 \| to = E2 \) | |
| 37 | + if (to==NULL || ...) S | |
| 38 | + ... when != \(x = E3 \| from = E3 \| to = E3 \) | |
| 39 | +- memcpy(to, from, x); | |
| @@ -0,0 +1,40 @@ | ||
| 1 | +/// Use kmemdup rather than duplicating its implementation | |
| 2 | +/// | |
| 3 | +// Confidence: High | |
| 4 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 5 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 6 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 7 | +// URL: http://coccinelle.lip6.fr/ | |
| 8 | +// Comments: | |
| 9 | +// Options: -no_includes -include_headers | |
| 10 | + | |
| 11 | +virtual patch | |
| 12 | + | |
| 13 | +@r1@ | |
| 14 | +expression from,to; | |
| 15 | +expression flag; | |
| 16 | +position p; | |
| 17 | +@@ | |
| 18 | + | |
| 19 | + to = \(kmalloc@p\|kzalloc@p\)(strlen(from) + 1,flag); | |
| 20 | + | |
| 21 | +@r2@ | |
| 22 | +expression x,from,to; | |
| 23 | +expression flag,E1; | |
| 24 | +position p; | |
| 25 | +@@ | |
| 26 | + | |
| 27 | + x = strlen(from) + 1; | |
| 28 | + ... when != \( x = E1 \| from = E1 \) | |
| 29 | + to = \(kmalloc@p\|kzalloc@p\)(x,flag); | |
| 30 | + | |
| 31 | +@@ | |
| 32 | +expression from,to,size,flag; | |
| 33 | +position p != {r1.p,r2.p}; | |
| 34 | +statement S; | |
| 35 | +@@ | |
| 36 | + | |
| 37 | +- to = \(kmalloc@p\|kzalloc@p\)(size,flag); | |
| 38 | ++ to = kmemdup(from,size,flag); | |
| 39 | + if (to==NULL || ...) S | |
| 40 | +- memcpy(to, from, size); | |
| @@ -0,0 +1,35 @@ | ||
| 1 | +/// Use kmemdup_user rather than duplicating its implementation | |
| 2 | +/// This is a little bit restricted to reduce false positives | |
| 3 | +/// | |
| 4 | +// Confidence: High | |
| 5 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 6 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 7 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 8 | +// URL: http://coccinelle.lip6.fr/ | |
| 9 | +// Comments: | |
| 10 | +// Options: -no_includes -include_headers | |
| 11 | + | |
| 12 | +virtual patch | |
| 13 | + | |
| 14 | +@@ | |
| 15 | +expression from,to,size,flag; | |
| 16 | +position p; | |
| 17 | +identifier l1,l2; | |
| 18 | +@@ | |
| 19 | + | |
| 20 | +- to = \(kmalloc@p\|kzalloc@p\)(size,flag); | |
| 21 | ++ to = memdup_user(from,size); | |
| 22 | + if ( | |
| 23 | +- to==NULL | |
| 24 | ++ IS_ERR(to) | |
| 25 | + || ...) { | |
| 26 | + <+... when != goto l1; | |
| 27 | +- -ENOMEM | |
| 28 | ++ PTR_ERR(to) | |
| 29 | + ...+> | |
| 30 | + } | |
| 31 | +- if (copy_from_user(to, from, size) != 0) { | |
| 32 | +- <+... when != goto l2; | |
| 33 | +- -EFAULT | |
| 34 | +- ...+> | |
| 35 | +- } | |
File renamed without changes.
| @@ -0,0 +1,117 @@ | ||
| 1 | +/// Find a use after free. | |
| 2 | +//# Values of variables may imply that some | |
| 3 | +//# execution paths are not possible, resulting in false positives. | |
| 4 | +//# Another source of false positives are macros such as | |
| 5 | +//# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument | |
| 6 | +/// | |
| 7 | +// Confidence: Moderate | |
| 8 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 9 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 10 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 11 | +// URL: http://coccinelle.lip6.fr/ | |
| 12 | +// Comments: | |
| 13 | +// Options: -no_includes -include_headers | |
| 14 | + | |
| 15 | +virtual org | |
| 16 | +virtual report | |
| 17 | + | |
| 18 | +@free@ | |
| 19 | +expression E; | |
| 20 | +position p1; | |
| 21 | +@@ | |
| 22 | + | |
| 23 | +kfree@p1(E) | |
| 24 | + | |
| 25 | +@print expression@ | |
| 26 | +constant char *c; | |
| 27 | +expression free.E,E2; | |
| 28 | +type T; | |
| 29 | +position p; | |
| 30 | +identifier f; | |
| 31 | +@@ | |
| 32 | + | |
| 33 | +( | |
| 34 | + f(...,c,...,(T)E@p,...) | |
| 35 | +| | |
| 36 | + E@p == E2 | |
| 37 | +| | |
| 38 | + E@p != E2 | |
| 39 | +| | |
| 40 | + !E@p | |
| 41 | +| | |
| 42 | + E@p || ... | |
| 43 | +) | |
| 44 | + | |
| 45 | +@sz@ | |
| 46 | +expression free.E; | |
| 47 | +position p; | |
| 48 | +@@ | |
| 49 | + | |
| 50 | + sizeof(<+...E@p...+>) | |
| 51 | + | |
| 52 | +@loop exists@ | |
| 53 | +expression E; | |
| 54 | +identifier l; | |
| 55 | +position ok; | |
| 56 | +@@ | |
| 57 | + | |
| 58 | +while (1) { ... | |
| 59 | + kfree@ok(E) | |
| 60 | + ... when != break; | |
| 61 | + when != goto l; | |
| 62 | + when forall | |
| 63 | +} | |
| 64 | + | |
| 65 | +@r exists@ | |
| 66 | +expression free.E, subE<=free.E, E2; | |
| 67 | +expression E1; | |
| 68 | +iterator iter; | |
| 69 | +statement S; | |
| 70 | +position free.p1!=loop.ok,p2!={print.p,sz.p}; | |
| 71 | +@@ | |
| 72 | + | |
| 73 | +kfree@p1(E,...) | |
| 74 | +... | |
| 75 | +( | |
| 76 | + iter(...,subE,...) S // no use | |
| 77 | +| | |
| 78 | + list_remove_head(E1,subE,...) | |
| 79 | +| | |
| 80 | + subE = E2 | |
| 81 | +| | |
| 82 | + subE++ | |
| 83 | +| | |
| 84 | + ++subE | |
| 85 | +| | |
| 86 | + --subE | |
| 87 | +| | |
| 88 | + subE-- | |
| 89 | +| | |
| 90 | + &subE | |
| 91 | +| | |
| 92 | + BUG(...) | |
| 93 | +| | |
| 94 | + BUG_ON(...) | |
| 95 | +| | |
| 96 | + return_VALUE(...) | |
| 97 | +| | |
| 98 | + return_ACPI_STATUS(...) | |
| 99 | +| | |
| 100 | + E@p2 // bad use | |
| 101 | +) | |
| 102 | + | |
| 103 | +@script:python depends on org@ | |
| 104 | +p1 << free.p1; | |
| 105 | +p2 << r.p2; | |
| 106 | +@@ | |
| 107 | + | |
| 108 | +cocci.print_main("kfree",p1) | |
| 109 | +cocci.print_secs("ref",p2) | |
| 110 | + | |
| 111 | +@script:python depends on report@ | |
| 112 | +p1 << free.p1; | |
| 113 | +p2 << r.p2; | |
| 114 | +@@ | |
| 115 | + | |
| 116 | +msg = "reference preceded by free on line %s" % (p1[0].line) | |
| 117 | +coccilib.report.print_report(p2[0],msg) | |
| @@ -0,0 +1,64 @@ | ||
| 1 | +/// These iterators only exit normally when the loop cursor is NULL, so there | |
| 2 | +/// is no point to call of_node_put on the final value. | |
| 3 | +/// | |
| 4 | +// Confidence: High | |
| 5 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 6 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 7 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 8 | +// URL: http://coccinelle.lip6.fr/ | |
| 9 | +// Comments: | |
| 10 | +// Options: -no_includes -include_headers | |
| 11 | + | |
| 12 | +virtual patch | |
| 13 | + | |
| 14 | +@@ | |
| 15 | +iterator name for_each_node_by_name; | |
| 16 | +expression np,E; | |
| 17 | +identifier l; | |
| 18 | +@@ | |
| 19 | + | |
| 20 | +for_each_node_by_name(np,...) { | |
| 21 | + ... when != break; | |
| 22 | + when != goto l; | |
| 23 | +} | |
| 24 | +... when != np = E | |
| 25 | +- of_node_put(np); | |
| 26 | + | |
| 27 | +@@ | |
| 28 | +iterator name for_each_node_by_type; | |
| 29 | +expression np,E; | |
| 30 | +identifier l; | |
| 31 | +@@ | |
| 32 | + | |
| 33 | +for_each_node_by_type(np,...) { | |
| 34 | + ... when != break; | |
| 35 | + when != goto l; | |
| 36 | +} | |
| 37 | +... when != np = E | |
| 38 | +- of_node_put(np); | |
| 39 | + | |
| 40 | +@@ | |
| 41 | +iterator name for_each_compatible_node; | |
| 42 | +expression np,E; | |
| 43 | +identifier l; | |
| 44 | +@@ | |
| 45 | + | |
| 46 | +for_each_compatible_node(np,...) { | |
| 47 | + ... when != break; | |
| 48 | + when != goto l; | |
| 49 | +} | |
| 50 | +... when != np = E | |
| 51 | +- of_node_put(np); | |
| 52 | + | |
| 53 | +@@ | |
| 54 | +iterator name for_each_matching_node; | |
| 55 | +expression np,E; | |
| 56 | +identifier l; | |
| 57 | +@@ | |
| 58 | + | |
| 59 | +for_each_matching_node(np,...) { | |
| 60 | + ... when != break; | |
| 61 | + when != goto l; | |
| 62 | +} | |
| 63 | +... when != np = E | |
| 64 | +- of_node_put(np); | |
| @@ -0,0 +1,58 @@ | ||
| 1 | +/// Many iterators have the property that the first argument is always bound | |
| 2 | +/// to a real list element, never NULL. False positives arise for some | |
| 3 | +/// iterators that do not have this property, or in cases when the loop | |
| 4 | +/// cursor is reassigned. The latter should only happen when the matched | |
| 5 | +/// code is on the way to a loop exit (break, goto, or return). | |
| 6 | +/// | |
| 7 | +// Confidence: Moderate | |
| 8 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 9 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 10 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 11 | +// URL: http://coccinelle.lip6.fr/ | |
| 12 | +// Comments: | |
| 13 | +// Options: -no_includes -include_headers | |
| 14 | + | |
| 15 | +virtual patch | |
| 16 | + | |
| 17 | +@@ | |
| 18 | +iterator I; | |
| 19 | +expression x,E,E1,E2; | |
| 20 | +statement S,S1,S2; | |
| 21 | +@@ | |
| 22 | + | |
| 23 | +I(x,...) { <... | |
| 24 | +( | |
| 25 | +- if (x == NULL && ...) S | |
| 26 | +| | |
| 27 | +- if (x != NULL || ...) | |
| 28 | + S | |
| 29 | +| | |
| 30 | +- (x == NULL) || | |
| 31 | + E | |
| 32 | +| | |
| 33 | +- (x != NULL) && | |
| 34 | + E | |
| 35 | +| | |
| 36 | +- (x == NULL && ...) ? E1 : | |
| 37 | + E2 | |
| 38 | +| | |
| 39 | +- (x != NULL || ...) ? | |
| 40 | + E1 | |
| 41 | +- : E2 | |
| 42 | +| | |
| 43 | +- if (x == NULL && ...) S1 else | |
| 44 | + S2 | |
| 45 | +| | |
| 46 | +- if (x != NULL || ...) | |
| 47 | + S1 | |
| 48 | +- else S2 | |
| 49 | +| | |
| 50 | ++ BAD( | |
| 51 | + x == NULL | |
| 52 | ++ ) | |
| 53 | +| | |
| 54 | ++ BAD( | |
| 55 | + x != NULL | |
| 56 | ++ ) | |
| 57 | +) | |
| 58 | + ...> } | |
| @@ -0,0 +1,62 @@ | ||
| 1 | +/// list_for_each_entry uses its first argument to get from one element of | |
| 2 | +/// the list to the next, so it is usually not a good idea to reassign it. | |
| 3 | +/// The first rule finds such a reassignment and the second rule checks | |
| 4 | +/// that there is a path from the reassignment back to the top of the loop. | |
| 5 | +/// | |
| 6 | +// Confidence: High | |
| 7 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 8 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 9 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 10 | +// URL: http://coccinelle.lip6.fr/ | |
| 11 | +// Comments: | |
| 12 | +// Options: -no_includes -include_headers | |
| 13 | + | |
| 14 | +virtual context | |
| 15 | +virtual org | |
| 16 | +virtual report | |
| 17 | + | |
| 18 | +@r@ | |
| 19 | +iterator name list_for_each_entry; | |
| 20 | +expression x,E; | |
| 21 | +position p1,p2; | |
| 22 | +@@ | |
| 23 | + | |
| 24 | +list_for_each_entry@p1(x,...) { <... x =@p2 E ...> } | |
| 25 | + | |
| 26 | +@depends on context && !org && !report@ | |
| 27 | +expression x,E; | |
| 28 | +position r.p1,r.p2; | |
| 29 | +statement S; | |
| 30 | +@@ | |
| 31 | + | |
| 32 | +*x =@p2 E | |
| 33 | +... | |
| 34 | +list_for_each_entry@p1(x,...) S | |
| 35 | + | |
| 36 | +// ------------------------------------------------------------------------ | |
| 37 | + | |
| 38 | +@back depends on (org || report) && !context exists@ | |
| 39 | +expression x,E; | |
| 40 | +position r.p1,r.p2; | |
| 41 | +statement S; | |
| 42 | +@@ | |
| 43 | + | |
| 44 | +x =@p2 E | |
| 45 | +... | |
| 46 | +list_for_each_entry@p1(x,...) S | |
| 47 | + | |
| 48 | +@script:python depends on back && org@ | |
| 49 | +p1 << r.p1; | |
| 50 | +p2 << r.p2; | |
| 51 | +@@ | |
| 52 | + | |
| 53 | +cocci.print_main("iterator",p1) | |
| 54 | +cocci.print_secs("update",p2) | |
| 55 | + | |
| 56 | +@script:python depends on back && report@ | |
| 57 | +p1 << r.p1; | |
| 58 | +p2 << r.p2; | |
| 59 | +@@ | |
| 60 | + | |
| 61 | +msg = "iterator with update on line %s" % (p2[0].line) | |
| 62 | +coccilib.report.print_report(p1[0],msg) | |
| @@ -0,0 +1,74 @@ | ||
| 1 | +/// Find functions that refer to GFP_KERNEL but are called with locks held. | |
| 2 | +/// The proposed change of converting the GFP_KERNEL is not necessarily the | |
| 3 | +/// correct one. It may be desired to unlock the lock, or to not call the | |
| 4 | +/// function under the lock in the first place. | |
| 5 | +/// | |
| 6 | +// Confidence: Moderate | |
| 7 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 8 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 9 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 10 | +// URL: http://coccinelle.lip6.fr/ | |
| 11 | +// Comments: | |
| 12 | +// Options: -no_includes -include_headers | |
| 13 | + | |
| 14 | +virtual patch | |
| 15 | + | |
| 16 | +@gfp exists@ | |
| 17 | +identifier fn; | |
| 18 | +position p; | |
| 19 | +@@ | |
| 20 | + | |
| 21 | +fn(...) { | |
| 22 | + ... when != read_unlock_irq(...) | |
| 23 | + when != write_unlock_irq(...) | |
| 24 | + when != read_unlock_irqrestore(...) | |
| 25 | + when != write_unlock_irqrestore(...) | |
| 26 | + when != spin_unlock(...) | |
| 27 | + when != spin_unlock_irq(...) | |
| 28 | + when != spin_unlock_irqrestore(...) | |
| 29 | + when != local_irq_enable(...) | |
| 30 | + when any | |
| 31 | + GFP_KERNEL@p | |
| 32 | + ... when any | |
| 33 | +} | |
| 34 | + | |
| 35 | +@locked@ | |
| 36 | +identifier gfp.fn; | |
| 37 | +@@ | |
| 38 | + | |
| 39 | +( | |
| 40 | +read_lock_irq | |
| 41 | +| | |
| 42 | +write_lock_irq | |
| 43 | +| | |
| 44 | +read_lock_irqsave | |
| 45 | +| | |
| 46 | +write_lock_irqsave | |
| 47 | +| | |
| 48 | +spin_lock | |
| 49 | +| | |
| 50 | +spin_trylock | |
| 51 | +| | |
| 52 | +spin_lock_irq | |
| 53 | +| | |
| 54 | +spin_lock_irqsave | |
| 55 | +| | |
| 56 | +local_irq_disable | |
| 57 | +) | |
| 58 | + (...) | |
| 59 | +... when != read_unlock_irq(...) | |
| 60 | + when != write_unlock_irq(...) | |
| 61 | + when != read_unlock_irqrestore(...) | |
| 62 | + when != write_unlock_irqrestore(...) | |
| 63 | + when != spin_unlock(...) | |
| 64 | + when != spin_unlock_irq(...) | |
| 65 | + when != spin_unlock_irqrestore(...) | |
| 66 | + when != local_irq_enable(...) | |
| 67 | +fn(...) | |
| 68 | + | |
| 69 | +@depends on locked@ | |
| 70 | +position gfp.p; | |
| 71 | +@@ | |
| 72 | + | |
| 73 | +- GFP_KERNEL@p | |
| 74 | ++ GFP_ATOMIC | |
| @@ -0,0 +1,92 @@ | ||
| 1 | +/// Find double locks. False positives may occur when some paths cannot | |
| 2 | +/// occur at execution, due to the values of variables, and when there is | |
| 3 | +/// an intervening function call that releases the lock. | |
| 4 | +/// | |
| 5 | +// Confidence: Moderate | |
| 6 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 7 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 8 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 9 | +// URL: http://coccinelle.lip6.fr/ | |
| 10 | +// Comments: | |
| 11 | +// Options: -no_includes -include_headers | |
| 12 | + | |
| 13 | +virtual org | |
| 14 | +virtual report | |
| 15 | + | |
| 16 | +@locked@ | |
| 17 | +position p1; | |
| 18 | +expression E1; | |
| 19 | +position p; | |
| 20 | +@@ | |
| 21 | + | |
| 22 | +( | |
| 23 | +mutex_lock@p1 | |
| 24 | +| | |
| 25 | +mutex_trylock@p1 | |
| 26 | +| | |
| 27 | +spin_lock@p1 | |
| 28 | +| | |
| 29 | +spin_trylock@p1 | |
| 30 | +| | |
| 31 | +read_lock@p1 | |
| 32 | +| | |
| 33 | +read_trylock@p1 | |
| 34 | +| | |
| 35 | +write_lock@p1 | |
| 36 | +| | |
| 37 | +write_trylock@p1 | |
| 38 | +) (E1@p,...); | |
| 39 | + | |
| 40 | +@balanced@ | |
| 41 | +position p1 != locked.p1; | |
| 42 | +position locked.p; | |
| 43 | +identifier lock,unlock; | |
| 44 | +expression x <= locked.E1; | |
| 45 | +expression E,locked.E1; | |
| 46 | +expression E2; | |
| 47 | +@@ | |
| 48 | + | |
| 49 | +if (E) { | |
| 50 | + <+... when != E1 | |
| 51 | + lock(E1@p,...) | |
| 52 | + ...+> | |
| 53 | +} | |
| 54 | +... when != E1 | |
| 55 | + when != \(x = E2\|&x\) | |
| 56 | + when forall | |
| 57 | +if (E) { | |
| 58 | + <+... when != E1 | |
| 59 | + unlock@p1(E1,...) | |
| 60 | + ...+> | |
| 61 | +} | |
| 62 | + | |
| 63 | +@r depends on !balanced exists@ | |
| 64 | +expression x <= locked.E1; | |
| 65 | +expression locked.E1; | |
| 66 | +expression E2; | |
| 67 | +identifier lock; | |
| 68 | +position locked.p,p1,p2; | |
| 69 | +@@ | |
| 70 | + | |
| 71 | +lock@p1 (E1@p,...); | |
| 72 | +... when != E1 | |
| 73 | + when != \(x = E2\|&x\) | |
| 74 | +lock@p2 (E1,...); | |
| 75 | + | |
| 76 | +@script:python depends on org@ | |
| 77 | +p1 << r.p1; | |
| 78 | +p2 << r.p2; | |
| 79 | +lock << r.lock; | |
| 80 | +@@ | |
| 81 | + | |
| 82 | +cocci.print_main(lock,p1) | |
| 83 | +cocci.print_secs("second lock",p2) | |
| 84 | + | |
| 85 | +@script:python depends on report@ | |
| 86 | +p1 << r.p1; | |
| 87 | +p2 << r.p2; | |
| 88 | +lock << r.lock; | |
| 89 | +@@ | |
| 90 | + | |
| 91 | +msg = "second lock on line %s" % (p2[0].line) | |
| 92 | +coccilib.report.print_report(p1[0],msg) | |
| @@ -0,0 +1,80 @@ | ||
| 1 | +/// Find nested lock+irqsave functions that use the same flags variables | |
| 2 | +/// | |
| 3 | +// Confidence: High | |
| 4 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 5 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 6 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 7 | +// URL: http://coccinelle.lip6.fr/ | |
| 8 | +// Comments: | |
| 9 | +// Options: -no_includes -include_headers | |
| 10 | + | |
| 11 | +virtual context | |
| 12 | +virtual org | |
| 13 | +virtual report | |
| 14 | + | |
| 15 | +@r@ | |
| 16 | +expression lock1,lock2,flags; | |
| 17 | +position p1,p2; | |
| 18 | +@@ | |
| 19 | + | |
| 20 | +( | |
| 21 | +spin_lock_irqsave@p1(lock1,flags) | |
| 22 | +| | |
| 23 | +read_lock_irqsave@p1(lock1,flags) | |
| 24 | +| | |
| 25 | +write_lock_irqsave@p1(lock1,flags) | |
| 26 | +) | |
| 27 | +... when != flags | |
| 28 | +( | |
| 29 | +spin_lock_irqsave(lock1,flags) | |
| 30 | +| | |
| 31 | +read_lock_irqsave(lock1,flags) | |
| 32 | +| | |
| 33 | +write_lock_irqsave(lock1,flags) | |
| 34 | +| | |
| 35 | +spin_lock_irqsave@p2(lock2,flags) | |
| 36 | +| | |
| 37 | +read_lock_irqsave@p2(lock2,flags) | |
| 38 | +| | |
| 39 | +write_lock_irqsave@p2(lock2,flags) | |
| 40 | +) | |
| 41 | + | |
| 42 | +@d@ | |
| 43 | +expression f <= r.flags; | |
| 44 | +expression lock1,lock2,flags; | |
| 45 | +position r.p1, r.p2; | |
| 46 | +@@ | |
| 47 | + | |
| 48 | +( | |
| 49 | +*spin_lock_irqsave@p1(lock1,flags) | |
| 50 | +| | |
| 51 | +*read_lock_irqsave@p1(lock1,flags) | |
| 52 | +| | |
| 53 | +*write_lock_irqsave@p1(lock1,flags) | |
| 54 | +) | |
| 55 | +... when != f | |
| 56 | +( | |
| 57 | +*spin_lock_irqsave@p2(lock2,flags) | |
| 58 | +| | |
| 59 | +*read_lock_irqsave@p2(lock2,flags) | |
| 60 | +| | |
| 61 | +*write_lock_irqsave@p2(lock2,flags) | |
| 62 | +) | |
| 63 | + | |
| 64 | +// ---------------------------------------------------------------------- | |
| 65 | + | |
| 66 | +@script:python depends on d && org@ | |
| 67 | +p1 << r.p1; | |
| 68 | +p2 << r.p2; | |
| 69 | +@@ | |
| 70 | + | |
| 71 | +cocci.print_main("original lock",p1) | |
| 72 | +cocci.print_secs("nested lock+irqsave that reuses flags",p2) | |
| 73 | + | |
| 74 | +@script:python depends on d && report@ | |
| 75 | +p1 << r.p1; | |
| 76 | +p2 << r.p2; | |
| 77 | +@@ | |
| 78 | + | |
| 79 | +msg="ERROR: nested lock+irqsave that reuses flags from %s." % (p1[0].line) | |
| 80 | +coccilib.report.print_report(p2[0], msg) | |
| @@ -0,0 +1,95 @@ | ||
| 1 | +/// Find missing unlocks. This semantic match considers the specific case | |
| 2 | +/// where the unlock is missing from an if branch, and there is a lock | |
| 3 | +/// before the if and an unlock after the if. False positives are due to | |
| 4 | +/// cases where the if branch represents a case where the function is | |
| 5 | +/// supposed to exit with the lock held, or where there is some preceding | |
| 6 | +/// function call that releases the lock. | |
| 7 | +/// | |
| 8 | +// Confidence: Moderate | |
| 9 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 10 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 11 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 12 | +// URL: http://coccinelle.lip6.fr/ | |
| 13 | +// Comments: | |
| 14 | +// Options: -no_includes -include_headers | |
| 15 | + | |
| 16 | +virtual org | |
| 17 | +virtual report | |
| 18 | + | |
| 19 | +@prelocked@ | |
| 20 | +position p1,p; | |
| 21 | +expression E1; | |
| 22 | +@@ | |
| 23 | + | |
| 24 | +( | |
| 25 | +mutex_lock@p1 | |
| 26 | +| | |
| 27 | +mutex_trylock@p1 | |
| 28 | +| | |
| 29 | +spin_lock@p1 | |
| 30 | +| | |
| 31 | +spin_trylock@p1 | |
| 32 | +| | |
| 33 | +read_lock@p1 | |
| 34 | +| | |
| 35 | +read_trylock@p1 | |
| 36 | +| | |
| 37 | +write_lock@p1 | |
| 38 | +| | |
| 39 | +write_trylock@p1 | |
| 40 | +| | |
| 41 | +read_lock_irq@p1 | |
| 42 | +| | |
| 43 | +write_lock_irq@p1 | |
| 44 | +| | |
| 45 | +read_lock_irqsave@p1 | |
| 46 | +| | |
| 47 | +write_lock_irqsave@p1 | |
| 48 | +| | |
| 49 | +spin_lock_irq@p1 | |
| 50 | +| | |
| 51 | +spin_lock_irqsave@p1 | |
| 52 | +) (E1@p,...); | |
| 53 | + | |
| 54 | +@looped@ | |
| 55 | +position r; | |
| 56 | +@@ | |
| 57 | + | |
| 58 | +for(...;...;...) { <+... return@r ...; ...+> } | |
| 59 | + | |
| 60 | +@err@ | |
| 61 | +expression E1; | |
| 62 | +position prelocked.p; | |
| 63 | +position up != prelocked.p1; | |
| 64 | +position r!=looped.r; | |
| 65 | +identifier lock,unlock; | |
| 66 | +@@ | |
| 67 | + | |
| 68 | +lock(E1@p,...); | |
| 69 | +<+... when != E1 | |
| 70 | +if (...) { | |
| 71 | + ... when != E1 | |
| 72 | + return@r ...; | |
| 73 | +} | |
| 74 | +...+> | |
| 75 | +unlock@up(E1,...); | |
| 76 | + | |
| 77 | +@script:python depends on org@ | |
| 78 | +p << prelocked.p1; | |
| 79 | +lock << err.lock; | |
| 80 | +unlock << err.unlock; | |
| 81 | +p2 << err.r; | |
| 82 | +@@ | |
| 83 | + | |
| 84 | +cocci.print_main(lock,p) | |
| 85 | +cocci.print_secs(unlock,p2) | |
| 86 | + | |
| 87 | +@script:python depends on report@ | |
| 88 | +p << prelocked.p1; | |
| 89 | +lock << err.lock; | |
| 90 | +unlock << err.unlock; | |
| 91 | +p2 << err.r; | |
| 92 | +@@ | |
| 93 | + | |
| 94 | +msg = "preceding lock on line %s" % (p[0].line) | |
| 95 | +coccilib.report.print_report(p2[0],msg) | |
| @@ -0,0 +1,53 @@ | ||
| 1 | +/// Find duplicate field initializations. This has a high rate of false | |
| 2 | +/// positives due to #ifdefs, which Coccinelle is not aware of in a structure | |
| 3 | +/// initialization. | |
| 4 | +/// | |
| 5 | +// Confidence: Low | |
| 6 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 7 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 8 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 9 | +// URL: http://coccinelle.lip6.fr/ | |
| 10 | +// Comments: | |
| 11 | +// Options: -no_includes -include_headers | |
| 12 | + | |
| 13 | +virtual org | |
| 14 | +virtual report | |
| 15 | + | |
| 16 | +@r@ | |
| 17 | +identifier I, s, fld; | |
| 18 | +position p0,p; | |
| 19 | +expression E; | |
| 20 | +@@ | |
| 21 | + | |
| 22 | +struct I s =@p0 { ... .fld@p = E, ...}; | |
| 23 | + | |
| 24 | +@s@ | |
| 25 | +identifier I, s, r.fld; | |
| 26 | +position r.p0,p; | |
| 27 | +expression E; | |
| 28 | +@@ | |
| 29 | + | |
| 30 | +struct I s =@p0 { ... .fld@p = E, ...}; | |
| 31 | + | |
| 32 | +@script:python depends on org@ | |
| 33 | +p0 << r.p0; | |
| 34 | +fld << r.fld; | |
| 35 | +ps << s.p; | |
| 36 | +pr << r.p; | |
| 37 | +@@ | |
| 38 | + | |
| 39 | +if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)): | |
| 40 | + cocci.print_main(fld,p0) | |
| 41 | + cocci.print_secs("s",ps) | |
| 42 | + cocci.print_secs("r",pr) | |
| 43 | + | |
| 44 | +@script:python depends on report@ | |
| 45 | +p0 << r.p0; | |
| 46 | +fld << r.fld; | |
| 47 | +ps << s.p; | |
| 48 | +pr << r.p; | |
| 49 | +@@ | |
| 50 | + | |
| 51 | +if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)): | |
| 52 | + msg = "%s: first occurrence %s, second occurrence %s" % (fld,ps[0].line,pr[0].line) | |
| 53 | + coccilib.report.print_report(p0[0],msg) | |
| @@ -0,0 +1,48 @@ | ||
| 1 | +/// Find confusingly indented code in or after an if. An if branch should | |
| 2 | +/// be indented. The code following an if should not be indented. | |
| 3 | +/// Sometimes, code after an if that is indented is actually intended to be | |
| 4 | +/// part of the if branch. | |
| 5 | +/// | |
| 6 | +/// This has a high rate of false positives, because Coccinelle's column | |
| 7 | +/// calculation does not distinguish between spaces and tabs, so code that | |
| 8 | +/// is not visually aligned may be considered to be in the same column. | |
| 9 | +/// | |
| 10 | +// Confidence: Low | |
| 11 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 12 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 13 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 14 | +// URL: http://coccinelle.lip6.fr/ | |
| 15 | +// Comments: | |
| 16 | +// Options: -no_includes -include_headers | |
| 17 | + | |
| 18 | +virtual org | |
| 19 | +virtual report | |
| 20 | + | |
| 21 | +@r disable braces4@ | |
| 22 | +position p1,p2; | |
| 23 | +statement S1,S2; | |
| 24 | +@@ | |
| 25 | + | |
| 26 | +( | |
| 27 | +if (...) { ... } | |
| 28 | +| | |
| 29 | +if (...) S1@p1 S2@p2 | |
| 30 | +) | |
| 31 | + | |
| 32 | +@script:python depends on org@ | |
| 33 | +p1 << r.p1; | |
| 34 | +p2 << r.p2; | |
| 35 | +@@ | |
| 36 | + | |
| 37 | +if (p1[0].column == p2[0].column): | |
| 38 | + cocci.print_main("branch",p1) | |
| 39 | + cocci.print_secs("after",p2) | |
| 40 | + | |
| 41 | +@script:python depends on report@ | |
| 42 | +p1 << r.p1; | |
| 43 | +p2 << r.p2; | |
| 44 | +@@ | |
| 45 | + | |
| 46 | +if (p1[0].column == p2[0].column): | |
| 47 | + msg = "code aligned with following code on line %s" % (p2[0].line) | |
| 48 | + coccilib.report.print_report(p1[0],msg) | |
File renamed without changes.
| @@ -0,0 +1,20 @@ | ||
| 1 | +/// The various basic memory allocation functions don't return ERR_PTR | |
| 2 | +/// | |
| 3 | +// Confidence: High | |
| 4 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 5 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 6 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 7 | +// URL: http://coccinelle.lip6.fr/ | |
| 8 | +// Comments: | |
| 9 | +// Options: -no_includes -include_headers | |
| 10 | + | |
| 11 | +virtual patch | |
| 12 | + | |
| 13 | +@@ | |
| 14 | +expression x,E; | |
| 15 | +@@ | |
| 16 | + | |
| 17 | +x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...) | |
| 18 | +... when != x = E | |
| 19 | +- IS_ERR(x) | |
| 20 | ++ !x | |
| @@ -0,0 +1,72 @@ | ||
| 1 | +/// This semantic patch looks for kmalloc etc that are not followed by a | |
| 2 | +/// NULL check. It only gives a report in the case where there is some | |
| 3 | +/// error handling code later in the function, which may be helpful | |
| 4 | +/// in determining what the error handling code for the call to kmalloc etc | |
| 5 | +/// should be. | |
| 6 | +/// | |
| 7 | +// Confidence: High | |
| 8 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 9 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 10 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 11 | +// URL: http://coccinelle.lip6.fr/ | |
| 12 | +// Comments: | |
| 13 | +// Options: -no_includes -include_headers | |
| 14 | + | |
| 15 | +virtual context | |
| 16 | +virtual org | |
| 17 | +virtual report | |
| 18 | + | |
| 19 | +@withtest@ | |
| 20 | +expression x; | |
| 21 | +position p; | |
| 22 | +identifier f,fld; | |
| 23 | +@@ | |
| 24 | + | |
| 25 | +x@p = f(...); | |
| 26 | +... when != x->fld | |
| 27 | +\(x == NULL \| x != NULL\) | |
| 28 | + | |
| 29 | +@fixed depends on context && !org && !report@ | |
| 30 | +expression x,x1; | |
| 31 | +position p1 != withtest.p; | |
| 32 | +statement S; | |
| 33 | +position any withtest.p; | |
| 34 | +identifier f; | |
| 35 | +@@ | |
| 36 | + | |
| 37 | +*x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); | |
| 38 | +... | |
| 39 | +*x1@p = f(...); | |
| 40 | +if (!x1) S | |
| 41 | + | |
| 42 | +// ------------------------------------------------------------------------ | |
| 43 | + | |
| 44 | +@rfixed depends on (org || report) && !context exists@ | |
| 45 | +expression x,x1; | |
| 46 | +position p1 != withtest.p; | |
| 47 | +position p2; | |
| 48 | +statement S; | |
| 49 | +position any withtest.p; | |
| 50 | +identifier f; | |
| 51 | +@@ | |
| 52 | + | |
| 53 | +x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); | |
| 54 | +... | |
| 55 | +x1@p = f@p2(...); | |
| 56 | +if (!x1) S | |
| 57 | + | |
| 58 | +@script:python depends on org@ | |
| 59 | +p1 << rfixed.p1; | |
| 60 | +p2 << rfixed.p2; | |
| 61 | +@@ | |
| 62 | + | |
| 63 | +cocci.print_main("alloc call",p1) | |
| 64 | +cocci.print_secs("possible model",p2) | |
| 65 | + | |
| 66 | +@script:python depends on report@ | |
| 67 | +p1 << rfixed.p1; | |
| 68 | +p2 << rfixed.p2; | |
| 69 | +@@ | |
| 70 | + | |
| 71 | +msg = "alloc with no test, possible model on line %s" % (p2[0].line) | |
| 72 | +coccilib.report.print_report(p1[0],msg) | |
| @@ -0,0 +1,54 @@ | ||
| 1 | +/// Find bit operations that include the same argument more than once | |
| 2 | +//# One source of false positives is when the argument performs a side | |
| 3 | +//# effect. Another source of false positives is when a neutral value | |
| 4 | +//# such as 0 for | is used to indicate no information, to maintain the | |
| 5 | +//# same structure as other similar expressions | |
| 6 | +/// | |
| 7 | +// Confidence: Moderate | |
| 8 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 9 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 10 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 11 | +// URL: http://coccinelle.lip6.fr/ | |
| 12 | +// Comments: | |
| 13 | +// Options: -no_includes -include_headers | |
| 14 | + | |
| 15 | +virtual context | |
| 16 | +virtual org | |
| 17 | +virtual report | |
| 18 | + | |
| 19 | +@r expression@ | |
| 20 | +expression E; | |
| 21 | +position p; | |
| 22 | +@@ | |
| 23 | + | |
| 24 | +( | |
| 25 | +* E@p | |
| 26 | + & ... & E | |
| 27 | +| | |
| 28 | +* E@p | |
| 29 | + | ... | E | |
| 30 | +| | |
| 31 | +* E@p | |
| 32 | + & ... & !E | |
| 33 | +| | |
| 34 | +* E@p | |
| 35 | + | ... | !E | |
| 36 | +| | |
| 37 | +* !E@p | |
| 38 | + & ... & E | |
| 39 | +| | |
| 40 | +* !E@p | |
| 41 | + | ... | E | |
| 42 | +) | |
| 43 | + | |
| 44 | +@script:python depends on org@ | |
| 45 | +p << r.p; | |
| 46 | +@@ | |
| 47 | + | |
| 48 | +cocci.print_main("duplicated argument to & or |",p) | |
| 49 | + | |
| 50 | +@script:python depends on report@ | |
| 51 | +p << r.p; | |
| 52 | +@@ | |
| 53 | + | |
| 54 | +coccilib.report.print_report(p[0],"duplicated argument to & or |") | |
| @@ -0,0 +1,40 @@ | ||
| 1 | +/// Find &&/|| operations that include the same argument more than once | |
| 2 | +//# A common source of false positives is when the argument performs a side | |
| 3 | +//# effect. | |
| 4 | +/// | |
| 5 | +// Confidence: Moderate | |
| 6 | +// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | |
| 7 | +// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | |
| 8 | +// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
| 9 | +// URL: http://coccinelle.lip6.fr/ | |
| 10 | +// Comments: | |
| 11 | +// Options: -no_includes -include_headers | |
| 12 | + | |
| 13 | +virtual context | |
| 14 | +virtual org | |
| 15 | +virtual report | |
| 16 | + | |
| 17 | +@r expression@ | |
| 18 | +expression E; | |
| 19 | +position p; | |
| 20 | +@@ | |
| 21 | + | |
| 22 | +( | |
| 23 | +* E@p | |
| 24 | + || ... || E | |
| 25 | +| | |
| 26 | +* E@p | |
| 27 | + && ... && E | |
| 28 | +) | |
| 29 | + | |
| 30 | +@script:python depends on org@ | |
| 31 | +p << r.p; | |
| 32 | +@@ | |
| 33 | + | |
| 34 | +cocci.print_main("duplicated argument to && or ||",p) | |
| 35 | + | |
| 36 | +@script:python depends on report@ | |
| 37 | +p << r.p; | |
| 38 | +@@ | |
| 39 | + | |
| 40 | +coccilib.report.print_report(p[0],"duplicated argument to && or ||") | |
| @@ -7,12 +7,10 @@ · 6 unmodified lines | ||
| 7 | 7 | # The obscure use of the "tr" filter is to work around older versions of |
| 8 | 8 | # "grep" that report the byte offset of the line instead of the pattern. |
| 9 | 9 | # |
| 10 | −# (c) 2009, Dick Streefland <dick@streefland.net> | |
| 10 | +# (c) 2009,2010 Dick Streefland <dick@streefland.net> | |
| 11 | 11 | # Licensed under the terms of the GNU General Public License. |
| 12 | 12 | # ---------------------------------------------------------------------- |
| 13 | 13 | |
| 14 | −gz1='\037\213\010' | |
| 15 | −gz2='01' | |
| 16 | 14 | cf1='IKCFG_ST\037\213\010' |
| 17 | 15 | cf2='0123456789' |
| 18 | 16 | |
| @@ -21,11 +19,25 @@ dump_config() · 2 unmodified lines | ||
| 21 | 19 | if pos=`tr "$cf1\n$cf2" "\n$cf2=" < "$1" | grep -abo "^$cf2"` |
| 22 | 20 | then |
| 23 | 21 | pos=${pos%%:*} |
| 24 | − tail -c+$(($pos+8)) "$1" | zcat -q | |
| 25 | − exit 0 | |
| 22 | + tail -c+$(($pos+8)) "$1" | zcat > $tmp1 2> /dev/null | |
| 23 | + if [ $? != 1 ] | |
| 24 | + then # exit status must be 0 or 2 (trailing garbage warning) | |
| 25 | + cat $tmp1 | |
| 26 | + exit 0 | |
| 27 | + fi | |
| 26 | 28 | fi |
| 27 | 29 | } |
| 28 | 30 | |
| 31 | +try_decompress() | |
| 32 | +{ | |
| 33 | + for pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"` | |
| 34 | + do | |
| 35 | + pos=${pos%%:*} | |
| 36 | + tail -c+$pos "$img" | $3 > $tmp2 2> /dev/null | |
| 37 | + dump_config $tmp2 | |
| 38 | + done | |
| 39 | +} | |
| 40 | + | |
| 29 | 41 | # Check invocation: |
| 30 | 42 | me=${0##*/} |
| 31 | 43 | img=$1 |
| @@ -35,18 +47,19 @@ then · 3 unmodified lines | ||
| 35 | 47 | exit 2 |
| 36 | 48 | fi |
| 37 | 49 | |
| 50 | +# Prepare temp files: | |
| 51 | +tmp1=/tmp/ikconfig$$.1 | |
| 52 | +tmp2=/tmp/ikconfig$$.2 | |
| 53 | +trap "rm -f $tmp1 $tmp2" 0 | |
| 54 | + | |
| 38 | 55 | # Initial attempt for uncompressed images or objects: |
| 39 | 56 | dump_config "$img" |
| 40 | 57 | |
| 41 | −# That didn't work, so decompress and try again: | |
| 42 | −tmp=/tmp/ikconfig$$ | |
| 43 | −trap "rm -f $tmp" 0 | |
| 44 | −for pos in `tr "$gz1\n$gz2" "\n$gz2=" < "$img" | grep -abo "^$gz2"` | |
| 45 | −do | |
| 46 | − pos=${pos%%:*} | |
| 47 | − tail -c+$pos "$img" | zcat 2> /dev/null > $tmp | |
| 48 | − dump_config $tmp | |
| 49 | −done | |
| 58 | +# That didn't work, so retry after decompression. | |
| 59 | +try_decompress '\037\213\010' xy gunzip | |
| 60 | +try_decompress 'BZh' xy bunzip2 | |
| 61 | +try_decompress '\135\0\0\0' xxx unlzma | |
| 62 | +try_decompress '\211\114\132' xy 'lzop -d' | |
| 50 | 63 | |
| 51 | 64 | # Bail out: |
| 52 | 65 | echo "$me: Cannot find kernel config." >&2 |
| @@ -84,6 +84,64 @@ my %ksymtab = (); # names that appear in __ksymtab_ · 83 unmodified lines | ||
| 84 | 84 | my %ref = (); # $ref{$name} exists if there is a true external reference to $name |
| 85 | 85 | my %export = (); # $export{$name} exists if there is an EXPORT_... of $name |
| 86 | 86 | |
| 87 | +my %nmexception = ( | |
| 88 | + 'fs/ext3/bitmap' => 1, | |
| 89 | + 'fs/ext4/bitmap' => 1, | |
| 90 | + 'arch/x86/lib/thunk_32' => 1, | |
| 91 | + 'arch/x86/lib/cmpxchg' => 1, | |
| 92 | + 'arch/x86/vdso/vdso32/note' => 1, | |
| 93 | + 'lib/irq_regs' => 1, | |
| 94 | + 'usr/initramfs_data' => 1, | |
| 95 | + 'drivers/scsi/aic94xx/aic94xx_dump' => 1, | |
| 96 | + 'drivers/scsi/libsas/sas_dump' => 1, | |
| 97 | + 'lib/dec_and_lock' => 1, | |
| 98 | + 'drivers/ide/ide-probe-mini' => 1, | |
| 99 | + 'usr/initramfs_data' => 1, | |
| 100 | + 'drivers/acpi/acpia/exdump' => 1, | |
| 101 | + 'drivers/acpi/acpia/rsdump' => 1, | |
| 102 | + 'drivers/acpi/acpia/nsdumpdv' => 1, | |
| 103 | + 'drivers/acpi/acpia/nsdump' => 1, | |
| 104 | + 'arch/ia64/sn/kernel/sn2/io' => 1, | |
| 105 | + 'arch/ia64/kernel/gate-data' => 1, | |
| 106 | + 'security/capability' => 1, | |
| 107 | + 'fs/ntfs/sysctl' => 1, | |
| 108 | + 'fs/jfs/jfs_debug' => 1, | |
| 109 | +); | |
| 110 | + | |
| 111 | +my %nameexception = ( | |
| 112 | + 'mod_use_count_' => 1, | |
| 113 | + '__initramfs_end' => 1, | |
| 114 | + '__initramfs_start' => 1, | |
| 115 | + '_einittext' => 1, | |
| 116 | + '_sinittext' => 1, | |
| 117 | + 'kallsyms_names' => 1, | |
| 118 | + 'kallsyms_num_syms' => 1, | |
| 119 | + 'kallsyms_addresses'=> 1, | |
| 120 | + '__this_module' => 1, | |
| 121 | + '_etext' => 1, | |
| 122 | + '_edata' => 1, | |
| 123 | + '_end' => 1, | |
| 124 | + '__bss_start' => 1, | |
| 125 | + '_text' => 1, | |
| 126 | + '_stext' => 1, | |
| 127 | + '__gp' => 1, | |
| 128 | + 'ia64_unw_start' => 1, | |
| 129 | + 'ia64_unw_end' => 1, | |
| 130 | + '__init_begin' => 1, | |
| 131 | + '__init_end' => 1, | |
| 132 | + '__bss_stop' => 1, | |
| 133 | + '__nosave_begin' => 1, | |
| 134 | + '__nosave_end' => 1, | |
| 135 | + 'pg0' => 1, | |
| 136 | + 'vdso_enabled' => 1, | |
| 137 | + '__stack_chk_fail' => 1, | |
| 138 | + 'VDSO32_PRELINK' => 1, | |
| 139 | + 'VDSO32_vsyscall' => 1, | |
| 140 | + 'VDSO32_rt_sigreturn'=>1, | |
| 141 | + 'VDSO32_sigreturn' => 1, | |
| 142 | +); | |
| 143 | + | |
| 144 | + | |
| 87 | 145 | &find(\&linux_objects, '.'); # find the objects and do_nm on them |
| 88 | 146 | &list_multiply_defined(); |
| 89 | 147 | &resolve_external_references(); |
| @@ -105,7 +163,8 @@ sub linux_objects · 15 unmodified lines | ||
| 105 | 163 | if (/.*\.o$/ && |
| 106 | 164 | ! ( |
| 107 | 165 | m:/built-in.o$: |
| 108 | − || m:arch/x86/kernel/vsyscall-syms.o$: | |
| 166 | + || m:arch/x86/vdso/: | |
| 167 | + || m:arch/x86/boot/: | |
| 109 | 168 | || m:arch/ia64/ia32/ia32.o$: |
| 110 | 169 | || m:arch/ia64/kernel/gate-syms.o$: |
| 111 | 170 | || m:arch/ia64/lib/__divdi3.o$: |
| @@ -148,6 +207,7 @@ sub linux_objects · 36 unmodified lines | ||
| 148 | 207 | || m:^.*/\.tmp_: |
| 149 | 208 | || m:^\.tmp_: |
| 150 | 209 | || m:/vmlinux-obj.o$: |
| 210 | + || m:^tools/: | |
| 151 | 211 | ) |
| 152 | 212 | ) { |
| 153 | 213 | do_nm($basename, $_); |
| @@ -167,11 +227,11 @@ sub do_nm · 13 unmodified lines | ||
| 167 | 227 | printf STDERR "$fullname is not an object file\n"; |
| 168 | 228 | return; |
| 169 | 229 | } |
| 170 | − ($source = $fullname) =~ s/\.o$//; | |
| 171 | − if (-e "$objtree$source.c" || -e "$objtree$source.S") { | |
| 172 | − $source = "$objtree$source"; | |
| 230 | + ($source = $basename) =~ s/\.o$//; | |
| 231 | + if (-e "$source.c" || -e "$source.S") { | |
| 232 | + $source = "$objtree$File::Find::dir/$source"; | |
| 173 | 233 | } else { |
| 174 | − $source = "$srctree$source"; | |
| 234 | + $source = "$srctree$File::Find::dir/$source"; | |
| 175 | 235 | } |
| 176 | 236 | if (! -e "$source.c" && ! -e "$source.S") { |
| 177 | 237 | # No obvious source, exclude the object if it is conglomerate |
| @@ -214,6 +274,7 @@ sub do_nm · 36 unmodified lines | ||
| 214 | 274 | # T global label/procedure |
| 215 | 275 | # U external reference |
| 216 | 276 | # W weak external reference to text that has been resolved |
| 277 | + # V similar to W, but the value of the weak symbol becomes zero with no error. | |
| 217 | 278 | # a assembler equate |
| 218 | 279 | # b static variable, uninitialised |
| 219 | 280 | # d static variable, initialised |
| @@ -222,8 +283,9 @@ sub do_nm · 2 unmodified lines | ||
| 222 | 283 | # s static variable, uninitialised, small bss |
| 223 | 284 | # t static label/procedures |
| 224 | 285 | # w weak external reference to text that has not been resolved |
| 286 | + # v similar to w | |
| 225 | 287 | # ? undefined type, used a lot by modules |
| 226 | − if ($type !~ /^[ABCDGRSTUWabdgrstw?]$/) { | |
| 288 | + if ($type !~ /^[ABCDGRSTUWVabdgrstwv?]$/) { | |
| 227 | 289 | printf STDERR "nm output for $fullname contains unknown type '$_'\n"; |
| 228 | 290 | } |
| 229 | 291 | elsif ($name =~ /\./) { |
| @@ -234,7 +296,7 @@ sub do_nm · 4 unmodified lines | ||
| 234 | 296 | # binutils keeps changing the type for exported symbols, force it to R |
| 235 | 297 | $type = 'R' if ($name =~ /^__ksymtab/ || $name =~ /^__kstrtab/); |
| 236 | 298 | $name =~ s/_R[a-f0-9]{8}$//; # module versions adds this |
| 237 | − if ($type =~ /[ABCDGRSTW]/ && | |
| 299 | + if ($type =~ /[ABCDGRSTWV]/ && | |
| 238 | 300 | $name ne 'init_module' && |
| 239 | 301 | $name ne 'cleanup_module' && |
| 240 | 302 | $name ne 'Using_Versions' && |
| @@ -270,27 +332,9 @@ sub do_nm · 29 unmodified lines | ||
| 270 | 332 | close($nmdata); |
| 271 | 333 | |
| 272 | 334 | if ($#nmdata < 0) { |
| 273 | − if ( | |
| 274 | − $fullname ne "lib/brlock.o" | |
| 275 | − && $fullname ne "lib/dec_and_lock.o" | |
| 276 | − && $fullname ne "fs/xfs/xfs_macros.o" | |
| 277 | − && $fullname ne "drivers/ide/ide-probe-mini.o" | |
| 278 | − && $fullname ne "usr/initramfs_data.o" | |
| 279 | − && $fullname ne "drivers/acpi/executer/exdump.o" | |
| 280 | − && $fullname ne "drivers/acpi/resources/rsdump.o" | |
| 281 | − && $fullname ne "drivers/acpi/namespace/nsdumpdv.o" | |
| 282 | − && $fullname ne "drivers/acpi/namespace/nsdump.o" | |
| 283 | − && $fullname ne "arch/ia64/sn/kernel/sn2/io.o" | |
| 284 | − && $fullname ne "arch/ia64/kernel/gate-data.o" | |
| 285 | − && $fullname ne "drivers/ieee1394/oui.o" | |
| 286 | − && $fullname ne "security/capability.o" | |
| 287 | − && $fullname ne "sound/core/wrappers.o" | |
| 288 | − && $fullname ne "fs/ntfs/sysctl.o" | |
| 289 | − && $fullname ne "fs/jfs/jfs_debug.o" | |
| 290 | − ) { | |
| 291 | − printf "No nm data for $fullname\n"; | |
| 292 | − } | |
| 293 | − return; | |
| 335 | + printf "No nm data for $fullname\n" | |
| 336 | + unless $nmexception{$fullname}; | |
| 337 | + return; | |
| 294 | 338 | } |
| 295 | 339 | $nmdata{$fullname} = \@nmdata; |
| 296 | 340 | } |
| @@ -319,18 +363,14 @@ sub list_multiply_defined · 22 unmodified lines | ||
| 319 | 363 | foreach my $name (keys(%def)) { |
| 320 | 364 | if ($#{$def{$name}} > 0) { |
| 321 | 365 | # Special case for cond_syscall |
| 322 | − if ($#{$def{$name}} == 1 && $name =~ /^sys_/ && | |
| 323 | − ($def{$name}[0] eq "kernel/sys.o" || | |
| 324 | − $def{$name}[1] eq "kernel/sys.o")) { | |
| 325 | − &drop_def("kernel/sys.o", $name); | |
| 326 | − next; | |
| 327 | − } | |
| 328 | − # Special case for i386 entry code | |
| 329 | − if ($#{$def{$name}} == 1 && $name =~ /^__kernel_/ && | |
| 330 | − $def{$name}[0] eq "arch/x86/kernel/vsyscall-int80_32.o" && | |
| 331 | − $def{$name}[1] eq "arch/x86/kernel/vsyscall-sysenter_32.o") { | |
| 332 | − &drop_def("arch/x86/kernel/vsyscall-sysenter_32.o", $name); | |
| 333 | − next; | |
| 366 | + if ($#{$def{$name}} == 1 && | |
| 367 | + ($name =~ /^sys_/ || $name =~ /^compat_sys_/ || | |
| 368 | + $name =~ /^sys32_/)) { | |
| 369 | + if($def{$name}[0] eq "kernel/sys_ni.o" || | |
| 370 | + $def{$name}[1] eq "kernel/sys_ni.o") { | |
| 371 | + &drop_def("kernel/sys_ni.o", $name); | |
| 372 | + next; | |
| 373 | + } | |
| 334 | 374 | } |
| 335 | 375 | |
| 336 | 376 | printf "$name is multiply defined in :-\n"; |
| @@ -372,31 +412,7 @@ sub resolve_external_references · 35 unmodified lines | ||
| 372 | 412 | $ref{$name} = "" |
| 373 | 413 | } |
| 374 | 414 | } |
| 375 | − elsif ( $name ne "mod_use_count_" | |
| 376 | − && $name ne "__initramfs_end" | |
| 377 | − && $name ne "__initramfs_start" | |
| 378 | − && $name ne "_einittext" | |
| 379 | − && $name ne "_sinittext" | |
| 380 | − && $name ne "kallsyms_names" | |
| 381 | − && $name ne "kallsyms_num_syms" | |
| 382 | − && $name ne "kallsyms_addresses" | |
| 383 | − && $name ne "__this_module" | |
| 384 | − && $name ne "_etext" | |
| 385 | − && $name ne "_edata" | |
| 386 | − && $name ne "_end" | |
| 387 | − && $name ne "__bss_start" | |
| 388 | − && $name ne "_text" | |
| 389 | − && $name ne "_stext" | |
| 390 | − && $name ne "__gp" | |
| 391 | − && $name ne "ia64_unw_start" | |
| 392 | − && $name ne "ia64_unw_end" | |
| 393 | − && $name ne "__init_begin" | |
| 394 | − && $name ne "__init_end" | |
| 395 | − && $name ne "__bss_stop" | |
| 396 | − && $name ne "__nosave_begin" | |
| 397 | − && $name ne "__nosave_end" | |
| 398 | − && $name ne "pg0" | |
| 399 | − && $name ne "__module_text_address" | |
| 415 | + elsif ( ! $nameexception{$name} | |
| 400 | 416 | && $name !~ /^__sched_text_/ |
| 401 | 417 | && $name !~ /^__start_/ |
| 402 | 418 | && $name !~ /^__end_/ |
| @@ -407,7 +423,6 @@ sub resolve_external_references · 4 unmodified lines | ||
| 407 | 423 | && $name !~ /^__.*per_cpu_end/ |
| 408 | 424 | && $name !~ /^__alt_instructions/ |
| 409 | 425 | && $name !~ /^__setup_/ |
| 410 | − && $name !~ /^jiffies/ | |
| 411 | 426 | && $name !~ /^__mod_timer/ |
| 412 | 427 | && $name !~ /^__mod_page_state/ |
| 413 | 428 | && $name !~ /^init_module/ |