Commit e596c79050eafea89cf9fe26b7a807643a2a9904
Exists in
master
and in
4 other branches
Merge branch 'misc' of git://git.kernel.org/pub/scm/linux/kernel/git/mmarek/kbuild-2.6
* '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 ...
Showing 34 changed files Side-by-side Diff
- Documentation/coccinelle.txt
- Documentation/kbuild/modules.txt
- MAINTAINERS
- scripts/basic/docproc.c
- scripts/coccicheck
- scripts/coccinelle/alloc/drop_kmalloc_cast.cocci
- scripts/coccinelle/alloc/kzalloc-simple.cocci
- scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci
- scripts/coccinelle/api/alloc/kzalloc-simple.cocci
- scripts/coccinelle/api/err_cast.cocci
- scripts/coccinelle/api/kstrdup.cocci
- scripts/coccinelle/api/memdup.cocci
- scripts/coccinelle/api/memdup_user.cocci
- scripts/coccinelle/api/resource_size.cocci
- scripts/coccinelle/deref_null.cocci
- scripts/coccinelle/err_cast.cocci
- scripts/coccinelle/free/kfree.cocci
- scripts/coccinelle/iterators/fen.cocci
- scripts/coccinelle/iterators/itnull.cocci
- scripts/coccinelle/iterators/list_entry_update.cocci
- scripts/coccinelle/locks/call_kern.cocci
- scripts/coccinelle/locks/double_lock.cocci
- scripts/coccinelle/locks/flags.cocci
- scripts/coccinelle/locks/mini_lock.cocci
- scripts/coccinelle/misc/doubleinit.cocci
- scripts/coccinelle/misc/ifcol.cocci
- scripts/coccinelle/null/deref_null.cocci
- scripts/coccinelle/null/eno.cocci
- scripts/coccinelle/null/kmerr.cocci
- scripts/coccinelle/resource_size.cocci
- scripts/coccinelle/tests/doublebitand.cocci
- scripts/coccinelle/tests/doubletest.cocci
- scripts/extract-ikconfig
- scripts/namespace.pl
Documentation/coccinelle.txt
... | ... | @@ -24,6 +24,9 @@ |
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 |
30 | 33 | |
31 | 34 | |
32 | 35 | |
... | ... | @@ -41,20 +44,22 @@ |
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 | |
61 | 66 | |
... | ... | @@ -68,9 +73,9 @@ |
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 | |
77 | 82 | |
... | ... | @@ -93,12 +98,35 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 |
Documentation/kbuild/modules.txt
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 | |
133 | +--- 2.4 Building Separate Files | |
134 | + | |
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 | |
143 | 137 | 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 | 138 | |
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 / | |
150 | 144 | |
151 | -=== 3. Example commands | |
152 | 145 | |
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. | |
146 | +=== 3. Creating a Kbuild File for an External Module | |
159 | 147 | |
160 | -# Kernel source | |
161 | -/lib/modules/<kernel-version>/source -> /usr/src/linux-<version> | |
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: | |
162 | 153 | |
163 | -# Output from kernel compile | |
164 | -/lib/modules/<kernel-version>/build -> /usr/src/linux-<version>-up | |
154 | + obj-m := <module_name>.o | |
165 | 155 | |
166 | -Change to the directory where the kbuild file is located and execute | |
167 | -the following commands to build the module: | |
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: | |
168 | 161 | |
169 | - cd /home/user/src/module | |
170 | - make -C /usr/src/`uname -r`/source \ | |
171 | - O=/lib/modules/`uname-r`/build \ | |
172 | - M=`pwd` | |
162 | + <module_name>-y := <src1>.o <src2>.o ... | |
173 | 163 | |
174 | -Then, to install the module use the following command: | |
164 | +NOTE: Further documentation describing the syntax used by kbuild is | |
165 | +located in Documentation/kbuild/makefiles.txt. | |
175 | 166 | |
176 | - make -C /usr/src/`uname -r`/source \ | |
177 | - O=/lib/modules/`uname-r`/build \ | |
178 | - M=`pwd` \ | |
179 | - modules_install | |
167 | +The examples below demonstrate how to create a build file for the | |
168 | +module 8123.ko, which is built from the following files: | |
180 | 169 | |
181 | -If you look closely you will see that this is the same command as | |
182 | -listed before - with the directories spelled out. | |
183 | - | |
184 | -The above are rather long commands, and the following chapter | |
185 | -lists a few tricks to make it all easier. | |
186 | - | |
187 | - | |
188 | -=== 4. Creating a kbuild file for an external module | |
189 | - | |
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. | |
193 | - | |
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. | |
197 | - | |
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 |
216 | 186 | |
... | ... | @@ -219,11 +189,11 @@ |
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: |
230 | 200 | |
231 | 201 | |
232 | 202 | |
233 | 203 | |
234 | 204 | |
235 | 205 | |
... | ... | @@ -231,36 +201,42 @@ |
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. | |
238 | 211 | |
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: | |
212 | +--- 3.2 Separate Kbuild File and Makefile | |
243 | 213 | |
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: | |
218 | + | |
244 | 219 | Example 2: |
245 | 220 | --> filename: Kbuild |
246 | 221 | obj-m := 8123.o |
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 | |
253 | 226 | |
227 | + default: | |
228 | + $(MAKE) -C $(KDIR) M=$$PWD | |
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 |
267 | 243 | |
268 | 244 | |
269 | 245 | |
... | ... | @@ -269,13 +245,15 @@ |
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: |
282 | 260 | |
283 | 261 | |
284 | 262 | |
285 | 263 | |
286 | 264 | |
287 | 265 | |
288 | 266 | |
289 | 267 | |
290 | 268 | |
291 | 269 | |
292 | 270 | |
293 | 271 | |
294 | 272 | |
295 | 273 | |
296 | 274 | |
297 | 275 | |
298 | 276 | |
299 | 277 | |
300 | 278 | |
301 | 279 | |
302 | 280 | |
303 | 281 | |
304 | 282 | |
305 | 283 | |
306 | 284 | |
307 | 285 | |
308 | 286 | |
309 | 287 | |
310 | 288 | |
311 | 289 | |
312 | 290 | |
313 | 291 | |
314 | 292 | |
315 | 293 | |
316 | 294 | |
317 | 295 | |
318 | 296 | |
319 | 297 | |
320 | 298 | |
321 | 299 | |
322 | 300 | |
323 | 301 | |
324 | 302 | |
325 | 303 | |
326 | 304 | |
327 | 305 | |
328 | 306 | |
329 | 307 | |
330 | 308 | |
331 | 309 | |
332 | 310 | |
333 | 311 | |
334 | 312 | |
335 | 313 | |
336 | 314 | |
337 | 315 | |
338 | 316 | |
339 | 317 | |
340 | 318 | |
341 | 319 | |
342 | 320 | |
343 | 321 | |
344 | 322 | |
345 | 323 | |
346 | 324 | |
347 | 325 | |
348 | 326 | |
349 | 327 | |
350 | 328 | |
351 | 329 | |
... | ... | @@ -283,270 +261,281 @@ |
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. | |
300 | 277 | |
301 | - Example 4: | |
302 | - obj-m := 8123.o | |
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. | |
281 | + | |
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. | |
308 | 287 | |
288 | +--- 3.4 Building Multiple Modules | |
309 | 289 | |
310 | -=== 5. Include files | |
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: | |
311 | 293 | |
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. | |
294 | + obj-m := foo.o bar.o | |
295 | + foo-y := <foo_srcs> | |
296 | + bar-y := <bar_srcs> | |
316 | 297 | |
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. | |
298 | + It is that simple! | |
322 | 299 | |
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)/*. | |
326 | 300 | |
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. | |
301 | +=== 4. Include Files | |
329 | 302 | |
330 | ---- 5.1 How to include files from the kernel include dir | |
303 | +Within the kernel, header files are kept in standard locations | |
304 | +according to the following rule: | |
331 | 305 | |
332 | - When a module needs to include a file from include/linux/, then one | |
333 | - just uses: | |
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/. | |
334 | 312 | |
335 | - #include <linux/modules.h> | |
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/. | |
336 | 317 | |
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. | |
318 | +--- 4.1 Kernel Includes | |
340 | 319 | |
341 | - #include "8123_if.h" | |
320 | + To include a header file located under include/linux/, simply | |
321 | + use: | |
342 | 322 | |
343 | - will do the job. | |
323 | + #include <linux/module.h> | |
344 | 324 | |
345 | ---- 5.2 External modules using an include/ dir | |
325 | + kbuild will add options to "gcc" so the relevant directories | |
326 | + are searched. | |
346 | 327 | |
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). | |
328 | +--- 4.2 Single Subdirectory | |
352 | 329 | |
353 | - In our example, if we move 8123_if.h to a subdirectory named include/ | |
354 | - the resulting Kbuild file would look like: | |
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. | |
355 | 334 | |
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: | |
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 | |
349 | +--- 4.3 Several Subdirectories | |
366 | 350 | |
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. | |
370 | - | |
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 | |
354 | + . | |
355 | + |__ src | |
356 | + | |__ complex_main.c | |
357 | + | |__ hal | |
358 | + | |__ hardwareif.c | |
359 | + | |__ include | |
360 | + | |__ hardwareif.h | |
361 | + |__ include | |
362 | + |__ complex.h | |
378 | 363 | |
379 | - To build a single module named complex.ko, we then need the following | |
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 | |
406 | + => Install dir: /frodo/lib/modules/$(KERNELRELEASE)/kernel/ | |
423 | 407 | |
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. | |
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. | |
428 | 412 | |
429 | ---- 6.2 INSTALL_MOD_DIR | |
413 | +--- 5.2 INSTALL_MOD_DIR | |
430 | 414 | |
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'. | |
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." | |
436 | 420 | |
437 | - $ make INSTALL_MOD_DIR=gandalf -C KERNELDIR \ | |
438 | - M=`pwd` modules_install | |
439 | - => Install dir: /lib/modules/$(KERNELRELEASE)/gandalf | |
421 | + $ make INSTALL_MOD_DIR=gandalf -C $KDIR \ | |
422 | + M=$PWD modules_install | |
423 | + => Install dir: /lib/modules/$(KERNELRELEASE)/gandalf/ | |
440 | 424 | |
441 | 425 | |
442 | -=== 7. Module versioning & Module.symvers | |
426 | +=== 6. Module Versioning | |
443 | 427 | |
444 | -Module versioning is enabled by the CONFIG_MODVERSIONS tag. | |
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. | |
445 | 434 | |
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. | |
435 | +Module.symvers contains a list of all exported symbols from a kernel | |
436 | +build. | |
451 | 437 | |
452 | -Module.symvers contains a list of all exported symbols from a kernel build. | |
438 | +--- 6.1 Symbols From the Kernel (vmlinux + modules) | |
453 | 439 | |
454 | ---- 7.1 Symbols from the kernel (vmlinux + modules) | |
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. | |
455 | 444 | |
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. | |
460 | - | |
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 | |
454 | + 1) It lists all exported symbols from vmlinux and all modules. | |
455 | + 2) It lists the CRC if CONFIG_MODVERSIONS is enabled. | |
472 | 456 | |
473 | ---- 7.2 Symbols and external modules | |
457 | +--- 6.2 Symbols and External Modules | |
474 | 458 | |
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. | |
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. | |
483 | 468 | |
484 | ---- 7.3 Symbols from another external module | |
469 | +--- 6.3 Symbols From Another External Module | |
485 | 470 | |
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. | |
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. | |
493 | 475 | |
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. | |
476 | + NOTE: The method with a top-level kbuild file is recommended | |
477 | + but may be impractical in certain situations. | |
498 | 478 | |
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: | |
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: | |
503 | 485 | |
504 | - #./Kbuild: (this file may also be named Makefile) | |
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 | |
509 | 495 | |
510 | - will then do the expected and compile both modules with full | |
511 | - knowledge on symbols from both modules. | |
496 | + $ make -C $KDIR M=$PWD | |
512 | 497 | |
498 | + will then do the expected and compile both modules with | |
499 | + full knowledge of symbols from either module. | |
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. | |
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. | |
525 | 512 | |
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. | |
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. | |
532 | 519 | |
533 | -=== 8. Tips & Tricks | |
534 | 520 | |
535 | ---- 8.1 Testing for CONFIG_FOO_BAR | |
521 | +=== 7. Tips & Tricks | |
536 | 522 | |
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. | |
523 | +--- 7.1 Testing for CONFIG_FOO_BAR | |
540 | 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. | |
529 | + | |
541 | 530 | #fs/ext2/Makefile |
542 | 531 | obj-$(CONFIG_EXT2_FS) += ext2.o |
543 | 532 | |
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. |
MAINTAINERS
... | ... | @@ -1613,7 +1613,7 @@ |
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 |
scripts/basic/docproc.c
scripts/coccicheck
... | ... | @@ -16,6 +16,7 @@ |
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 |
22 | 23 | |
23 | 24 | |
... | ... | @@ -25,11 +26,13 @@ |
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 @@ |
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 | |
51 | 54 | |
52 | 55 | |
53 | 56 | |
54 | 57 | |
... | ... | @@ -52,21 +55,44 @@ |
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 | |
63 | + sed -ne 's|^///||p' $COCCI | |
59 | 64 | |
60 | - echo ' The semantic patch that makes this change is available' | |
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 | } |
scripts/coccinelle/alloc/drop_kmalloc_cast.cocci
1 | -/// | |
2 | -/// Casting (void *) value returned by kmalloc is useless | |
3 | -/// as mentioned in Documentation/CodingStyle, Chap 14. | |
4 | -/// | |
5 | -// Confidence: High | |
6 | -// Copyright: 2009,2010 Nicolas Palix, DIKU. GPLv2. | |
7 | -// URL: http://coccinelle.lip6.fr/ | |
8 | -// Options: -no_includes -include_headers | |
9 | -// | |
10 | -// Keywords: kmalloc, kzalloc, kcalloc | |
11 | -// Version min: < 2.6.12 kmalloc | |
12 | -// Version min: < 2.6.12 kcalloc | |
13 | -// Version min: 2.6.14 kzalloc | |
14 | -// | |
15 | - | |
16 | -virtual context | |
17 | -virtual patch | |
18 | -virtual org | |
19 | -virtual report | |
20 | - | |
21 | -//---------------------------------------------------------- | |
22 | -// For context mode | |
23 | -//---------------------------------------------------------- | |
24 | - | |
25 | -@depends on context@ | |
26 | -type T; | |
27 | -@@ | |
28 | - | |
29 | -* (T *) | |
30 | - \(kmalloc\|kzalloc\|kcalloc\)(...) | |
31 | - | |
32 | -//---------------------------------------------------------- | |
33 | -// For patch mode | |
34 | -//---------------------------------------------------------- | |
35 | - | |
36 | -@depends on patch@ | |
37 | -type T; | |
38 | -@@ | |
39 | - | |
40 | -- (T *) | |
41 | - \(kmalloc\|kzalloc\|kcalloc\)(...) | |
42 | - | |
43 | -//---------------------------------------------------------- | |
44 | -// For org and report mode | |
45 | -//---------------------------------------------------------- | |
46 | - | |
47 | -@r depends on org || report@ | |
48 | -type T; | |
49 | -position p; | |
50 | -@@ | |
51 | - | |
52 | - (T@p *)\(kmalloc\|kzalloc\|kcalloc\)(...) | |
53 | - | |
54 | -@script:python depends on org@ | |
55 | -p << r.p; | |
56 | -t << r.T; | |
57 | -@@ | |
58 | - | |
59 | -coccilib.org.print_safe_todo(p[0], t) | |
60 | - | |
61 | -@script:python depends on report@ | |
62 | -p << r.p; | |
63 | -t << r.T; | |
64 | -@@ | |
65 | - | |
66 | -msg="WARNING: casting value returned by k[cmz]alloc to (%s *) is useless." % (t) | |
67 | -coccilib.report.print_report(p[0], msg) |
scripts/coccinelle/alloc/kzalloc-simple.cocci
1 | -/// | |
2 | -/// kzalloc should be used rather than kmalloc followed by memset 0 | |
3 | -/// | |
4 | -// Confidence: High | |
5 | -// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2. | |
6 | -// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
7 | -// URL: http://coccinelle.lip6.fr/rules/kzalloc.html | |
8 | -// Options: -no_includes -include_headers | |
9 | -// | |
10 | -// Keywords: kmalloc, kzalloc | |
11 | -// Version min: < 2.6.12 kmalloc | |
12 | -// Version min: 2.6.14 kzalloc | |
13 | -// | |
14 | - | |
15 | -virtual context | |
16 | -virtual patch | |
17 | -virtual org | |
18 | -virtual report | |
19 | - | |
20 | -//---------------------------------------------------------- | |
21 | -// For context mode | |
22 | -//---------------------------------------------------------- | |
23 | - | |
24 | -@depends on context@ | |
25 | -type T, T2; | |
26 | -expression x; | |
27 | -expression E1,E2; | |
28 | -statement S; | |
29 | -@@ | |
30 | - | |
31 | -* x = (T)kmalloc(E1,E2); | |
32 | - if ((x==NULL) || ...) S | |
33 | -* memset((T2)x,0,E1); | |
34 | - | |
35 | -//---------------------------------------------------------- | |
36 | -// For patch mode | |
37 | -//---------------------------------------------------------- | |
38 | - | |
39 | -@depends on patch@ | |
40 | -type T, T2; | |
41 | -expression x; | |
42 | -expression E1,E2; | |
43 | -statement S; | |
44 | -@@ | |
45 | - | |
46 | -- x = (T)kmalloc(E1,E2); | |
47 | -+ x = kzalloc(E1,E2); | |
48 | - if ((x==NULL) || ...) S | |
49 | -- memset((T2)x,0,E1); | |
50 | - | |
51 | -//---------------------------------------------------------- | |
52 | -// For org mode | |
53 | -//---------------------------------------------------------- | |
54 | - | |
55 | -@r depends on org || report@ | |
56 | -type T, T2; | |
57 | -expression x; | |
58 | -expression E1,E2; | |
59 | -statement S; | |
60 | -position p; | |
61 | -@@ | |
62 | - | |
63 | - x = (T)kmalloc@p(E1,E2); | |
64 | - if ((x==NULL) || ...) S | |
65 | - memset((T2)x,0,E1); | |
66 | - | |
67 | -@script:python depends on org@ | |
68 | -p << r.p; | |
69 | -x << r.x; | |
70 | -@@ | |
71 | - | |
72 | -msg="%s" % (x) | |
73 | -msg_safe=msg.replace("[","@(").replace("]",")") | |
74 | -coccilib.org.print_todo(p[0], msg_safe) | |
75 | - | |
76 | -@script:python depends on report@ | |
77 | -p << r.p; | |
78 | -x << r.x; | |
79 | -@@ | |
80 | - | |
81 | -msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x) | |
82 | -coccilib.report.print_report(p[0], msg) |
scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci
1 | +/// | |
2 | +/// Casting (void *) value returned by kmalloc is useless | |
3 | +/// as mentioned in Documentation/CodingStyle, Chap 14. | |
4 | +/// | |
5 | +// Confidence: High | |
6 | +// Copyright: 2009,2010 Nicolas Palix, DIKU. GPLv2. | |
7 | +// URL: http://coccinelle.lip6.fr/ | |
8 | +// Options: -no_includes -include_headers | |
9 | +// | |
10 | +// Keywords: kmalloc, kzalloc, kcalloc | |
11 | +// Version min: < 2.6.12 kmalloc | |
12 | +// Version min: < 2.6.12 kcalloc | |
13 | +// Version min: 2.6.14 kzalloc | |
14 | +// | |
15 | + | |
16 | +virtual context | |
17 | +virtual patch | |
18 | +virtual org | |
19 | +virtual report | |
20 | + | |
21 | +//---------------------------------------------------------- | |
22 | +// For context mode | |
23 | +//---------------------------------------------------------- | |
24 | + | |
25 | +@depends on context@ | |
26 | +type T; | |
27 | +@@ | |
28 | + | |
29 | +* (T *) | |
30 | + \(kmalloc\|kzalloc\|kcalloc\)(...) | |
31 | + | |
32 | +//---------------------------------------------------------- | |
33 | +// For patch mode | |
34 | +//---------------------------------------------------------- | |
35 | + | |
36 | +@depends on patch@ | |
37 | +type T; | |
38 | +@@ | |
39 | + | |
40 | +- (T *) | |
41 | + \(kmalloc\|kzalloc\|kcalloc\)(...) | |
42 | + | |
43 | +//---------------------------------------------------------- | |
44 | +// For org and report mode | |
45 | +//---------------------------------------------------------- | |
46 | + | |
47 | +@r depends on org || report@ | |
48 | +type T; | |
49 | +position p; | |
50 | +@@ | |
51 | + | |
52 | + (T@p *)\(kmalloc\|kzalloc\|kcalloc\)(...) | |
53 | + | |
54 | +@script:python depends on org@ | |
55 | +p << r.p; | |
56 | +t << r.T; | |
57 | +@@ | |
58 | + | |
59 | +coccilib.org.print_safe_todo(p[0], t) | |
60 | + | |
61 | +@script:python depends on report@ | |
62 | +p << r.p; | |
63 | +t << r.T; | |
64 | +@@ | |
65 | + | |
66 | +msg="WARNING: casting value returned by k[cmz]alloc to (%s *) is useless." % (t) | |
67 | +coccilib.report.print_report(p[0], msg) |
scripts/coccinelle/api/alloc/kzalloc-simple.cocci
1 | +/// | |
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 | |
7 | +/// | |
8 | +// Confidence: High | |
9 | +// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2. | |
10 | +// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
11 | +// URL: http://coccinelle.lip6.fr/rules/kzalloc.html | |
12 | +// Options: -no_includes -include_headers | |
13 | +// | |
14 | +// Keywords: kmalloc, kzalloc | |
15 | +// Version min: < 2.6.12 kmalloc | |
16 | +// Version min: 2.6.14 kzalloc | |
17 | +// | |
18 | + | |
19 | +virtual context | |
20 | +virtual patch | |
21 | +virtual org | |
22 | +virtual report | |
23 | + | |
24 | +//---------------------------------------------------------- | |
25 | +// For context mode | |
26 | +//---------------------------------------------------------- | |
27 | + | |
28 | +@depends on context@ | |
29 | +type T, T2; | |
30 | +expression x; | |
31 | +expression E1,E2; | |
32 | +statement S; | |
33 | +@@ | |
34 | + | |
35 | +* x = (T)kmalloc(E1,E2); | |
36 | + if ((x==NULL) || ...) S | |
37 | +* memset((T2)x,0,E1); | |
38 | + | |
39 | +//---------------------------------------------------------- | |
40 | +// For patch mode | |
41 | +//---------------------------------------------------------- | |
42 | + | |
43 | +@depends on patch@ | |
44 | +type T, T2; | |
45 | +expression x; | |
46 | +expression E1,E2; | |
47 | +statement S; | |
48 | +@@ | |
49 | + | |
50 | +- x = (T)kmalloc(E1,E2); | |
51 | ++ x = kzalloc(E1,E2); | |
52 | + if ((x==NULL) || ...) S | |
53 | +- memset((T2)x,0,E1); | |
54 | + | |
55 | +//---------------------------------------------------------- | |
56 | +// For org mode | |
57 | +//---------------------------------------------------------- | |
58 | + | |
59 | +@r depends on org || report@ | |
60 | +type T, T2; | |
61 | +expression x; | |
62 | +expression E1,E2; | |
63 | +statement S; | |
64 | +position p; | |
65 | +@@ | |
66 | + | |
67 | + x = (T)kmalloc@p(E1,E2); | |
68 | + if ((x==NULL) || ...) S | |
69 | + memset((T2)x,0,E1); | |
70 | + | |
71 | +@script:python depends on org@ | |
72 | +p << r.p; | |
73 | +x << r.x; | |
74 | +@@ | |
75 | + | |
76 | +msg="%s" % (x) | |
77 | +msg_safe=msg.replace("[","@(").replace("]",")") | |
78 | +coccilib.org.print_todo(p[0], msg_safe) | |
79 | + | |
80 | +@script:python depends on report@ | |
81 | +p << r.p; | |
82 | +x << r.x; | |
83 | +@@ | |
84 | + | |
85 | +msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x) | |
86 | +coccilib.report.print_report(p[0], msg) |
scripts/coccinelle/api/err_cast.cocci
1 | +/// | |
2 | +/// Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...)) | |
3 | +/// | |
4 | +// Confidence: High | |
5 | +// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2. | |
6 | +// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2. | |
7 | +// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
8 | +// URL: http://coccinelle.lip6.fr/ | |
9 | +// Options: | |
10 | +// | |
11 | +// Keywords: ERR_PTR, PTR_ERR, ERR_CAST | |
12 | +// Version min: 2.6.25 | |
13 | +// | |
14 | + | |
15 | +virtual context | |
16 | +virtual patch | |
17 | +virtual org | |
18 | +virtual report | |
19 | + | |
20 | + | |
21 | +@ depends on context && !patch && !org && !report@ | |
22 | +expression x; | |
23 | +@@ | |
24 | + | |
25 | +* ERR_PTR(PTR_ERR(x)) | |
26 | + | |
27 | +@ depends on !context && patch && !org && !report @ | |
28 | +expression x; | |
29 | +@@ | |
30 | + | |
31 | +- ERR_PTR(PTR_ERR(x)) | |
32 | ++ ERR_CAST(x) | |
33 | + | |
34 | +@r depends on !context && !patch && (org || report)@ | |
35 | +expression x; | |
36 | +position p; | |
37 | +@@ | |
38 | + | |
39 | + ERR_PTR@p(PTR_ERR(x)) | |
40 | + | |
41 | +@script:python depends on org@ | |
42 | +p << r.p; | |
43 | +x << r.x; | |
44 | +@@ | |
45 | + | |
46 | +msg="WARNING ERR_CAST can be used with %s" % (x) | |
47 | +msg_safe=msg.replace("[","@(").replace("]",")") | |
48 | +coccilib.org.print_todo(p[0], msg_safe) | |
49 | + | |
50 | +@script:python depends on report@ | |
51 | +p << r.p; | |
52 | +x << r.x; | |
53 | +@@ | |
54 | + | |
55 | +msg="WARNING: ERR_CAST can be used with %s" % (x) | |
56 | +coccilib.report.print_report(p[0], msg) |
scripts/coccinelle/api/kstrdup.cocci
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); |
scripts/coccinelle/api/memdup.cocci
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); |
scripts/coccinelle/api/memdup_user.cocci
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 | +- } |
scripts/coccinelle/api/resource_size.cocci
1 | +/// | |
2 | +/// Use resource_size function on resource object | |
3 | +/// instead of explicit computation. | |
4 | +/// | |
5 | +// Confidence: High | |
6 | +// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2. | |
7 | +// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2. | |
8 | +// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
9 | +// URL: http://coccinelle.lip6.fr/ | |
10 | +// Options: | |
11 | +// | |
12 | +// Keywords: resource_size | |
13 | +// Version min: 2.6.27 resource_size | |
14 | +// | |
15 | + | |
16 | +virtual context | |
17 | +virtual patch | |
18 | +virtual org | |
19 | +virtual report | |
20 | + | |
21 | +//---------------------------------------------------------- | |
22 | +// For context mode | |
23 | +//---------------------------------------------------------- | |
24 | + | |
25 | +@r_context depends on context && !patch && !org@ | |
26 | +struct resource *res; | |
27 | +@@ | |
28 | + | |
29 | +* (res->end - res->start) + 1 | |
30 | + | |
31 | +//---------------------------------------------------------- | |
32 | +// For patch mode | |
33 | +//---------------------------------------------------------- | |
34 | + | |
35 | +@r_patch depends on !context && patch && !org@ | |
36 | +struct resource *res; | |
37 | +@@ | |
38 | + | |
39 | +- (res->end - res->start) + 1 | |
40 | ++ resource_size(res) | |
41 | + | |
42 | +//---------------------------------------------------------- | |
43 | +// For org mode | |
44 | +//---------------------------------------------------------- | |
45 | + | |
46 | + | |
47 | +@r_org depends on !context && !patch && (org || report)@ | |
48 | +struct resource *res; | |
49 | +position p; | |
50 | +@@ | |
51 | + | |
52 | + (res->end@p - res->start) + 1 | |
53 | + | |
54 | +@rbad_org depends on !context && !patch && (org || report)@ | |
55 | +struct resource *res; | |
56 | +position p != r_org.p; | |
57 | +@@ | |
58 | + | |
59 | + res->end@p - res->start | |
60 | + | |
61 | +@script:python depends on org@ | |
62 | +p << r_org.p; | |
63 | +x << r_org.res; | |
64 | +@@ | |
65 | + | |
66 | +msg="ERROR with %s" % (x) | |
67 | +msg_safe=msg.replace("[","@(").replace("]",")") | |
68 | +coccilib.org.print_todo(p[0], msg_safe) | |
69 | + | |
70 | +@script:python depends on report@ | |
71 | +p << r_org.p; | |
72 | +x << r_org.res; | |
73 | +@@ | |
74 | + | |
75 | +msg="ERROR: Missing resource_size with %s" % (x) | |
76 | +coccilib.report.print_report(p[0], msg) | |
77 | + | |
78 | +@script:python depends on org@ | |
79 | +p << rbad_org.p; | |
80 | +x << rbad_org.res; | |
81 | +@@ | |
82 | + | |
83 | +msg="WARNING with %s" % (x) | |
84 | +msg_safe=msg.replace("[","@(").replace("]",")") | |
85 | +coccilib.org.print_todo(p[0], msg_safe) | |
86 | + | |
87 | +@script:python depends on report@ | |
88 | +p << rbad_org.p; | |
89 | +x << rbad_org.res; | |
90 | +@@ | |
91 | + | |
92 | +msg="WARNING: Suspicious code. resource_size is maybe missing with %s" % (x) | |
93 | +coccilib.report.print_report(p[0], msg) |
scripts/coccinelle/deref_null.cocci
1 | -/// | |
2 | -/// A variable is dereference under a NULL test. | |
3 | -/// Even though it is know to be NULL. | |
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: -I ... -all_includes can give more complete results | |
11 | -// Options: | |
12 | - | |
13 | -virtual context | |
14 | -virtual patch | |
15 | -virtual org | |
16 | -virtual report | |
17 | - | |
18 | -@initialize:python depends on !context && patch && !org && !report@ | |
19 | - | |
20 | -import sys | |
21 | -print >> sys.stderr, "This semantic patch does not support the 'patch' mode." | |
22 | - | |
23 | -@depends on patch@ | |
24 | -@@ | |
25 | - | |
26 | -this_rule_should_never_matches(); | |
27 | - | |
28 | -@ifm depends on !patch@ | |
29 | -expression *E; | |
30 | -statement S1,S2; | |
31 | -position p1; | |
32 | -@@ | |
33 | - | |
34 | -if@p1 ((E == NULL && ...) || ...) S1 else S2 | |
35 | - | |
36 | -// The following two rules are separate, because both can match a single | |
37 | -// expression in different ways | |
38 | -@pr1 depends on !patch expression@ | |
39 | -expression *ifm.E; | |
40 | -identifier f; | |
41 | -position p1; | |
42 | -@@ | |
43 | - | |
44 | - (E != NULL && ...) ? <+...E->f@p1...+> : ... | |
45 | - | |
46 | -@pr2 depends on !patch expression@ | |
47 | -expression *ifm.E; | |
48 | -identifier f; | |
49 | -position p2; | |
50 | -@@ | |
51 | - | |
52 | -( | |
53 | - (E != NULL) && ... && <+...E->f@p2...+> | |
54 | -| | |
55 | - (E == NULL) || ... || <+...E->f@p2...+> | |
56 | -| | |
57 | - sizeof(<+...E->f@p2...+>) | |
58 | -) | |
59 | - | |
60 | -// For org and report modes | |
61 | - | |
62 | -@r depends on !context && !patch && (org || report) exists@ | |
63 | -expression subE <= ifm.E; | |
64 | -expression *ifm.E; | |
65 | -expression E1,E2; | |
66 | -identifier f; | |
67 | -statement S1,S2,S3,S4; | |
68 | -iterator iter; | |
69 | -position p!={pr1.p1,pr2.p2}; | |
70 | -position ifm.p1; | |
71 | -@@ | |
72 | - | |
73 | -if@p1 ((E == NULL && ...) || ...) | |
74 | -{ | |
75 | - ... when != if (...) S1 else S2 | |
76 | -( | |
77 | - iter(subE,...) S4 // no use | |
78 | -| | |
79 | - list_remove_head(E2,subE,...) | |
80 | -| | |
81 | - subE = E1 | |
82 | -| | |
83 | - for(subE = E1;...;...) S4 | |
84 | -| | |
85 | - subE++ | |
86 | -| | |
87 | - ++subE | |
88 | -| | |
89 | - --subE | |
90 | -| | |
91 | - subE-- | |
92 | -| | |
93 | - &subE | |
94 | -| | |
95 | - E->f@p // bad use | |
96 | -) | |
97 | - ... when any | |
98 | - return ...; | |
99 | -} | |
100 | -else S3 | |
101 | - | |
102 | -@script:python depends on !context && !patch && !org && report@ | |
103 | -p << r.p; | |
104 | -p1 << ifm.p1; | |
105 | -x << ifm.E; | |
106 | -@@ | |
107 | - | |
108 | -msg="ERROR: %s is NULL but dereferenced." % (x) | |
109 | -coccilib.report.print_report(p[0], msg) | |
110 | -cocci.include_match(False) | |
111 | - | |
112 | -@script:python depends on !context && !patch && org && !report@ | |
113 | -p << r.p; | |
114 | -p1 << ifm.p1; | |
115 | -x << ifm.E; | |
116 | -@@ | |
117 | - | |
118 | -msg="ERROR: %s is NULL but dereferenced." % (x) | |
119 | -msg_safe=msg.replace("[","@(").replace("]",")") | |
120 | -cocci.print_main(msg_safe,p) | |
121 | -cocci.include_match(False) | |
122 | - | |
123 | -@s depends on !context && !patch && (org || report) exists@ | |
124 | -expression subE <= ifm.E; | |
125 | -expression *ifm.E; | |
126 | -expression E1,E2; | |
127 | -identifier f; | |
128 | -statement S1,S2,S3,S4; | |
129 | -iterator iter; | |
130 | -position p!={pr1.p1,pr2.p2}; | |
131 | -position ifm.p1; | |
132 | -@@ | |
133 | - | |
134 | -if@p1 ((E == NULL && ...) || ...) | |
135 | -{ | |
136 | - ... when != if (...) S1 else S2 | |
137 | -( | |
138 | - iter(subE,...) S4 // no use | |
139 | -| | |
140 | - list_remove_head(E2,subE,...) | |
141 | -| | |
142 | - subE = E1 | |
143 | -| | |
144 | - for(subE = E1;...;...) S4 | |
145 | -| | |
146 | - subE++ | |
147 | -| | |
148 | - ++subE | |
149 | -| | |
150 | - --subE | |
151 | -| | |
152 | - subE-- | |
153 | -| | |
154 | - &subE | |
155 | -| | |
156 | - E->f@p // bad use | |
157 | -) | |
158 | - ... when any | |
159 | -} | |
160 | -else S3 | |
161 | - | |
162 | -@script:python depends on !context && !patch && !org && report@ | |
163 | -p << s.p; | |
164 | -p1 << ifm.p1; | |
165 | -x << ifm.E; | |
166 | -@@ | |
167 | - | |
168 | -msg="ERROR: %s is NULL but dereferenced." % (x) | |
169 | -coccilib.report.print_report(p[0], msg) | |
170 | - | |
171 | -@script:python depends on !context && !patch && org && !report@ | |
172 | -p << s.p; | |
173 | -p1 << ifm.p1; | |
174 | -x << ifm.E; | |
175 | -@@ | |
176 | - | |
177 | -msg="ERROR: %s is NULL but dereferenced." % (x) | |
178 | -msg_safe=msg.replace("[","@(").replace("]",")") | |
179 | -cocci.print_main(msg_safe,p) | |
180 | - | |
181 | -// For context mode | |
182 | - | |
183 | -@depends on context && !patch && !org && !report exists@ | |
184 | -expression subE <= ifm.E; | |
185 | -expression *ifm.E; | |
186 | -expression E1,E2; | |
187 | -identifier f; | |
188 | -statement S1,S2,S3,S4; | |
189 | -iterator iter; | |
190 | -position p!={pr1.p1,pr2.p2}; | |
191 | -position ifm.p1; | |
192 | -@@ | |
193 | - | |
194 | -if@p1 ((E == NULL && ...) || ...) | |
195 | -{ | |
196 | - ... when != if (...) S1 else S2 | |
197 | -( | |
198 | - iter(subE,...) S4 // no use | |
199 | -| | |
200 | - list_remove_head(E2,subE,...) | |
201 | -| | |
202 | - subE = E1 | |
203 | -| | |
204 | - for(subE = E1;...;...) S4 | |
205 | -| | |
206 | - subE++ | |
207 | -| | |
208 | - ++subE | |
209 | -| | |
210 | - --subE | |
211 | -| | |
212 | - subE-- | |
213 | -| | |
214 | - &subE | |
215 | -| | |
216 | -* E->f@p // bad use | |
217 | -) | |
218 | - ... when any | |
219 | - return ...; | |
220 | -} | |
221 | -else S3 | |
222 | - | |
223 | -// The following three rules are duplicates of ifm, pr1 and pr2 respectively. | |
224 | -// It is need because the previous rule as already made a "change". | |
225 | - | |
226 | -@ifm1 depends on !patch@ | |
227 | -expression *E; | |
228 | -statement S1,S2; | |
229 | -position p1; | |
230 | -@@ | |
231 | - | |
232 | -if@p1 ((E == NULL && ...) || ...) S1 else S2 | |
233 | - | |
234 | -@pr11 depends on !patch expression@ | |
235 | -expression *ifm1.E; | |
236 | -identifier f; | |
237 | -position p1; | |
238 | -@@ | |
239 | - | |
240 | - (E != NULL && ...) ? <+...E->f@p1...+> : ... | |
241 | - | |
242 | -@pr12 depends on !patch expression@ | |
243 | -expression *ifm1.E; | |
244 | -identifier f; | |
245 | -position p2; | |
246 | -@@ | |
247 | - | |
248 | -( | |
249 | - (E != NULL) && ... && <+...E->f@p2...+> | |
250 | -| | |
251 | - (E == NULL) || ... || <+...E->f@p2...+> | |
252 | -| | |
253 | - sizeof(<+...E->f@p2...+>) | |
254 | -) | |
255 | - | |
256 | -@depends on context && !patch && !org && !report exists@ | |
257 | -expression subE <= ifm1.E; | |
258 | -expression *ifm1.E; | |
259 | -expression E1,E2; | |
260 | -identifier f; | |
261 | -statement S1,S2,S3,S4; | |
262 | -iterator iter; | |
263 | -position p!={pr11.p1,pr12.p2}; | |
264 | -position ifm1.p1; | |
265 | -@@ | |
266 | - | |
267 | -if@p1 ((E == NULL && ...) || ...) | |
268 | -{ | |
269 | - ... when != if (...) S1 else S2 | |
270 | -( | |
271 | - iter(subE,...) S4 // no use | |
272 | -| | |
273 | - list_remove_head(E2,subE,...) | |
274 | -| | |
275 | - subE = E1 | |
276 | -| | |
277 | - for(subE = E1;...;...) S4 | |
278 | -| | |
279 | - subE++ | |
280 | -| | |
281 | - ++subE | |
282 | -| | |
283 | - --subE | |
284 | -| | |
285 | - subE-- | |
286 | -| | |
287 | - &subE | |
288 | -| | |
289 | -* E->f@p // bad use | |
290 | -) | |
291 | - ... when any | |
292 | -} | |
293 | -else S3 |
scripts/coccinelle/err_cast.cocci
1 | -/// | |
2 | -/// Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...)) | |
3 | -/// | |
4 | -// Confidence: High | |
5 | -// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2. | |
6 | -// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2. | |
7 | -// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
8 | -// URL: http://coccinelle.lip6.fr/ | |
9 | -// Options: | |
10 | -// | |
11 | -// Keywords: ERR_PTR, PTR_ERR, ERR_CAST | |
12 | -// Version min: 2.6.25 | |
13 | -// | |
14 | - | |
15 | -virtual context | |
16 | -virtual patch | |
17 | -virtual org | |
18 | -virtual report | |
19 | - | |
20 | - | |
21 | -@ depends on context && !patch && !org && !report@ | |
22 | -expression x; | |
23 | -@@ | |
24 | - | |
25 | -* ERR_PTR(PTR_ERR(x)) | |
26 | - | |
27 | -@ depends on !context && patch && !org && !report @ | |
28 | -expression x; | |
29 | -@@ | |
30 | - | |
31 | -- ERR_PTR(PTR_ERR(x)) | |
32 | -+ ERR_CAST(x) | |
33 | - | |
34 | -@r depends on !context && !patch && (org || report)@ | |
35 | -expression x; | |
36 | -position p; | |
37 | -@@ | |
38 | - | |
39 | - ERR_PTR@p(PTR_ERR(x)) | |
40 | - | |
41 | -@script:python depends on org@ | |
42 | -p << r.p; | |
43 | -x << r.x; | |
44 | -@@ | |
45 | - | |
46 | -msg="WARNING ERR_CAST can be used with %s" % (x) | |
47 | -msg_safe=msg.replace("[","@(").replace("]",")") | |
48 | -coccilib.org.print_todo(p[0], msg_safe) | |
49 | - | |
50 | -@script:python depends on report@ | |
51 | -p << r.p; | |
52 | -x << r.x; | |
53 | -@@ | |
54 | - | |
55 | -msg="WARNING: ERR_CAST can be used with %s" % (x) | |
56 | -coccilib.report.print_report(p[0], msg) |
scripts/coccinelle/free/kfree.cocci
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) |
scripts/coccinelle/iterators/fen.cocci
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); |
scripts/coccinelle/iterators/itnull.cocci
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 | + ...> } |
scripts/coccinelle/iterators/list_entry_update.cocci
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) |
scripts/coccinelle/locks/call_kern.cocci
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 |
scripts/coccinelle/locks/double_lock.cocci
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) |
scripts/coccinelle/locks/flags.cocci
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) |
scripts/coccinelle/locks/mini_lock.cocci
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) |
scripts/coccinelle/misc/doubleinit.cocci
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) |
scripts/coccinelle/misc/ifcol.cocci
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) |
scripts/coccinelle/null/deref_null.cocci
1 | +/// | |
2 | +/// A variable is dereference under a NULL test. | |
3 | +/// Even though it is know to be NULL. | |
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: -I ... -all_includes can give more complete results | |
11 | +// Options: | |
12 | + | |
13 | +virtual context | |
14 | +virtual patch | |
15 | +virtual org | |
16 | +virtual report | |
17 | + | |
18 | +@initialize:python depends on !context && patch && !org && !report@ | |
19 | + | |
20 | +import sys | |
21 | +print >> sys.stderr, "This semantic patch does not support the 'patch' mode." | |
22 | + | |
23 | +@depends on patch@ | |
24 | +@@ | |
25 | + | |
26 | +this_rule_should_never_matches(); | |
27 | + | |
28 | +@ifm depends on !patch@ | |
29 | +expression *E; | |
30 | +statement S1,S2; | |
31 | +position p1; | |
32 | +@@ | |
33 | + | |
34 | +if@p1 ((E == NULL && ...) || ...) S1 else S2 | |
35 | + | |
36 | +// The following two rules are separate, because both can match a single | |
37 | +// expression in different ways | |
38 | +@pr1 depends on !patch expression@ | |
39 | +expression *ifm.E; | |
40 | +identifier f; | |
41 | +position p1; | |
42 | +@@ | |
43 | + | |
44 | + (E != NULL && ...) ? <+...E->f@p1...+> : ... | |
45 | + | |
46 | +@pr2 depends on !patch expression@ | |
47 | +expression *ifm.E; | |
48 | +identifier f; | |
49 | +position p2; | |
50 | +@@ | |
51 | + | |
52 | +( | |
53 | + (E != NULL) && ... && <+...E->f@p2...+> | |
54 | +| | |
55 | + (E == NULL) || ... || <+...E->f@p2...+> | |
56 | +| | |
57 | + sizeof(<+...E->f@p2...+>) | |
58 | +) | |
59 | + | |
60 | +// For org and report modes | |
61 | + | |
62 | +@r depends on !context && !patch && (org || report) exists@ | |
63 | +expression subE <= ifm.E; | |
64 | +expression *ifm.E; | |
65 | +expression E1,E2; | |
66 | +identifier f; | |
67 | +statement S1,S2,S3,S4; | |
68 | +iterator iter; | |
69 | +position p!={pr1.p1,pr2.p2}; | |
70 | +position ifm.p1; | |
71 | +@@ | |
72 | + | |
73 | +if@p1 ((E == NULL && ...) || ...) | |
74 | +{ | |
75 | + ... when != if (...) S1 else S2 | |
76 | +( | |
77 | + iter(subE,...) S4 // no use | |
78 | +| | |
79 | + list_remove_head(E2,subE,...) | |
80 | +| | |
81 | + subE = E1 | |
82 | +| | |
83 | + for(subE = E1;...;...) S4 | |
84 | +| | |
85 | + subE++ | |
86 | +| | |
87 | + ++subE | |
88 | +| | |
89 | + --subE | |
90 | +| | |
91 | + subE-- | |
92 | +| | |
93 | + &subE | |
94 | +| | |
95 | + E->f@p // bad use | |
96 | +) | |
97 | + ... when any | |
98 | + return ...; | |
99 | +} | |
100 | +else S3 | |
101 | + | |
102 | +@script:python depends on !context && !patch && !org && report@ | |
103 | +p << r.p; | |
104 | +p1 << ifm.p1; | |
105 | +x << ifm.E; | |
106 | +@@ | |
107 | + | |
108 | +msg="ERROR: %s is NULL but dereferenced." % (x) | |
109 | +coccilib.report.print_report(p[0], msg) | |
110 | +cocci.include_match(False) | |
111 | + | |
112 | +@script:python depends on !context && !patch && org && !report@ | |
113 | +p << r.p; | |
114 | +p1 << ifm.p1; | |
115 | +x << ifm.E; | |
116 | +@@ | |
117 | + | |
118 | +msg="ERROR: %s is NULL but dereferenced." % (x) | |
119 | +msg_safe=msg.replace("[","@(").replace("]",")") | |
120 | +cocci.print_main(msg_safe,p) | |
121 | +cocci.include_match(False) | |
122 | + | |
123 | +@s depends on !context && !patch && (org || report) exists@ | |
124 | +expression subE <= ifm.E; | |
125 | +expression *ifm.E; | |
126 | +expression E1,E2; | |
127 | +identifier f; | |
128 | +statement S1,S2,S3,S4; | |
129 | +iterator iter; | |
130 | +position p!={pr1.p1,pr2.p2}; | |
131 | +position ifm.p1; | |
132 | +@@ | |
133 | + | |
134 | +if@p1 ((E == NULL && ...) || ...) | |
135 | +{ | |
136 | + ... when != if (...) S1 else S2 | |
137 | +( | |
138 | + iter(subE,...) S4 // no use | |
139 | +| | |
140 | + list_remove_head(E2,subE,...) | |
141 | +| | |
142 | + subE = E1 | |
143 | +| | |
144 | + for(subE = E1;...;...) S4 | |
145 | +| | |
146 | + subE++ | |
147 | +| | |
148 | + ++subE | |
149 | +| | |
150 | + --subE | |
151 | +| | |
152 | + subE-- | |
153 | +| | |
154 | + &subE | |
155 | +| | |
156 | + E->f@p // bad use | |
157 | +) | |
158 | + ... when any | |
159 | +} | |
160 | +else S3 | |
161 | + | |
162 | +@script:python depends on !context && !patch && !org && report@ | |
163 | +p << s.p; | |
164 | +p1 << ifm.p1; | |
165 | +x << ifm.E; | |
166 | +@@ | |
167 | + | |
168 | +msg="ERROR: %s is NULL but dereferenced." % (x) | |
169 | +coccilib.report.print_report(p[0], msg) | |
170 | + | |
171 | +@script:python depends on !context && !patch && org && !report@ | |
172 | +p << s.p; | |
173 | +p1 << ifm.p1; | |
174 | +x << ifm.E; | |
175 | +@@ | |
176 | + | |
177 | +msg="ERROR: %s is NULL but dereferenced." % (x) | |
178 | +msg_safe=msg.replace("[","@(").replace("]",")") | |
179 | +cocci.print_main(msg_safe,p) | |
180 | + | |
181 | +// For context mode | |
182 | + | |
183 | +@depends on context && !patch && !org && !report exists@ | |
184 | +expression subE <= ifm.E; | |
185 | +expression *ifm.E; | |
186 | +expression E1,E2; | |
187 | +identifier f; | |
188 | +statement S1,S2,S3,S4; | |
189 | +iterator iter; | |
190 | +position p!={pr1.p1,pr2.p2}; | |
191 | +position ifm.p1; | |
192 | +@@ | |
193 | + | |
194 | +if@p1 ((E == NULL && ...) || ...) | |
195 | +{ | |
196 | + ... when != if (...) S1 else S2 | |
197 | +( | |
198 | + iter(subE,...) S4 // no use | |
199 | +| | |
200 | + list_remove_head(E2,subE,...) | |
201 | +| | |
202 | + subE = E1 | |
203 | +| | |
204 | + for(subE = E1;...;...) S4 | |
205 | +| | |
206 | + subE++ | |
207 | +| | |
208 | + ++subE | |
209 | +| | |
210 | + --subE | |
211 | +| | |
212 | + subE-- | |
213 | +| | |
214 | + &subE | |
215 | +| | |
216 | +* E->f@p // bad use | |
217 | +) | |
218 | + ... when any | |
219 | + return ...; | |
220 | +} | |
221 | +else S3 | |
222 | + | |
223 | +// The following three rules are duplicates of ifm, pr1 and pr2 respectively. | |
224 | +// It is need because the previous rule as already made a "change". | |
225 | + | |
226 | +@ifm1 depends on !patch@ | |
227 | +expression *E; | |
228 | +statement S1,S2; | |
229 | +position p1; | |
230 | +@@ | |
231 | + | |
232 | +if@p1 ((E == NULL && ...) || ...) S1 else S2 | |
233 | + | |
234 | +@pr11 depends on !patch expression@ | |
235 | +expression *ifm1.E; | |
236 | +identifier f; | |
237 | +position p1; | |
238 | +@@ | |
239 | + | |
240 | + (E != NULL && ...) ? <+...E->f@p1...+> : ... | |
241 | + | |
242 | +@pr12 depends on !patch expression@ | |
243 | +expression *ifm1.E; | |
244 | +identifier f; | |
245 | +position p2; | |
246 | +@@ | |
247 | + | |
248 | +( | |
249 | + (E != NULL) && ... && <+...E->f@p2...+> | |
250 | +| | |
251 | + (E == NULL) || ... || <+...E->f@p2...+> | |
252 | +| | |
253 | + sizeof(<+...E->f@p2...+>) | |
254 | +) | |
255 | + | |
256 | +@depends on context && !patch && !org && !report exists@ | |
257 | +expression subE <= ifm1.E; | |
258 | +expression *ifm1.E; | |
259 | +expression E1,E2; | |
260 | +identifier f; | |
261 | +statement S1,S2,S3,S4; | |
262 | +iterator iter; | |
263 | +position p!={pr11.p1,pr12.p2}; | |
264 | +position ifm1.p1; | |
265 | +@@ | |
266 | + | |
267 | +if@p1 ((E == NULL && ...) || ...) | |
268 | +{ | |
269 | + ... when != if (...) S1 else S2 | |
270 | +( | |
271 | + iter(subE,...) S4 // no use | |
272 | +| | |
273 | + list_remove_head(E2,subE,...) | |
274 | +| | |
275 | + subE = E1 | |
276 | +| | |
277 | + for(subE = E1;...;...) S4 | |
278 | +| | |
279 | + subE++ | |
280 | +| | |
281 | + ++subE | |
282 | +| | |
283 | + --subE | |
284 | +| | |
285 | + subE-- | |
286 | +| | |
287 | + &subE | |
288 | +| | |
289 | +* E->f@p // bad use | |
290 | +) | |
291 | + ... when any | |
292 | +} | |
293 | +else S3 |
scripts/coccinelle/null/eno.cocci
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 |
scripts/coccinelle/null/kmerr.cocci
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) |
scripts/coccinelle/resource_size.cocci
1 | -/// | |
2 | -/// Use resource_size function on resource object | |
3 | -/// instead of explicit computation. | |
4 | -/// | |
5 | -// Confidence: High | |
6 | -// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2. | |
7 | -// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2. | |
8 | -// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2. | |
9 | -// URL: http://coccinelle.lip6.fr/ | |
10 | -// Options: | |
11 | -// | |
12 | -// Keywords: resource_size | |
13 | -// Version min: 2.6.27 resource_size | |
14 | -// | |
15 | - | |
16 | -virtual context | |
17 | -virtual patch | |
18 | -virtual org | |
19 | -virtual report | |
20 | - | |
21 | -//---------------------------------------------------------- | |
22 | -// For context mode | |
23 | -//---------------------------------------------------------- | |
24 | - | |
25 | -@r_context depends on context && !patch && !org@ | |
26 | -struct resource *res; | |
27 | -@@ | |
28 | - | |
29 | -* (res->end - res->start) + 1 | |
30 | - | |
31 | -//---------------------------------------------------------- | |
32 | -// For patch mode | |
33 | -//---------------------------------------------------------- | |
34 | - | |
35 | -@r_patch depends on !context && patch && !org@ | |
36 | -struct resource *res; | |
37 | -@@ | |
38 | - | |
39 | -- (res->end - res->start) + 1 | |
40 | -+ resource_size(res) | |
41 | - | |
42 | -//---------------------------------------------------------- | |
43 | -// For org mode | |
44 | -//---------------------------------------------------------- | |
45 | - | |
46 | - | |
47 | -@r_org depends on !context && !patch && (org || report)@ | |
48 | -struct resource *res; | |
49 | -position p; | |
50 | -@@ | |
51 | - | |
52 | - (res->end@p - res->start) + 1 | |
53 | - | |
54 | -@rbad_org depends on !context && !patch && (org || report)@ | |
55 | -struct resource *res; | |
56 | -position p != r_org.p; | |
57 | -@@ | |
58 | - | |
59 | - res->end@p - res->start | |
60 | - | |
61 | -@script:python depends on org@ | |
62 | -p << r_org.p; | |
63 | -x << r_org.res; | |
64 | -@@ | |
65 | - | |
66 | -msg="ERROR with %s" % (x) | |
67 | -msg_safe=msg.replace("[","@(").replace("]",")") | |
68 | -coccilib.org.print_todo(p[0], msg_safe) | |
69 | - | |
70 | -@script:python depends on report@ | |
71 | -p << r_org.p; | |
72 | -x << r_org.res; | |
73 | -@@ | |
74 | - | |
75 | -msg="ERROR: Missing resource_size with %s" % (x) | |
76 | -coccilib.report.print_report(p[0], msg) | |
77 | - | |
78 | -@script:python depends on org@ | |
79 | -p << rbad_org.p; | |
80 | -x << rbad_org.res; | |
81 | -@@ | |
82 | - | |
83 | -msg="WARNING with %s" % (x) | |
84 | -msg_safe=msg.replace("[","@(").replace("]",")") | |
85 | -coccilib.org.print_todo(p[0], msg_safe) | |
86 | - | |
87 | -@script:python depends on report@ | |
88 | -p << rbad_org.p; | |
89 | -x << rbad_org.res; | |
90 | -@@ | |
91 | - | |
92 | -msg="WARNING: Suspicious code. resource_size is maybe missing with %s" % (x) | |
93 | -coccilib.report.print_report(p[0], msg) |
scripts/coccinelle/tests/doublebitand.cocci
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 |") |
scripts/coccinelle/tests/doubletest.cocci
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 ||") |
scripts/extract-ikconfig
... | ... | @@ -7,12 +7,10 @@ |
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 | |
19 | 17 | |
... | ... | @@ -21,11 +19,25 @@ |
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 |
32 | 44 | |
... | ... | @@ -35,18 +47,19 @@ |
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 |
scripts/namespace.pl
... | ... | @@ -84,6 +84,64 @@ |
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 @@ |
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 @@ |
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, $_); |
154 | 214 | |
... | ... | @@ -167,11 +227,11 @@ |
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 @@ |
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 |
220 | 281 | |
... | ... | @@ -222,8 +283,9 @@ |
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 @@ |
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 @@ |
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 | } |
297 | 341 | |
... | ... | @@ -319,19 +363,15 @@ |
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; | |
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 | + } | |
327 | 374 | } |
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; | |
334 | - } | |
335 | 375 | |
336 | 376 | printf "$name is multiply defined in :-\n"; |
337 | 377 | foreach my $module (@{$def{$name}}) { |
... | ... | @@ -372,31 +412,7 @@ |
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 @@ |
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/ |