diff options
Diffstat (limited to 'scripts')
26 files changed, 1196 insertions, 92 deletions
diff --git a/scripts/basic/docproc.c b/scripts/basic/docproc.c index fc3b18d844af..98dec87974d0 100644 --- a/scripts/basic/docproc.c +++ b/scripts/basic/docproc.c | |||
| @@ -333,7 +333,10 @@ static void docsect(char *filename, char *line) | |||
| 333 | if (*s == '\n') | 333 | if (*s == '\n') |
| 334 | *s = '\0'; | 334 | *s = '\0'; |
| 335 | 335 | ||
| 336 | asprintf(&s, "DOC: %s", line); | 336 | if (asprintf(&s, "DOC: %s", line) < 0) { |
| 337 | perror("asprintf"); | ||
| 338 | exit(1); | ||
| 339 | } | ||
| 337 | consume_symbol(s); | 340 | consume_symbol(s); |
| 338 | free(s); | 341 | free(s); |
| 339 | 342 | ||
diff --git a/scripts/coccicheck b/scripts/coccicheck index b8bcf1f7bed7..1bb1a1bd2daa 100755 --- a/scripts/coccicheck +++ b/scripts/coccicheck | |||
| @@ -16,6 +16,7 @@ if [ "$C" = "1" -o "$C" = "2" ]; then | |||
| 16 | else | 16 | else |
| 17 | ONLINE=0 | 17 | ONLINE=0 |
| 18 | FLAGS="-very_quiet" | 18 | FLAGS="-very_quiet" |
| 19 | OPTIONS="-dir $srctree" | ||
| 19 | fi | 20 | fi |
| 20 | 21 | ||
| 21 | if [ ! -x "$SPATCH" ]; then | 22 | if [ ! -x "$SPATCH" ]; then |
| @@ -25,11 +26,13 @@ fi | |||
| 25 | 26 | ||
| 26 | if [ "$MODE" = "" ] ; then | 27 | if [ "$MODE" = "" ] ; then |
| 27 | if [ "$ONLINE" = "0" ] ; then | 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 | echo 'You can specify the mode with "make coccicheck MODE=<mode>"' | 31 | echo 'You can specify the mode with "make coccicheck MODE=<mode>"' |
| 30 | echo 'Available modes are: report, patch, context, org' | ||
| 31 | fi | 32 | fi |
| 32 | MODE="report" | 33 | MODE="chain" |
| 34 | elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then | ||
| 35 | FLAGS="$FLAGS -no_show_diff" | ||
| 33 | fi | 36 | fi |
| 34 | 37 | ||
| 35 | if [ "$ONLINE" = "0" ] ; then | 38 | if [ "$ONLINE" = "0" ] ; then |
| @@ -44,7 +47,7 @@ coccinelle () { | |||
| 44 | 47 | ||
| 45 | OPT=`grep "Option" $COCCI | cut -d':' -f2` | 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 | # $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null | 52 | # $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null |
| 50 | 53 | ||
| @@ -52,21 +55,44 @@ coccinelle () { | |||
| 52 | 55 | ||
| 53 | FILE=`echo $COCCI | sed "s|$srctree/||"` | 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 | echo 'Message example to submit a patch:' | 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 | echo " in $FILE." | 76 | echo " in $FILE." |
| 62 | echo '' | 77 | echo '' |
| 63 | echo ' More information about semantic patching is available at' | 78 | echo ' More information about semantic patching is available at' |
| 64 | echo ' http://coccinelle.lip6.fr/' | 79 | echo ' http://coccinelle.lip6.fr/' |
| 65 | echo '' | 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 | else | 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 | fi | 96 | fi |
| 71 | 97 | ||
| 72 | } | 98 | } |
diff --git a/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci b/scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci index 7d4771d449c3..7d4771d449c3 100644 --- a/scripts/coccinelle/alloc/drop_kmalloc_cast.cocci +++ b/scripts/coccinelle/api/alloc/drop_kmalloc_cast.cocci | |||
diff --git a/scripts/coccinelle/alloc/kzalloc-simple.cocci b/scripts/coccinelle/api/alloc/kzalloc-simple.cocci index 2eae828fc657..046b9b16f8f9 100644 --- a/scripts/coccinelle/alloc/kzalloc-simple.cocci +++ b/scripts/coccinelle/api/alloc/kzalloc-simple.cocci | |||
| @@ -1,5 +1,9 @@ | |||
| 1 | /// | 1 | /// |
| 2 | /// kzalloc should be used rather than kmalloc followed by memset 0 | 2 | /// Use kzalloc rather than kmalloc followed by memset with 0 |
| 3 | /// | ||
| 4 | /// This considers some simple cases that are common and easy to validate | ||
| 5 | /// Note in particular that there are no ...s in the rule, so all of the | ||
| 6 | /// matched code has to be contiguous | ||
| 3 | /// | 7 | /// |
| 4 | // Confidence: High | 8 | // Confidence: High |
| 5 | // Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2. | 9 | // Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2. |
diff --git a/scripts/coccinelle/err_cast.cocci b/scripts/coccinelle/api/err_cast.cocci index 2ce115000af6..2ce115000af6 100644 --- a/scripts/coccinelle/err_cast.cocci +++ b/scripts/coccinelle/api/err_cast.cocci | |||
diff --git a/scripts/coccinelle/api/kstrdup.cocci b/scripts/coccinelle/api/kstrdup.cocci new file mode 100644 index 000000000000..e0805ad08d39 --- /dev/null +++ b/scripts/coccinelle/api/kstrdup.cocci | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | /// Use kstrdup rather than duplicating its implementation | ||
| 2 | /// | ||
| 3 | // Confidence: High | ||
| 4 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 5 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 6 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 7 | // URL: http://coccinelle.lip6.fr/ | ||
| 8 | // Comments: | ||
| 9 | // Options: -no_includes -include_headers | ||
| 10 | |||
| 11 | virtual patch | ||
| 12 | |||
| 13 | @@ | ||
| 14 | expression from,to; | ||
| 15 | expression flag,E1,E2; | ||
| 16 | statement S; | ||
| 17 | @@ | ||
| 18 | |||
| 19 | - to = kmalloc(strlen(from) + 1,flag); | ||
| 20 | + to = kstrdup(from, flag); | ||
| 21 | ... when != \(from = E1 \| to = E1 \) | ||
| 22 | if (to==NULL || ...) S | ||
| 23 | ... when != \(from = E2 \| to = E2 \) | ||
| 24 | - strcpy(to, from); | ||
| 25 | |||
| 26 | @@ | ||
| 27 | expression x,from,to; | ||
| 28 | expression flag,E1,E2,E3; | ||
| 29 | statement S; | ||
| 30 | @@ | ||
| 31 | |||
| 32 | - x = strlen(from) + 1; | ||
| 33 | ... when != \( x = E1 \| from = E1 \) | ||
| 34 | - to = \(kmalloc\|kzalloc\)(x,flag); | ||
| 35 | + to = kstrdup(from, flag); | ||
| 36 | ... when != \(x = E2 \| from = E2 \| to = E2 \) | ||
| 37 | if (to==NULL || ...) S | ||
| 38 | ... when != \(x = E3 \| from = E3 \| to = E3 \) | ||
| 39 | - memcpy(to, from, x); | ||
diff --git a/scripts/coccinelle/api/memdup.cocci b/scripts/coccinelle/api/memdup.cocci new file mode 100644 index 000000000000..b5d722077dc1 --- /dev/null +++ b/scripts/coccinelle/api/memdup.cocci | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | /// Use kmemdup rather than duplicating its implementation | ||
| 2 | /// | ||
| 3 | // Confidence: High | ||
| 4 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 5 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 6 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 7 | // URL: http://coccinelle.lip6.fr/ | ||
| 8 | // Comments: | ||
| 9 | // Options: -no_includes -include_headers | ||
| 10 | |||
| 11 | virtual patch | ||
| 12 | |||
| 13 | @r1@ | ||
| 14 | expression from,to; | ||
| 15 | expression flag; | ||
| 16 | position p; | ||
| 17 | @@ | ||
| 18 | |||
| 19 | to = \(kmalloc@p\|kzalloc@p\)(strlen(from) + 1,flag); | ||
| 20 | |||
| 21 | @r2@ | ||
| 22 | expression x,from,to; | ||
| 23 | expression flag,E1; | ||
| 24 | position p; | ||
| 25 | @@ | ||
| 26 | |||
| 27 | x = strlen(from) + 1; | ||
| 28 | ... when != \( x = E1 \| from = E1 \) | ||
| 29 | to = \(kmalloc@p\|kzalloc@p\)(x,flag); | ||
| 30 | |||
| 31 | @@ | ||
| 32 | expression from,to,size,flag; | ||
| 33 | position p != {r1.p,r2.p}; | ||
| 34 | statement S; | ||
| 35 | @@ | ||
| 36 | |||
| 37 | - to = \(kmalloc@p\|kzalloc@p\)(size,flag); | ||
| 38 | + to = kmemdup(from,size,flag); | ||
| 39 | if (to==NULL || ...) S | ||
| 40 | - memcpy(to, from, size); | ||
diff --git a/scripts/coccinelle/api/memdup_user.cocci b/scripts/coccinelle/api/memdup_user.cocci new file mode 100644 index 000000000000..72ce012e878a --- /dev/null +++ b/scripts/coccinelle/api/memdup_user.cocci | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | /// Use kmemdup_user rather than duplicating its implementation | ||
| 2 | /// This is a little bit restricted to reduce false positives | ||
| 3 | /// | ||
| 4 | // Confidence: High | ||
| 5 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 6 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 7 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 8 | // URL: http://coccinelle.lip6.fr/ | ||
| 9 | // Comments: | ||
| 10 | // Options: -no_includes -include_headers | ||
| 11 | |||
| 12 | virtual patch | ||
| 13 | |||
| 14 | @@ | ||
| 15 | expression from,to,size,flag; | ||
| 16 | position p; | ||
| 17 | identifier l1,l2; | ||
| 18 | @@ | ||
| 19 | |||
| 20 | - to = \(kmalloc@p\|kzalloc@p\)(size,flag); | ||
| 21 | + to = memdup_user(from,size); | ||
| 22 | if ( | ||
| 23 | - to==NULL | ||
| 24 | + IS_ERR(to) | ||
| 25 | || ...) { | ||
| 26 | <+... when != goto l1; | ||
| 27 | - -ENOMEM | ||
| 28 | + PTR_ERR(to) | ||
| 29 | ...+> | ||
| 30 | } | ||
| 31 | - if (copy_from_user(to, from, size) != 0) { | ||
| 32 | - <+... when != goto l2; | ||
| 33 | - -EFAULT | ||
| 34 | - ...+> | ||
| 35 | - } | ||
diff --git a/scripts/coccinelle/resource_size.cocci b/scripts/coccinelle/api/resource_size.cocci index 1935a58b39d9..1935a58b39d9 100644 --- a/scripts/coccinelle/resource_size.cocci +++ b/scripts/coccinelle/api/resource_size.cocci | |||
diff --git a/scripts/coccinelle/free/kfree.cocci b/scripts/coccinelle/free/kfree.cocci new file mode 100644 index 000000000000..f9f79d9245ee --- /dev/null +++ b/scripts/coccinelle/free/kfree.cocci | |||
| @@ -0,0 +1,117 @@ | |||
| 1 | /// Find a use after free. | ||
| 2 | //# Values of variables may imply that some | ||
| 3 | //# execution paths are not possible, resulting in false positives. | ||
| 4 | //# Another source of false positives are macros such as | ||
| 5 | //# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument | ||
| 6 | /// | ||
| 7 | // Confidence: Moderate | ||
| 8 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 9 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 10 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 11 | // URL: http://coccinelle.lip6.fr/ | ||
| 12 | // Comments: | ||
| 13 | // Options: -no_includes -include_headers | ||
| 14 | |||
| 15 | virtual org | ||
| 16 | virtual report | ||
| 17 | |||
| 18 | @free@ | ||
| 19 | expression E; | ||
| 20 | position p1; | ||
| 21 | @@ | ||
| 22 | |||
| 23 | kfree@p1(E) | ||
| 24 | |||
| 25 | @print expression@ | ||
| 26 | constant char *c; | ||
| 27 | expression free.E,E2; | ||
| 28 | type T; | ||
| 29 | position p; | ||
| 30 | identifier f; | ||
| 31 | @@ | ||
| 32 | |||
| 33 | ( | ||
| 34 | f(...,c,...,(T)E@p,...) | ||
| 35 | | | ||
| 36 | E@p == E2 | ||
| 37 | | | ||
| 38 | E@p != E2 | ||
| 39 | | | ||
| 40 | !E@p | ||
| 41 | | | ||
| 42 | E@p || ... | ||
| 43 | ) | ||
| 44 | |||
| 45 | @sz@ | ||
| 46 | expression free.E; | ||
| 47 | position p; | ||
| 48 | @@ | ||
| 49 | |||
| 50 | sizeof(<+...E@p...+>) | ||
| 51 | |||
| 52 | @loop exists@ | ||
| 53 | expression E; | ||
| 54 | identifier l; | ||
| 55 | position ok; | ||
| 56 | @@ | ||
| 57 | |||
| 58 | while (1) { ... | ||
| 59 | kfree@ok(E) | ||
| 60 | ... when != break; | ||
| 61 | when != goto l; | ||
| 62 | when forall | ||
| 63 | } | ||
| 64 | |||
| 65 | @r exists@ | ||
| 66 | expression free.E, subE<=free.E, E2; | ||
| 67 | expression E1; | ||
| 68 | iterator iter; | ||
| 69 | statement S; | ||
| 70 | position free.p1!=loop.ok,p2!={print.p,sz.p}; | ||
| 71 | @@ | ||
| 72 | |||
| 73 | kfree@p1(E,...) | ||
| 74 | ... | ||
| 75 | ( | ||
| 76 | iter(...,subE,...) S // no use | ||
| 77 | | | ||
| 78 | list_remove_head(E1,subE,...) | ||
| 79 | | | ||
| 80 | subE = E2 | ||
| 81 | | | ||
| 82 | subE++ | ||
| 83 | | | ||
| 84 | ++subE | ||
| 85 | | | ||
| 86 | --subE | ||
| 87 | | | ||
| 88 | subE-- | ||
| 89 | | | ||
| 90 | &subE | ||
| 91 | | | ||
| 92 | BUG(...) | ||
| 93 | | | ||
| 94 | BUG_ON(...) | ||
| 95 | | | ||
| 96 | return_VALUE(...) | ||
| 97 | | | ||
| 98 | return_ACPI_STATUS(...) | ||
| 99 | | | ||
| 100 | E@p2 // bad use | ||
| 101 | ) | ||
| 102 | |||
| 103 | @script:python depends on org@ | ||
| 104 | p1 << free.p1; | ||
| 105 | p2 << r.p2; | ||
| 106 | @@ | ||
| 107 | |||
| 108 | cocci.print_main("kfree",p1) | ||
| 109 | cocci.print_secs("ref",p2) | ||
| 110 | |||
| 111 | @script:python depends on report@ | ||
| 112 | p1 << free.p1; | ||
| 113 | p2 << r.p2; | ||
| 114 | @@ | ||
| 115 | |||
| 116 | msg = "reference preceded by free on line %s" % (p1[0].line) | ||
| 117 | coccilib.report.print_report(p2[0],msg) | ||
diff --git a/scripts/coccinelle/iterators/fen.cocci b/scripts/coccinelle/iterators/fen.cocci new file mode 100644 index 000000000000..77bc108c3f59 --- /dev/null +++ b/scripts/coccinelle/iterators/fen.cocci | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | /// These iterators only exit normally when the loop cursor is NULL, so there | ||
| 2 | /// is no point to call of_node_put on the final value. | ||
| 3 | /// | ||
| 4 | // Confidence: High | ||
| 5 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 6 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 7 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 8 | // URL: http://coccinelle.lip6.fr/ | ||
| 9 | // Comments: | ||
| 10 | // Options: -no_includes -include_headers | ||
| 11 | |||
| 12 | virtual patch | ||
| 13 | |||
| 14 | @@ | ||
| 15 | iterator name for_each_node_by_name; | ||
| 16 | expression np,E; | ||
| 17 | identifier l; | ||
| 18 | @@ | ||
| 19 | |||
| 20 | for_each_node_by_name(np,...) { | ||
| 21 | ... when != break; | ||
| 22 | when != goto l; | ||
| 23 | } | ||
| 24 | ... when != np = E | ||
| 25 | - of_node_put(np); | ||
| 26 | |||
| 27 | @@ | ||
| 28 | iterator name for_each_node_by_type; | ||
| 29 | expression np,E; | ||
| 30 | identifier l; | ||
| 31 | @@ | ||
| 32 | |||
| 33 | for_each_node_by_type(np,...) { | ||
| 34 | ... when != break; | ||
| 35 | when != goto l; | ||
| 36 | } | ||
| 37 | ... when != np = E | ||
| 38 | - of_node_put(np); | ||
| 39 | |||
| 40 | @@ | ||
| 41 | iterator name for_each_compatible_node; | ||
| 42 | expression np,E; | ||
| 43 | identifier l; | ||
| 44 | @@ | ||
| 45 | |||
| 46 | for_each_compatible_node(np,...) { | ||
| 47 | ... when != break; | ||
| 48 | when != goto l; | ||
| 49 | } | ||
| 50 | ... when != np = E | ||
| 51 | - of_node_put(np); | ||
| 52 | |||
| 53 | @@ | ||
| 54 | iterator name for_each_matching_node; | ||
| 55 | expression np,E; | ||
| 56 | identifier l; | ||
| 57 | @@ | ||
| 58 | |||
| 59 | for_each_matching_node(np,...) { | ||
| 60 | ... when != break; | ||
| 61 | when != goto l; | ||
| 62 | } | ||
| 63 | ... when != np = E | ||
| 64 | - of_node_put(np); | ||
diff --git a/scripts/coccinelle/iterators/itnull.cocci b/scripts/coccinelle/iterators/itnull.cocci new file mode 100644 index 000000000000..baa4297a4ed1 --- /dev/null +++ b/scripts/coccinelle/iterators/itnull.cocci | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | /// Many iterators have the property that the first argument is always bound | ||
| 2 | /// to a real list element, never NULL. False positives arise for some | ||
| 3 | /// iterators that do not have this property, or in cases when the loop | ||
| 4 | /// cursor is reassigned. The latter should only happen when the matched | ||
| 5 | /// code is on the way to a loop exit (break, goto, or return). | ||
| 6 | /// | ||
| 7 | // Confidence: Moderate | ||
| 8 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 9 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 10 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 11 | // URL: http://coccinelle.lip6.fr/ | ||
| 12 | // Comments: | ||
| 13 | // Options: -no_includes -include_headers | ||
| 14 | |||
| 15 | virtual patch | ||
| 16 | |||
| 17 | @@ | ||
| 18 | iterator I; | ||
| 19 | expression x,E,E1,E2; | ||
| 20 | statement S,S1,S2; | ||
| 21 | @@ | ||
| 22 | |||
| 23 | I(x,...) { <... | ||
| 24 | ( | ||
| 25 | - if (x == NULL && ...) S | ||
| 26 | | | ||
| 27 | - if (x != NULL || ...) | ||
| 28 | S | ||
| 29 | | | ||
| 30 | - (x == NULL) || | ||
| 31 | E | ||
| 32 | | | ||
| 33 | - (x != NULL) && | ||
| 34 | E | ||
| 35 | | | ||
| 36 | - (x == NULL && ...) ? E1 : | ||
| 37 | E2 | ||
| 38 | | | ||
| 39 | - (x != NULL || ...) ? | ||
| 40 | E1 | ||
| 41 | - : E2 | ||
| 42 | | | ||
| 43 | - if (x == NULL && ...) S1 else | ||
| 44 | S2 | ||
| 45 | | | ||
| 46 | - if (x != NULL || ...) | ||
| 47 | S1 | ||
| 48 | - else S2 | ||
| 49 | | | ||
| 50 | + BAD( | ||
| 51 | x == NULL | ||
| 52 | + ) | ||
| 53 | | | ||
| 54 | + BAD( | ||
| 55 | x != NULL | ||
| 56 | + ) | ||
| 57 | ) | ||
| 58 | ...> } \ No newline at end of file | ||
diff --git a/scripts/coccinelle/iterators/list_entry_update.cocci b/scripts/coccinelle/iterators/list_entry_update.cocci new file mode 100644 index 000000000000..b2967475679b --- /dev/null +++ b/scripts/coccinelle/iterators/list_entry_update.cocci | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | /// list_for_each_entry uses its first argument to get from one element of | ||
| 2 | /// the list to the next, so it is usually not a good idea to reassign it. | ||
| 3 | /// The first rule finds such a reassignment and the second rule checks | ||
| 4 | /// that there is a path from the reassignment back to the top of the loop. | ||
| 5 | /// | ||
| 6 | // Confidence: High | ||
| 7 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 8 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 9 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 10 | // URL: http://coccinelle.lip6.fr/ | ||
| 11 | // Comments: | ||
| 12 | // Options: -no_includes -include_headers | ||
| 13 | |||
| 14 | virtual context | ||
| 15 | virtual org | ||
| 16 | virtual report | ||
| 17 | |||
| 18 | @r@ | ||
| 19 | iterator name list_for_each_entry; | ||
| 20 | expression x,E; | ||
| 21 | position p1,p2; | ||
| 22 | @@ | ||
| 23 | |||
| 24 | list_for_each_entry@p1(x,...) { <... x =@p2 E ...> } | ||
| 25 | |||
| 26 | @depends on context && !org && !report@ | ||
| 27 | expression x,E; | ||
| 28 | position r.p1,r.p2; | ||
| 29 | statement S; | ||
| 30 | @@ | ||
| 31 | |||
| 32 | *x =@p2 E | ||
| 33 | ... | ||
| 34 | list_for_each_entry@p1(x,...) S | ||
| 35 | |||
| 36 | // ------------------------------------------------------------------------ | ||
| 37 | |||
| 38 | @back depends on (org || report) && !context exists@ | ||
| 39 | expression x,E; | ||
| 40 | position r.p1,r.p2; | ||
| 41 | statement S; | ||
| 42 | @@ | ||
| 43 | |||
| 44 | x =@p2 E | ||
| 45 | ... | ||
| 46 | list_for_each_entry@p1(x,...) S | ||
| 47 | |||
| 48 | @script:python depends on back && org@ | ||
| 49 | p1 << r.p1; | ||
| 50 | p2 << r.p2; | ||
| 51 | @@ | ||
| 52 | |||
| 53 | cocci.print_main("iterator",p1) | ||
| 54 | cocci.print_secs("update",p2) | ||
| 55 | |||
| 56 | @script:python depends on back && report@ | ||
| 57 | p1 << r.p1; | ||
| 58 | p2 << r.p2; | ||
| 59 | @@ | ||
| 60 | |||
| 61 | msg = "iterator with update on line %s" % (p2[0].line) | ||
| 62 | coccilib.report.print_report(p1[0],msg) | ||
diff --git a/scripts/coccinelle/locks/call_kern.cocci b/scripts/coccinelle/locks/call_kern.cocci new file mode 100644 index 000000000000..00af5344a68f --- /dev/null +++ b/scripts/coccinelle/locks/call_kern.cocci | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | /// Find functions that refer to GFP_KERNEL but are called with locks held. | ||
| 2 | /// The proposed change of converting the GFP_KERNEL is not necessarily the | ||
| 3 | /// correct one. It may be desired to unlock the lock, or to not call the | ||
| 4 | /// function under the lock in the first place. | ||
| 5 | /// | ||
| 6 | // Confidence: Moderate | ||
| 7 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 8 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 9 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 10 | // URL: http://coccinelle.lip6.fr/ | ||
| 11 | // Comments: | ||
| 12 | // Options: -no_includes -include_headers | ||
| 13 | |||
| 14 | virtual patch | ||
| 15 | |||
| 16 | @gfp exists@ | ||
| 17 | identifier fn; | ||
| 18 | position p; | ||
| 19 | @@ | ||
| 20 | |||
| 21 | fn(...) { | ||
| 22 | ... when != read_unlock_irq(...) | ||
| 23 | when != write_unlock_irq(...) | ||
| 24 | when != read_unlock_irqrestore(...) | ||
| 25 | when != write_unlock_irqrestore(...) | ||
| 26 | when != spin_unlock(...) | ||
| 27 | when != spin_unlock_irq(...) | ||
| 28 | when != spin_unlock_irqrestore(...) | ||
| 29 | when != local_irq_enable(...) | ||
| 30 | when any | ||
| 31 | GFP_KERNEL@p | ||
| 32 | ... when any | ||
| 33 | } | ||
| 34 | |||
| 35 | @locked@ | ||
| 36 | identifier gfp.fn; | ||
| 37 | @@ | ||
| 38 | |||
| 39 | ( | ||
| 40 | read_lock_irq | ||
| 41 | | | ||
| 42 | write_lock_irq | ||
| 43 | | | ||
| 44 | read_lock_irqsave | ||
| 45 | | | ||
| 46 | write_lock_irqsave | ||
| 47 | | | ||
| 48 | spin_lock | ||
| 49 | | | ||
| 50 | spin_trylock | ||
| 51 | | | ||
| 52 | spin_lock_irq | ||
| 53 | | | ||
| 54 | spin_lock_irqsave | ||
| 55 | | | ||
| 56 | local_irq_disable | ||
| 57 | ) | ||
| 58 | (...) | ||
| 59 | ... when != read_unlock_irq(...) | ||
| 60 | when != write_unlock_irq(...) | ||
| 61 | when != read_unlock_irqrestore(...) | ||
| 62 | when != write_unlock_irqrestore(...) | ||
| 63 | when != spin_unlock(...) | ||
| 64 | when != spin_unlock_irq(...) | ||
| 65 | when != spin_unlock_irqrestore(...) | ||
| 66 | when != local_irq_enable(...) | ||
| 67 | fn(...) | ||
| 68 | |||
| 69 | @depends on locked@ | ||
| 70 | position gfp.p; | ||
| 71 | @@ | ||
| 72 | |||
| 73 | - GFP_KERNEL@p | ||
| 74 | + GFP_ATOMIC | ||
diff --git a/scripts/coccinelle/locks/double_lock.cocci b/scripts/coccinelle/locks/double_lock.cocci new file mode 100644 index 000000000000..63b24e682fad --- /dev/null +++ b/scripts/coccinelle/locks/double_lock.cocci | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | /// Find double locks. False positives may occur when some paths cannot | ||
| 2 | /// occur at execution, due to the values of variables, and when there is | ||
| 3 | /// an intervening function call that releases the lock. | ||
| 4 | /// | ||
| 5 | // Confidence: Moderate | ||
| 6 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 7 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 8 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 9 | // URL: http://coccinelle.lip6.fr/ | ||
| 10 | // Comments: | ||
| 11 | // Options: -no_includes -include_headers | ||
| 12 | |||
| 13 | virtual org | ||
| 14 | virtual report | ||
| 15 | |||
| 16 | @locked@ | ||
| 17 | position p1; | ||
| 18 | expression E1; | ||
| 19 | position p; | ||
| 20 | @@ | ||
| 21 | |||
| 22 | ( | ||
| 23 | mutex_lock@p1 | ||
| 24 | | | ||
| 25 | mutex_trylock@p1 | ||
| 26 | | | ||
| 27 | spin_lock@p1 | ||
| 28 | | | ||
| 29 | spin_trylock@p1 | ||
| 30 | | | ||
| 31 | read_lock@p1 | ||
| 32 | | | ||
| 33 | read_trylock@p1 | ||
| 34 | | | ||
| 35 | write_lock@p1 | ||
| 36 | | | ||
| 37 | write_trylock@p1 | ||
| 38 | ) (E1@p,...); | ||
| 39 | |||
| 40 | @balanced@ | ||
| 41 | position p1 != locked.p1; | ||
| 42 | position locked.p; | ||
| 43 | identifier lock,unlock; | ||
| 44 | expression x <= locked.E1; | ||
| 45 | expression E,locked.E1; | ||
| 46 | expression E2; | ||
| 47 | @@ | ||
| 48 | |||
| 49 | if (E) { | ||
| 50 | <+... when != E1 | ||
| 51 | lock(E1@p,...) | ||
| 52 | ...+> | ||
| 53 | } | ||
| 54 | ... when != E1 | ||
| 55 | when != \(x = E2\|&x\) | ||
| 56 | when forall | ||
| 57 | if (E) { | ||
| 58 | <+... when != E1 | ||
| 59 | unlock@p1(E1,...) | ||
| 60 | ...+> | ||
| 61 | } | ||
| 62 | |||
| 63 | @r depends on !balanced exists@ | ||
| 64 | expression x <= locked.E1; | ||
| 65 | expression locked.E1; | ||
| 66 | expression E2; | ||
| 67 | identifier lock; | ||
| 68 | position locked.p,p1,p2; | ||
| 69 | @@ | ||
| 70 | |||
| 71 | lock@p1 (E1@p,...); | ||
| 72 | ... when != E1 | ||
| 73 | when != \(x = E2\|&x\) | ||
| 74 | lock@p2 (E1,...); | ||
| 75 | |||
| 76 | @script:python depends on org@ | ||
| 77 | p1 << r.p1; | ||
| 78 | p2 << r.p2; | ||
| 79 | lock << r.lock; | ||
| 80 | @@ | ||
| 81 | |||
| 82 | cocci.print_main(lock,p1) | ||
| 83 | cocci.print_secs("second lock",p2) | ||
| 84 | |||
| 85 | @script:python depends on report@ | ||
| 86 | p1 << r.p1; | ||
| 87 | p2 << r.p2; | ||
| 88 | lock << r.lock; | ||
| 89 | @@ | ||
| 90 | |||
| 91 | msg = "second lock on line %s" % (p2[0].line) | ||
| 92 | coccilib.report.print_report(p1[0],msg) | ||
diff --git a/scripts/coccinelle/locks/flags.cocci b/scripts/coccinelle/locks/flags.cocci new file mode 100644 index 000000000000..b4344d838097 --- /dev/null +++ b/scripts/coccinelle/locks/flags.cocci | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | /// Find nested lock+irqsave functions that use the same flags variables | ||
| 2 | /// | ||
| 3 | // Confidence: High | ||
| 4 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 5 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 6 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 7 | // URL: http://coccinelle.lip6.fr/ | ||
| 8 | // Comments: | ||
| 9 | // Options: -no_includes -include_headers | ||
| 10 | |||
| 11 | virtual context | ||
| 12 | virtual org | ||
| 13 | virtual report | ||
| 14 | |||
| 15 | @r@ | ||
| 16 | expression lock1,lock2,flags; | ||
| 17 | position p1,p2; | ||
| 18 | @@ | ||
| 19 | |||
| 20 | ( | ||
| 21 | spin_lock_irqsave@p1(lock1,flags) | ||
| 22 | | | ||
| 23 | read_lock_irqsave@p1(lock1,flags) | ||
| 24 | | | ||
| 25 | write_lock_irqsave@p1(lock1,flags) | ||
| 26 | ) | ||
| 27 | ... when != flags | ||
| 28 | ( | ||
| 29 | spin_lock_irqsave(lock1,flags) | ||
| 30 | | | ||
| 31 | read_lock_irqsave(lock1,flags) | ||
| 32 | | | ||
| 33 | write_lock_irqsave(lock1,flags) | ||
| 34 | | | ||
| 35 | spin_lock_irqsave@p2(lock2,flags) | ||
| 36 | | | ||
| 37 | read_lock_irqsave@p2(lock2,flags) | ||
| 38 | | | ||
| 39 | write_lock_irqsave@p2(lock2,flags) | ||
| 40 | ) | ||
| 41 | |||
| 42 | @d@ | ||
| 43 | expression f <= r.flags; | ||
| 44 | expression lock1,lock2,flags; | ||
| 45 | position r.p1, r.p2; | ||
| 46 | @@ | ||
| 47 | |||
| 48 | ( | ||
| 49 | *spin_lock_irqsave@p1(lock1,flags) | ||
| 50 | | | ||
| 51 | *read_lock_irqsave@p1(lock1,flags) | ||
| 52 | | | ||
| 53 | *write_lock_irqsave@p1(lock1,flags) | ||
| 54 | ) | ||
| 55 | ... when != f | ||
| 56 | ( | ||
| 57 | *spin_lock_irqsave@p2(lock2,flags) | ||
| 58 | | | ||
| 59 | *read_lock_irqsave@p2(lock2,flags) | ||
| 60 | | | ||
| 61 | *write_lock_irqsave@p2(lock2,flags) | ||
| 62 | ) | ||
| 63 | |||
| 64 | // ---------------------------------------------------------------------- | ||
| 65 | |||
| 66 | @script:python depends on d && org@ | ||
| 67 | p1 << r.p1; | ||
| 68 | p2 << r.p2; | ||
| 69 | @@ | ||
| 70 | |||
| 71 | cocci.print_main("original lock",p1) | ||
| 72 | cocci.print_secs("nested lock+irqsave that reuses flags",p2) | ||
| 73 | |||
| 74 | @script:python depends on d && report@ | ||
| 75 | p1 << r.p1; | ||
| 76 | p2 << r.p2; | ||
| 77 | @@ | ||
| 78 | |||
| 79 | msg="ERROR: nested lock+irqsave that reuses flags from %s." % (p1[0].line) | ||
| 80 | coccilib.report.print_report(p2[0], msg) | ||
diff --git a/scripts/coccinelle/locks/mini_lock.cocci b/scripts/coccinelle/locks/mini_lock.cocci new file mode 100644 index 000000000000..7641a2925434 --- /dev/null +++ b/scripts/coccinelle/locks/mini_lock.cocci | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | /// Find missing unlocks. This semantic match considers the specific case | ||
| 2 | /// where the unlock is missing from an if branch, and there is a lock | ||
| 3 | /// before the if and an unlock after the if. False positives are due to | ||
| 4 | /// cases where the if branch represents a case where the function is | ||
| 5 | /// supposed to exit with the lock held, or where there is some preceding | ||
| 6 | /// function call that releases the lock. | ||
| 7 | /// | ||
| 8 | // Confidence: Moderate | ||
| 9 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 10 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 11 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 12 | // URL: http://coccinelle.lip6.fr/ | ||
| 13 | // Comments: | ||
| 14 | // Options: -no_includes -include_headers | ||
| 15 | |||
| 16 | virtual org | ||
| 17 | virtual report | ||
| 18 | |||
| 19 | @prelocked@ | ||
| 20 | position p1,p; | ||
| 21 | expression E1; | ||
| 22 | @@ | ||
| 23 | |||
| 24 | ( | ||
| 25 | mutex_lock@p1 | ||
| 26 | | | ||
| 27 | mutex_trylock@p1 | ||
| 28 | | | ||
| 29 | spin_lock@p1 | ||
| 30 | | | ||
| 31 | spin_trylock@p1 | ||
| 32 | | | ||
| 33 | read_lock@p1 | ||
| 34 | | | ||
| 35 | read_trylock@p1 | ||
| 36 | | | ||
| 37 | write_lock@p1 | ||
| 38 | | | ||
| 39 | write_trylock@p1 | ||
| 40 | | | ||
| 41 | read_lock_irq@p1 | ||
| 42 | | | ||
| 43 | write_lock_irq@p1 | ||
| 44 | | | ||
| 45 | read_lock_irqsave@p1 | ||
| 46 | | | ||
| 47 | write_lock_irqsave@p1 | ||
| 48 | | | ||
| 49 | spin_lock_irq@p1 | ||
| 50 | | | ||
| 51 | spin_lock_irqsave@p1 | ||
| 52 | ) (E1@p,...); | ||
| 53 | |||
| 54 | @looped@ | ||
| 55 | position r; | ||
| 56 | @@ | ||
| 57 | |||
| 58 | for(...;...;...) { <+... return@r ...; ...+> } | ||
| 59 | |||
| 60 | @err@ | ||
| 61 | expression E1; | ||
| 62 | position prelocked.p; | ||
| 63 | position up != prelocked.p1; | ||
| 64 | position r!=looped.r; | ||
| 65 | identifier lock,unlock; | ||
| 66 | @@ | ||
| 67 | |||
| 68 | lock(E1@p,...); | ||
| 69 | <+... when != E1 | ||
| 70 | if (...) { | ||
| 71 | ... when != E1 | ||
| 72 | return@r ...; | ||
| 73 | } | ||
| 74 | ...+> | ||
| 75 | unlock@up(E1,...); | ||
| 76 | |||
| 77 | @script:python depends on org@ | ||
| 78 | p << prelocked.p1; | ||
| 79 | lock << err.lock; | ||
| 80 | unlock << err.unlock; | ||
| 81 | p2 << err.r; | ||
| 82 | @@ | ||
| 83 | |||
| 84 | cocci.print_main(lock,p) | ||
| 85 | cocci.print_secs(unlock,p2) | ||
| 86 | |||
| 87 | @script:python depends on report@ | ||
| 88 | p << prelocked.p1; | ||
| 89 | lock << err.lock; | ||
| 90 | unlock << err.unlock; | ||
| 91 | p2 << err.r; | ||
| 92 | @@ | ||
| 93 | |||
| 94 | msg = "preceding lock on line %s" % (p[0].line) | ||
| 95 | coccilib.report.print_report(p2[0],msg) | ||
diff --git a/scripts/coccinelle/misc/doubleinit.cocci b/scripts/coccinelle/misc/doubleinit.cocci new file mode 100644 index 000000000000..55d7dc19dfe0 --- /dev/null +++ b/scripts/coccinelle/misc/doubleinit.cocci | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | /// Find duplicate field initializations. This has a high rate of false | ||
| 2 | /// positives due to #ifdefs, which Coccinelle is not aware of in a structure | ||
| 3 | /// initialization. | ||
| 4 | /// | ||
| 5 | // Confidence: Low | ||
| 6 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 7 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 8 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 9 | // URL: http://coccinelle.lip6.fr/ | ||
| 10 | // Comments: | ||
| 11 | // Options: -no_includes -include_headers | ||
| 12 | |||
| 13 | virtual org | ||
| 14 | virtual report | ||
| 15 | |||
| 16 | @r@ | ||
| 17 | identifier I, s, fld; | ||
| 18 | position p0,p; | ||
| 19 | expression E; | ||
| 20 | @@ | ||
| 21 | |||
| 22 | struct I s =@p0 { ... .fld@p = E, ...}; | ||
| 23 | |||
| 24 | @s@ | ||
| 25 | identifier I, s, r.fld; | ||
| 26 | position r.p0,p; | ||
| 27 | expression E; | ||
| 28 | @@ | ||
| 29 | |||
| 30 | struct I s =@p0 { ... .fld@p = E, ...}; | ||
| 31 | |||
| 32 | @script:python depends on org@ | ||
| 33 | p0 << r.p0; | ||
| 34 | fld << r.fld; | ||
| 35 | ps << s.p; | ||
| 36 | pr << r.p; | ||
| 37 | @@ | ||
| 38 | |||
| 39 | if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)): | ||
| 40 | cocci.print_main(fld,p0) | ||
| 41 | cocci.print_secs("s",ps) | ||
| 42 | cocci.print_secs("r",pr) | ||
| 43 | |||
| 44 | @script:python depends on report@ | ||
| 45 | p0 << r.p0; | ||
| 46 | fld << r.fld; | ||
| 47 | ps << s.p; | ||
| 48 | pr << r.p; | ||
| 49 | @@ | ||
| 50 | |||
| 51 | if int(ps[0].line) < int(pr[0].line) or (int(ps[0].line) == int(pr[0].line) and int(ps[0].column) < int(pr[0].column)): | ||
| 52 | msg = "%s: first occurrence %s, second occurrence %s" % (fld,ps[0].line,pr[0].line) | ||
| 53 | coccilib.report.print_report(p0[0],msg) | ||
diff --git a/scripts/coccinelle/misc/ifcol.cocci b/scripts/coccinelle/misc/ifcol.cocci new file mode 100644 index 000000000000..b7ed91dbeb95 --- /dev/null +++ b/scripts/coccinelle/misc/ifcol.cocci | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | /// Find confusingly indented code in or after an if. An if branch should | ||
| 2 | /// be indented. The code following an if should not be indented. | ||
| 3 | /// Sometimes, code after an if that is indented is actually intended to be | ||
| 4 | /// part of the if branch. | ||
| 5 | /// | ||
| 6 | /// This has a high rate of false positives, because Coccinelle's column | ||
| 7 | /// calculation does not distinguish between spaces and tabs, so code that | ||
| 8 | /// is not visually aligned may be considered to be in the same column. | ||
| 9 | /// | ||
| 10 | // Confidence: Low | ||
| 11 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 12 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 13 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 14 | // URL: http://coccinelle.lip6.fr/ | ||
| 15 | // Comments: | ||
| 16 | // Options: -no_includes -include_headers | ||
| 17 | |||
| 18 | virtual org | ||
| 19 | virtual report | ||
| 20 | |||
| 21 | @r disable braces4@ | ||
| 22 | position p1,p2; | ||
| 23 | statement S1,S2; | ||
| 24 | @@ | ||
| 25 | |||
| 26 | ( | ||
| 27 | if (...) { ... } | ||
| 28 | | | ||
| 29 | if (...) S1@p1 S2@p2 | ||
| 30 | ) | ||
| 31 | |||
| 32 | @script:python depends on org@ | ||
| 33 | p1 << r.p1; | ||
| 34 | p2 << r.p2; | ||
| 35 | @@ | ||
| 36 | |||
| 37 | if (p1[0].column == p2[0].column): | ||
| 38 | cocci.print_main("branch",p1) | ||
| 39 | cocci.print_secs("after",p2) | ||
| 40 | |||
| 41 | @script:python depends on report@ | ||
| 42 | p1 << r.p1; | ||
| 43 | p2 << r.p2; | ||
| 44 | @@ | ||
| 45 | |||
| 46 | if (p1[0].column == p2[0].column): | ||
| 47 | msg = "code aligned with following code on line %s" % (p2[0].line) | ||
| 48 | coccilib.report.print_report(p1[0],msg) | ||
diff --git a/scripts/coccinelle/deref_null.cocci b/scripts/coccinelle/null/deref_null.cocci index 9969d76d0f4b..9969d76d0f4b 100644 --- a/scripts/coccinelle/deref_null.cocci +++ b/scripts/coccinelle/null/deref_null.cocci | |||
diff --git a/scripts/coccinelle/null/eno.cocci b/scripts/coccinelle/null/eno.cocci new file mode 100644 index 000000000000..4c9c52b9c413 --- /dev/null +++ b/scripts/coccinelle/null/eno.cocci | |||
| @@ -0,0 +1,20 @@ | |||
| 1 | /// The various basic memory allocation functions don't return ERR_PTR | ||
| 2 | /// | ||
| 3 | // Confidence: High | ||
| 4 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 5 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 6 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 7 | // URL: http://coccinelle.lip6.fr/ | ||
| 8 | // Comments: | ||
| 9 | // Options: -no_includes -include_headers | ||
| 10 | |||
| 11 | virtual patch | ||
| 12 | |||
| 13 | @@ | ||
| 14 | expression x,E; | ||
| 15 | @@ | ||
| 16 | |||
| 17 | x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...) | ||
| 18 | ... when != x = E | ||
| 19 | - IS_ERR(x) | ||
| 20 | + !x | ||
diff --git a/scripts/coccinelle/null/kmerr.cocci b/scripts/coccinelle/null/kmerr.cocci new file mode 100644 index 000000000000..949bf656c64c --- /dev/null +++ b/scripts/coccinelle/null/kmerr.cocci | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | /// This semantic patch looks for kmalloc etc that are not followed by a | ||
| 2 | /// NULL check. It only gives a report in the case where there is some | ||
| 3 | /// error handling code later in the function, which may be helpful | ||
| 4 | /// in determining what the error handling code for the call to kmalloc etc | ||
| 5 | /// should be. | ||
| 6 | /// | ||
| 7 | // Confidence: High | ||
| 8 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 9 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 10 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 11 | // URL: http://coccinelle.lip6.fr/ | ||
| 12 | // Comments: | ||
| 13 | // Options: -no_includes -include_headers | ||
| 14 | |||
| 15 | virtual context | ||
| 16 | virtual org | ||
| 17 | virtual report | ||
| 18 | |||
| 19 | @withtest@ | ||
| 20 | expression x; | ||
| 21 | position p; | ||
| 22 | identifier f,fld; | ||
| 23 | @@ | ||
| 24 | |||
| 25 | x@p = f(...); | ||
| 26 | ... when != x->fld | ||
| 27 | \(x == NULL \| x != NULL\) | ||
| 28 | |||
| 29 | @fixed depends on context && !org && !report@ | ||
| 30 | expression x,x1; | ||
| 31 | position p1 != withtest.p; | ||
| 32 | statement S; | ||
| 33 | position any withtest.p; | ||
| 34 | identifier f; | ||
| 35 | @@ | ||
| 36 | |||
| 37 | *x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); | ||
| 38 | ... | ||
| 39 | *x1@p = f(...); | ||
| 40 | if (!x1) S | ||
| 41 | |||
| 42 | // ------------------------------------------------------------------------ | ||
| 43 | |||
| 44 | @rfixed depends on (org || report) && !context exists@ | ||
| 45 | expression x,x1; | ||
| 46 | position p1 != withtest.p; | ||
| 47 | position p2; | ||
| 48 | statement S; | ||
| 49 | position any withtest.p; | ||
| 50 | identifier f; | ||
| 51 | @@ | ||
| 52 | |||
| 53 | x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...); | ||
| 54 | ... | ||
| 55 | x1@p = f@p2(...); | ||
| 56 | if (!x1) S | ||
| 57 | |||
| 58 | @script:python depends on org@ | ||
| 59 | p1 << rfixed.p1; | ||
| 60 | p2 << rfixed.p2; | ||
| 61 | @@ | ||
| 62 | |||
| 63 | cocci.print_main("alloc call",p1) | ||
| 64 | cocci.print_secs("possible model",p2) | ||
| 65 | |||
| 66 | @script:python depends on report@ | ||
| 67 | p1 << rfixed.p1; | ||
| 68 | p2 << rfixed.p2; | ||
| 69 | @@ | ||
| 70 | |||
| 71 | msg = "alloc with no test, possible model on line %s" % (p2[0].line) | ||
| 72 | coccilib.report.print_report(p1[0],msg) | ||
diff --git a/scripts/coccinelle/tests/doublebitand.cocci b/scripts/coccinelle/tests/doublebitand.cocci new file mode 100644 index 000000000000..9ba73d05a77e --- /dev/null +++ b/scripts/coccinelle/tests/doublebitand.cocci | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | /// Find bit operations that include the same argument more than once | ||
| 2 | //# One source of false positives is when the argument performs a side | ||
| 3 | //# effect. Another source of false positives is when a neutral value | ||
| 4 | //# such as 0 for | is used to indicate no information, to maintain the | ||
| 5 | //# same structure as other similar expressions | ||
| 6 | /// | ||
| 7 | // Confidence: Moderate | ||
| 8 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 9 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 10 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 11 | // URL: http://coccinelle.lip6.fr/ | ||
| 12 | // Comments: | ||
| 13 | // Options: -no_includes -include_headers | ||
| 14 | |||
| 15 | virtual context | ||
| 16 | virtual org | ||
| 17 | virtual report | ||
| 18 | |||
| 19 | @r expression@ | ||
| 20 | expression E; | ||
| 21 | position p; | ||
| 22 | @@ | ||
| 23 | |||
| 24 | ( | ||
| 25 | * E@p | ||
| 26 | & ... & E | ||
| 27 | | | ||
| 28 | * E@p | ||
| 29 | | ... | E | ||
| 30 | | | ||
| 31 | * E@p | ||
| 32 | & ... & !E | ||
| 33 | | | ||
| 34 | * E@p | ||
| 35 | | ... | !E | ||
| 36 | | | ||
| 37 | * !E@p | ||
| 38 | & ... & E | ||
| 39 | | | ||
| 40 | * !E@p | ||
| 41 | | ... | E | ||
| 42 | ) | ||
| 43 | |||
| 44 | @script:python depends on org@ | ||
| 45 | p << r.p; | ||
| 46 | @@ | ||
| 47 | |||
| 48 | cocci.print_main("duplicated argument to & or |",p) | ||
| 49 | |||
| 50 | @script:python depends on report@ | ||
| 51 | p << r.p; | ||
| 52 | @@ | ||
| 53 | |||
| 54 | coccilib.report.print_report(p[0],"duplicated argument to & or |") | ||
diff --git a/scripts/coccinelle/tests/doubletest.cocci b/scripts/coccinelle/tests/doubletest.cocci new file mode 100644 index 000000000000..13a2c0e8a4bf --- /dev/null +++ b/scripts/coccinelle/tests/doubletest.cocci | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | /// Find &&/|| operations that include the same argument more than once | ||
| 2 | //# A common source of false positives is when the argument performs a side | ||
| 3 | //# effect. | ||
| 4 | /// | ||
| 5 | // Confidence: Moderate | ||
| 6 | // Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2. | ||
| 7 | // Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2. | ||
| 8 | // Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2. | ||
| 9 | // URL: http://coccinelle.lip6.fr/ | ||
| 10 | // Comments: | ||
| 11 | // Options: -no_includes -include_headers | ||
| 12 | |||
| 13 | virtual context | ||
| 14 | virtual org | ||
| 15 | virtual report | ||
| 16 | |||
| 17 | @r expression@ | ||
| 18 | expression E; | ||
| 19 | position p; | ||
| 20 | @@ | ||
| 21 | |||
| 22 | ( | ||
| 23 | * E@p | ||
| 24 | || ... || E | ||
| 25 | | | ||
| 26 | * E@p | ||
| 27 | && ... && E | ||
| 28 | ) | ||
| 29 | |||
| 30 | @script:python depends on org@ | ||
| 31 | p << r.p; | ||
| 32 | @@ | ||
| 33 | |||
| 34 | cocci.print_main("duplicated argument to && or ||",p) | ||
| 35 | |||
| 36 | @script:python depends on report@ | ||
| 37 | p << r.p; | ||
| 38 | @@ | ||
| 39 | |||
| 40 | coccilib.report.print_report(p[0],"duplicated argument to && or ||") | ||
diff --git a/scripts/extract-ikconfig b/scripts/extract-ikconfig index 37f30d36c944..1512c0a755ac 100755 --- a/scripts/extract-ikconfig +++ b/scripts/extract-ikconfig | |||
| @@ -7,12 +7,10 @@ | |||
| 7 | # The obscure use of the "tr" filter is to work around older versions of | 7 | # The obscure use of the "tr" filter is to work around older versions of |
| 8 | # "grep" that report the byte offset of the line instead of the pattern. | 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 | # Licensed under the terms of the GNU General Public License. | 11 | # Licensed under the terms of the GNU General Public License. |
| 12 | # ---------------------------------------------------------------------- | 12 | # ---------------------------------------------------------------------- |
| 13 | 13 | ||
| 14 | gz1='\037\213\010' | ||
| 15 | gz2='01' | ||
| 16 | cf1='IKCFG_ST\037\213\010' | 14 | cf1='IKCFG_ST\037\213\010' |
| 17 | cf2='0123456789' | 15 | cf2='0123456789' |
| 18 | 16 | ||
| @@ -21,11 +19,25 @@ dump_config() | |||
| 21 | if pos=`tr "$cf1\n$cf2" "\n$cf2=" < "$1" | grep -abo "^$cf2"` | 19 | if pos=`tr "$cf1\n$cf2" "\n$cf2=" < "$1" | grep -abo "^$cf2"` |
| 22 | then | 20 | then |
| 23 | pos=${pos%%:*} | 21 | pos=${pos%%:*} |
| 24 | tail -c+$(($pos+8)) "$1" | zcat -q | 22 | tail -c+$(($pos+8)) "$1" | zcat > $tmp1 2> /dev/null |
| 25 | exit 0 | 23 | if [ $? != 1 ] |
| 24 | then # exit status must be 0 or 2 (trailing garbage warning) | ||
| 25 | cat $tmp1 | ||
| 26 | exit 0 | ||
| 27 | fi | ||
| 26 | fi | 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 | # Check invocation: | 41 | # Check invocation: |
| 30 | me=${0##*/} | 42 | me=${0##*/} |
| 31 | img=$1 | 43 | img=$1 |
| @@ -35,18 +47,19 @@ then | |||
| 35 | exit 2 | 47 | exit 2 |
| 36 | fi | 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 | # Initial attempt for uncompressed images or objects: | 55 | # Initial attempt for uncompressed images or objects: |
| 39 | dump_config "$img" | 56 | dump_config "$img" |
| 40 | 57 | ||
| 41 | # That didn't work, so decompress and try again: | 58 | # That didn't work, so retry after decompression. |
| 42 | tmp=/tmp/ikconfig$$ | 59 | try_decompress '\037\213\010' xy gunzip |
| 43 | trap "rm -f $tmp" 0 | 60 | try_decompress 'BZh' xy bunzip2 |
| 44 | for pos in `tr "$gz1\n$gz2" "\n$gz2=" < "$img" | grep -abo "^$gz2"` | 61 | try_decompress '\135\0\0\0' xxx unlzma |
| 45 | do | 62 | try_decompress '\211\114\132' xy 'lzop -d' |
| 46 | pos=${pos%%:*} | ||
| 47 | tail -c+$pos "$img" | zcat 2> /dev/null > $tmp | ||
| 48 | dump_config $tmp | ||
| 49 | done | ||
| 50 | 63 | ||
| 51 | # Bail out: | 64 | # Bail out: |
| 52 | echo "$me: Cannot find kernel config." >&2 | 65 | echo "$me: Cannot find kernel config." >&2 |
diff --git a/scripts/namespace.pl b/scripts/namespace.pl index 361d0f71184b..a71be6b7cdec 100755 --- a/scripts/namespace.pl +++ b/scripts/namespace.pl | |||
| @@ -84,6 +84,64 @@ my %ksymtab = (); # names that appear in __ksymtab_ | |||
| 84 | my %ref = (); # $ref{$name} exists if there is a true external reference to $name | 84 | my %ref = (); # $ref{$name} exists if there is a true external reference to $name |
| 85 | my %export = (); # $export{$name} exists if there is an EXPORT_... of $name | 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 | &find(\&linux_objects, '.'); # find the objects and do_nm on them | 145 | &find(\&linux_objects, '.'); # find the objects and do_nm on them |
| 88 | &list_multiply_defined(); | 146 | &list_multiply_defined(); |
| 89 | &resolve_external_references(); | 147 | &resolve_external_references(); |
| @@ -105,7 +163,8 @@ sub linux_objects | |||
| 105 | if (/.*\.o$/ && | 163 | if (/.*\.o$/ && |
| 106 | ! ( | 164 | ! ( |
| 107 | m:/built-in.o$: | 165 | m:/built-in.o$: |
| 108 | || m:arch/x86/kernel/vsyscall-syms.o$: | 166 | || m:arch/x86/vdso/: |
| 167 | || m:arch/x86/boot/: | ||
| 109 | || m:arch/ia64/ia32/ia32.o$: | 168 | || m:arch/ia64/ia32/ia32.o$: |
| 110 | || m:arch/ia64/kernel/gate-syms.o$: | 169 | || m:arch/ia64/kernel/gate-syms.o$: |
| 111 | || m:arch/ia64/lib/__divdi3.o$: | 170 | || m:arch/ia64/lib/__divdi3.o$: |
| @@ -148,6 +207,7 @@ sub linux_objects | |||
| 148 | || m:^.*/\.tmp_: | 207 | || m:^.*/\.tmp_: |
| 149 | || m:^\.tmp_: | 208 | || m:^\.tmp_: |
| 150 | || m:/vmlinux-obj.o$: | 209 | || m:/vmlinux-obj.o$: |
| 210 | || m:^tools/: | ||
| 151 | ) | 211 | ) |
| 152 | ) { | 212 | ) { |
| 153 | do_nm($basename, $_); | 213 | do_nm($basename, $_); |
| @@ -167,11 +227,11 @@ sub do_nm | |||
| 167 | printf STDERR "$fullname is not an object file\n"; | 227 | printf STDERR "$fullname is not an object file\n"; |
| 168 | return; | 228 | return; |
| 169 | } | 229 | } |
| 170 | ($source = $fullname) =~ s/\.o$//; | 230 | ($source = $basename) =~ s/\.o$//; |
| 171 | if (-e "$objtree$source.c" || -e "$objtree$source.S") { | 231 | if (-e "$source.c" || -e "$source.S") { |
| 172 | $source = "$objtree$source"; | 232 | $source = "$objtree$File::Find::dir/$source"; |
| 173 | } else { | 233 | } else { |
| 174 | $source = "$srctree$source"; | 234 | $source = "$srctree$File::Find::dir/$source"; |
| 175 | } | 235 | } |
| 176 | if (! -e "$source.c" && ! -e "$source.S") { | 236 | if (! -e "$source.c" && ! -e "$source.S") { |
| 177 | # No obvious source, exclude the object if it is conglomerate | 237 | # No obvious source, exclude the object if it is conglomerate |
| @@ -214,6 +274,7 @@ sub do_nm | |||
| 214 | # T global label/procedure | 274 | # T global label/procedure |
| 215 | # U external reference | 275 | # U external reference |
| 216 | # W weak external reference to text that has been resolved | 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 | # a assembler equate | 278 | # a assembler equate |
| 218 | # b static variable, uninitialised | 279 | # b static variable, uninitialised |
| 219 | # d static variable, initialised | 280 | # d static variable, initialised |
| @@ -222,8 +283,9 @@ sub do_nm | |||
| 222 | # s static variable, uninitialised, small bss | 283 | # s static variable, uninitialised, small bss |
| 223 | # t static label/procedures | 284 | # t static label/procedures |
| 224 | # w weak external reference to text that has not been resolved | 285 | # w weak external reference to text that has not been resolved |
| 286 | # v similar to w | ||
| 225 | # ? undefined type, used a lot by modules | 287 | # ? undefined type, used a lot by modules |
| 226 | if ($type !~ /^[ABCDGRSTUWabdgrstw?]$/) { | 288 | if ($type !~ /^[ABCDGRSTUWVabdgrstwv?]$/) { |
| 227 | printf STDERR "nm output for $fullname contains unknown type '$_'\n"; | 289 | printf STDERR "nm output for $fullname contains unknown type '$_'\n"; |
| 228 | } | 290 | } |
| 229 | elsif ($name =~ /\./) { | 291 | elsif ($name =~ /\./) { |
| @@ -234,7 +296,7 @@ sub do_nm | |||
| 234 | # binutils keeps changing the type for exported symbols, force it to R | 296 | # binutils keeps changing the type for exported symbols, force it to R |
| 235 | $type = 'R' if ($name =~ /^__ksymtab/ || $name =~ /^__kstrtab/); | 297 | $type = 'R' if ($name =~ /^__ksymtab/ || $name =~ /^__kstrtab/); |
| 236 | $name =~ s/_R[a-f0-9]{8}$//; # module versions adds this | 298 | $name =~ s/_R[a-f0-9]{8}$//; # module versions adds this |
| 237 | if ($type =~ /[ABCDGRSTW]/ && | 299 | if ($type =~ /[ABCDGRSTWV]/ && |
| 238 | $name ne 'init_module' && | 300 | $name ne 'init_module' && |
| 239 | $name ne 'cleanup_module' && | 301 | $name ne 'cleanup_module' && |
| 240 | $name ne 'Using_Versions' && | 302 | $name ne 'Using_Versions' && |
| @@ -270,27 +332,9 @@ sub do_nm | |||
| 270 | close($nmdata); | 332 | close($nmdata); |
| 271 | 333 | ||
| 272 | if ($#nmdata < 0) { | 334 | if ($#nmdata < 0) { |
| 273 | if ( | 335 | printf "No nm data for $fullname\n" |
| 274 | $fullname ne "lib/brlock.o" | 336 | unless $nmexception{$fullname}; |
| 275 | && $fullname ne "lib/dec_and_lock.o" | 337 | return; |
| 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; | ||
| 294 | } | 338 | } |
| 295 | $nmdata{$fullname} = \@nmdata; | 339 | $nmdata{$fullname} = \@nmdata; |
| 296 | } | 340 | } |
| @@ -319,18 +363,14 @@ sub list_multiply_defined | |||
| 319 | foreach my $name (keys(%def)) { | 363 | foreach my $name (keys(%def)) { |
| 320 | if ($#{$def{$name}} > 0) { | 364 | if ($#{$def{$name}} > 0) { |
| 321 | # Special case for cond_syscall | 365 | # Special case for cond_syscall |
| 322 | if ($#{$def{$name}} == 1 && $name =~ /^sys_/ && | 366 | if ($#{$def{$name}} == 1 && |
| 323 | ($def{$name}[0] eq "kernel/sys.o" || | 367 | ($name =~ /^sys_/ || $name =~ /^compat_sys_/ || |
| 324 | $def{$name}[1] eq "kernel/sys.o")) { | 368 | $name =~ /^sys32_/)) { |
| 325 | &drop_def("kernel/sys.o", $name); | 369 | if($def{$name}[0] eq "kernel/sys_ni.o" || |
| 326 | next; | 370 | $def{$name}[1] eq "kernel/sys_ni.o") { |
| 327 | } | 371 | &drop_def("kernel/sys_ni.o", $name); |
| 328 | # Special case for i386 entry code | 372 | next; |
| 329 | if ($#{$def{$name}} == 1 && $name =~ /^__kernel_/ && | 373 | } |
| 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 | } | 374 | } |
| 335 | 375 | ||
| 336 | printf "$name is multiply defined in :-\n"; | 376 | printf "$name is multiply defined in :-\n"; |
| @@ -372,31 +412,7 @@ sub resolve_external_references | |||
| 372 | $ref{$name} = "" | 412 | $ref{$name} = "" |
| 373 | } | 413 | } |
| 374 | } | 414 | } |
| 375 | elsif ( $name ne "mod_use_count_" | 415 | elsif ( ! $nameexception{$name} |
| 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" | ||
| 400 | && $name !~ /^__sched_text_/ | 416 | && $name !~ /^__sched_text_/ |
| 401 | && $name !~ /^__start_/ | 417 | && $name !~ /^__start_/ |
| 402 | && $name !~ /^__end_/ | 418 | && $name !~ /^__end_/ |
| @@ -407,7 +423,6 @@ sub resolve_external_references | |||
| 407 | && $name !~ /^__.*per_cpu_end/ | 423 | && $name !~ /^__.*per_cpu_end/ |
| 408 | && $name !~ /^__alt_instructions/ | 424 | && $name !~ /^__alt_instructions/ |
| 409 | && $name !~ /^__setup_/ | 425 | && $name !~ /^__setup_/ |
| 410 | && $name !~ /^jiffies/ | ||
| 411 | && $name !~ /^__mod_timer/ | 426 | && $name !~ /^__mod_timer/ |
| 412 | && $name !~ /^__mod_page_state/ | 427 | && $name !~ /^__mod_page_state/ |
| 413 | && $name !~ /^init_module/ | 428 | && $name !~ /^init_module/ |
