mirror of
https://github.com/Fishwaldo/Star64_linux.git
synced 2025-06-26 08:31:13 +00:00
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 ...
This commit is contained in:
commit
e596c79050
29 changed files with 1591 additions and 470 deletions
|
@ -333,7 +333,10 @@ static void docsect(char *filename, char *line)
|
|||
if (*s == '\n')
|
||||
*s = '\0';
|
||||
|
||||
asprintf(&s, "DOC: %s", line);
|
||||
if (asprintf(&s, "DOC: %s", line) < 0) {
|
||||
perror("asprintf");
|
||||
exit(1);
|
||||
}
|
||||
consume_symbol(s);
|
||||
free(s);
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ if [ "$C" = "1" -o "$C" = "2" ]; then
|
|||
else
|
||||
ONLINE=0
|
||||
FLAGS="-very_quiet"
|
||||
OPTIONS="-dir $srctree"
|
||||
fi
|
||||
|
||||
if [ ! -x "$SPATCH" ]; then
|
||||
|
@ -25,11 +26,13 @@ fi
|
|||
|
||||
if [ "$MODE" = "" ] ; then
|
||||
if [ "$ONLINE" = "0" ] ; then
|
||||
echo 'You have not explicitly specify the mode to use. Fallback to "report".'
|
||||
echo 'You have not explicitly specified the mode to use. Using default "chain" mode.'
|
||||
echo 'All available modes will be tried (in that order): patch, report, context, org'
|
||||
echo 'You can specify the mode with "make coccicheck MODE=<mode>"'
|
||||
echo 'Available modes are: report, patch, context, org'
|
||||
fi
|
||||
MODE="report"
|
||||
MODE="chain"
|
||||
elif [ "$MODE" = "report" -o "$MODE" = "org" ] ; then
|
||||
FLAGS="$FLAGS -no_show_diff"
|
||||
fi
|
||||
|
||||
if [ "$ONLINE" = "0" ] ; then
|
||||
|
@ -44,7 +47,7 @@ coccinelle () {
|
|||
|
||||
OPT=`grep "Option" $COCCI | cut -d':' -f2`
|
||||
|
||||
# The option '-parse_cocci' can be used to syntaxically check the SmPL files.
|
||||
# The option '-parse_cocci' can be used to syntactically check the SmPL files.
|
||||
#
|
||||
# $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null
|
||||
|
||||
|
@ -52,21 +55,44 @@ coccinelle () {
|
|||
|
||||
FILE=`echo $COCCI | sed "s|$srctree/||"`
|
||||
|
||||
echo "Processing `basename $COCCI` with option(s) \"$OPT\""
|
||||
echo "Processing `basename $COCCI`"
|
||||
echo "with option(s) \"$OPT\""
|
||||
echo ''
|
||||
echo 'Message example to submit a patch:'
|
||||
|
||||
sed -e '/\/\/\//!d' -e 's|^///||' $COCCI
|
||||
sed -ne 's|^///||p' $COCCI
|
||||
|
||||
echo ' The semantic patch that makes this change is available'
|
||||
if [ "$MODE" = "patch" ] ; then
|
||||
echo ' The semantic patch that makes this change is available'
|
||||
elif [ "$MODE" = "report" ] ; then
|
||||
echo ' The semantic patch that makes this report is available'
|
||||
elif [ "$MODE" = "context" ] ; then
|
||||
echo ' The semantic patch that spots this code is available'
|
||||
elif [ "$MODE" = "org" ] ; then
|
||||
echo ' The semantic patch that makes this Org report is available'
|
||||
else
|
||||
echo ' The semantic patch that makes this output is available'
|
||||
fi
|
||||
echo " in $FILE."
|
||||
echo ''
|
||||
echo ' More information about semantic patching is available at'
|
||||
echo ' http://coccinelle.lip6.fr/'
|
||||
echo ''
|
||||
|
||||
$SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT -dir $srctree || exit 1
|
||||
if [ "`sed -ne 's|^//#||p' $COCCI`" ] ; then
|
||||
echo 'Semantic patch information:'
|
||||
sed -ne 's|^//#||p' $COCCI
|
||||
echo ''
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ "$MODE" = "chain" ] ; then
|
||||
$SPATCH -D patch $FLAGS -sp_file $COCCI $OPT $OPTIONS || \
|
||||
$SPATCH -D report $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || \
|
||||
$SPATCH -D context $FLAGS -sp_file $COCCI $OPT $OPTIONS || \
|
||||
$SPATCH -D org $FLAGS -sp_file $COCCI $OPT $OPTIONS -no_show_diff || exit 1
|
||||
else
|
||||
$SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1
|
||||
$SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1
|
||||
fi
|
||||
|
||||
}
|
||||
|
|
|
@ -1,5 +1,9 @@
|
|||
///
|
||||
/// kzalloc should be used rather than kmalloc followed by memset 0
|
||||
/// Use kzalloc rather than kmalloc followed by memset with 0
|
||||
///
|
||||
/// This considers some simple cases that are common and easy to validate
|
||||
/// Note in particular that there are no ...s in the rule, so all of the
|
||||
/// matched code has to be contiguous
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2.
|
39
scripts/coccinelle/api/kstrdup.cocci
Normal file
39
scripts/coccinelle/api/kstrdup.cocci
Normal file
|
@ -0,0 +1,39 @@
|
|||
/// Use kstrdup rather than duplicating its implementation
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual patch
|
||||
|
||||
@@
|
||||
expression from,to;
|
||||
expression flag,E1,E2;
|
||||
statement S;
|
||||
@@
|
||||
|
||||
- to = kmalloc(strlen(from) + 1,flag);
|
||||
+ to = kstrdup(from, flag);
|
||||
... when != \(from = E1 \| to = E1 \)
|
||||
if (to==NULL || ...) S
|
||||
... when != \(from = E2 \| to = E2 \)
|
||||
- strcpy(to, from);
|
||||
|
||||
@@
|
||||
expression x,from,to;
|
||||
expression flag,E1,E2,E3;
|
||||
statement S;
|
||||
@@
|
||||
|
||||
- x = strlen(from) + 1;
|
||||
... when != \( x = E1 \| from = E1 \)
|
||||
- to = \(kmalloc\|kzalloc\)(x,flag);
|
||||
+ to = kstrdup(from, flag);
|
||||
... when != \(x = E2 \| from = E2 \| to = E2 \)
|
||||
if (to==NULL || ...) S
|
||||
... when != \(x = E3 \| from = E3 \| to = E3 \)
|
||||
- memcpy(to, from, x);
|
40
scripts/coccinelle/api/memdup.cocci
Normal file
40
scripts/coccinelle/api/memdup.cocci
Normal file
|
@ -0,0 +1,40 @@
|
|||
/// Use kmemdup rather than duplicating its implementation
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual patch
|
||||
|
||||
@r1@
|
||||
expression from,to;
|
||||
expression flag;
|
||||
position p;
|
||||
@@
|
||||
|
||||
to = \(kmalloc@p\|kzalloc@p\)(strlen(from) + 1,flag);
|
||||
|
||||
@r2@
|
||||
expression x,from,to;
|
||||
expression flag,E1;
|
||||
position p;
|
||||
@@
|
||||
|
||||
x = strlen(from) + 1;
|
||||
... when != \( x = E1 \| from = E1 \)
|
||||
to = \(kmalloc@p\|kzalloc@p\)(x,flag);
|
||||
|
||||
@@
|
||||
expression from,to,size,flag;
|
||||
position p != {r1.p,r2.p};
|
||||
statement S;
|
||||
@@
|
||||
|
||||
- to = \(kmalloc@p\|kzalloc@p\)(size,flag);
|
||||
+ to = kmemdup(from,size,flag);
|
||||
if (to==NULL || ...) S
|
||||
- memcpy(to, from, size);
|
35
scripts/coccinelle/api/memdup_user.cocci
Normal file
35
scripts/coccinelle/api/memdup_user.cocci
Normal file
|
@ -0,0 +1,35 @@
|
|||
/// Use kmemdup_user rather than duplicating its implementation
|
||||
/// This is a little bit restricted to reduce false positives
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual patch
|
||||
|
||||
@@
|
||||
expression from,to,size,flag;
|
||||
position p;
|
||||
identifier l1,l2;
|
||||
@@
|
||||
|
||||
- to = \(kmalloc@p\|kzalloc@p\)(size,flag);
|
||||
+ to = memdup_user(from,size);
|
||||
if (
|
||||
- to==NULL
|
||||
+ IS_ERR(to)
|
||||
|| ...) {
|
||||
<+... when != goto l1;
|
||||
- -ENOMEM
|
||||
+ PTR_ERR(to)
|
||||
...+>
|
||||
}
|
||||
- if (copy_from_user(to, from, size) != 0) {
|
||||
- <+... when != goto l2;
|
||||
- -EFAULT
|
||||
- ...+>
|
||||
- }
|
117
scripts/coccinelle/free/kfree.cocci
Normal file
117
scripts/coccinelle/free/kfree.cocci
Normal file
|
@ -0,0 +1,117 @@
|
|||
/// Find a use after free.
|
||||
//# Values of variables may imply that some
|
||||
//# execution paths are not possible, resulting in false positives.
|
||||
//# Another source of false positives are macros such as
|
||||
//# SCTP_DBG_OBJCNT_DEC that do not actually evaluate their argument
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@free@
|
||||
expression E;
|
||||
position p1;
|
||||
@@
|
||||
|
||||
kfree@p1(E)
|
||||
|
||||
@print expression@
|
||||
constant char *c;
|
||||
expression free.E,E2;
|
||||
type T;
|
||||
position p;
|
||||
identifier f;
|
||||
@@
|
||||
|
||||
(
|
||||
f(...,c,...,(T)E@p,...)
|
||||
|
|
||||
E@p == E2
|
||||
|
|
||||
E@p != E2
|
||||
|
|
||||
!E@p
|
||||
|
|
||||
E@p || ...
|
||||
)
|
||||
|
||||
@sz@
|
||||
expression free.E;
|
||||
position p;
|
||||
@@
|
||||
|
||||
sizeof(<+...E@p...+>)
|
||||
|
||||
@loop exists@
|
||||
expression E;
|
||||
identifier l;
|
||||
position ok;
|
||||
@@
|
||||
|
||||
while (1) { ...
|
||||
kfree@ok(E)
|
||||
... when != break;
|
||||
when != goto l;
|
||||
when forall
|
||||
}
|
||||
|
||||
@r exists@
|
||||
expression free.E, subE<=free.E, E2;
|
||||
expression E1;
|
||||
iterator iter;
|
||||
statement S;
|
||||
position free.p1!=loop.ok,p2!={print.p,sz.p};
|
||||
@@
|
||||
|
||||
kfree@p1(E,...)
|
||||
...
|
||||
(
|
||||
iter(...,subE,...) S // no use
|
||||
|
|
||||
list_remove_head(E1,subE,...)
|
||||
|
|
||||
subE = E2
|
||||
|
|
||||
subE++
|
||||
|
|
||||
++subE
|
||||
|
|
||||
--subE
|
||||
|
|
||||
subE--
|
||||
|
|
||||
&subE
|
||||
|
|
||||
BUG(...)
|
||||
|
|
||||
BUG_ON(...)
|
||||
|
|
||||
return_VALUE(...)
|
||||
|
|
||||
return_ACPI_STATUS(...)
|
||||
|
|
||||
E@p2 // bad use
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << free.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
cocci.print_main("kfree",p1)
|
||||
cocci.print_secs("ref",p2)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << free.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
msg = "reference preceded by free on line %s" % (p1[0].line)
|
||||
coccilib.report.print_report(p2[0],msg)
|
64
scripts/coccinelle/iterators/fen.cocci
Normal file
64
scripts/coccinelle/iterators/fen.cocci
Normal file
|
@ -0,0 +1,64 @@
|
|||
/// These iterators only exit normally when the loop cursor is NULL, so there
|
||||
/// is no point to call of_node_put on the final value.
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual patch
|
||||
|
||||
@@
|
||||
iterator name for_each_node_by_name;
|
||||
expression np,E;
|
||||
identifier l;
|
||||
@@
|
||||
|
||||
for_each_node_by_name(np,...) {
|
||||
... when != break;
|
||||
when != goto l;
|
||||
}
|
||||
... when != np = E
|
||||
- of_node_put(np);
|
||||
|
||||
@@
|
||||
iterator name for_each_node_by_type;
|
||||
expression np,E;
|
||||
identifier l;
|
||||
@@
|
||||
|
||||
for_each_node_by_type(np,...) {
|
||||
... when != break;
|
||||
when != goto l;
|
||||
}
|
||||
... when != np = E
|
||||
- of_node_put(np);
|
||||
|
||||
@@
|
||||
iterator name for_each_compatible_node;
|
||||
expression np,E;
|
||||
identifier l;
|
||||
@@
|
||||
|
||||
for_each_compatible_node(np,...) {
|
||||
... when != break;
|
||||
when != goto l;
|
||||
}
|
||||
... when != np = E
|
||||
- of_node_put(np);
|
||||
|
||||
@@
|
||||
iterator name for_each_matching_node;
|
||||
expression np,E;
|
||||
identifier l;
|
||||
@@
|
||||
|
||||
for_each_matching_node(np,...) {
|
||||
... when != break;
|
||||
when != goto l;
|
||||
}
|
||||
... when != np = E
|
||||
- of_node_put(np);
|
58
scripts/coccinelle/iterators/itnull.cocci
Normal file
58
scripts/coccinelle/iterators/itnull.cocci
Normal file
|
@ -0,0 +1,58 @@
|
|||
/// Many iterators have the property that the first argument is always bound
|
||||
/// to a real list element, never NULL. False positives arise for some
|
||||
/// iterators that do not have this property, or in cases when the loop
|
||||
/// cursor is reassigned. The latter should only happen when the matched
|
||||
/// code is on the way to a loop exit (break, goto, or return).
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual patch
|
||||
|
||||
@@
|
||||
iterator I;
|
||||
expression x,E,E1,E2;
|
||||
statement S,S1,S2;
|
||||
@@
|
||||
|
||||
I(x,...) { <...
|
||||
(
|
||||
- if (x == NULL && ...) S
|
||||
|
|
||||
- if (x != NULL || ...)
|
||||
S
|
||||
|
|
||||
- (x == NULL) ||
|
||||
E
|
||||
|
|
||||
- (x != NULL) &&
|
||||
E
|
||||
|
|
||||
- (x == NULL && ...) ? E1 :
|
||||
E2
|
||||
|
|
||||
- (x != NULL || ...) ?
|
||||
E1
|
||||
- : E2
|
||||
|
|
||||
- if (x == NULL && ...) S1 else
|
||||
S2
|
||||
|
|
||||
- if (x != NULL || ...)
|
||||
S1
|
||||
- else S2
|
||||
|
|
||||
+ BAD(
|
||||
x == NULL
|
||||
+ )
|
||||
|
|
||||
+ BAD(
|
||||
x != NULL
|
||||
+ )
|
||||
)
|
||||
...> }
|
62
scripts/coccinelle/iterators/list_entry_update.cocci
Normal file
62
scripts/coccinelle/iterators/list_entry_update.cocci
Normal file
|
@ -0,0 +1,62 @@
|
|||
/// list_for_each_entry uses its first argument to get from one element of
|
||||
/// the list to the next, so it is usually not a good idea to reassign it.
|
||||
/// The first rule finds such a reassignment and the second rule checks
|
||||
/// that there is a path from the reassignment back to the top of the loop.
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@r@
|
||||
iterator name list_for_each_entry;
|
||||
expression x,E;
|
||||
position p1,p2;
|
||||
@@
|
||||
|
||||
list_for_each_entry@p1(x,...) { <... x =@p2 E ...> }
|
||||
|
||||
@depends on context && !org && !report@
|
||||
expression x,E;
|
||||
position r.p1,r.p2;
|
||||
statement S;
|
||||
@@
|
||||
|
||||
*x =@p2 E
|
||||
...
|
||||
list_for_each_entry@p1(x,...) S
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@back depends on (org || report) && !context exists@
|
||||
expression x,E;
|
||||
position r.p1,r.p2;
|
||||
statement S;
|
||||
@@
|
||||
|
||||
x =@p2 E
|
||||
...
|
||||
list_for_each_entry@p1(x,...) S
|
||||
|
||||
@script:python depends on back && org@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
cocci.print_main("iterator",p1)
|
||||
cocci.print_secs("update",p2)
|
||||
|
||||
@script:python depends on back && report@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
msg = "iterator with update on line %s" % (p2[0].line)
|
||||
coccilib.report.print_report(p1[0],msg)
|
74
scripts/coccinelle/locks/call_kern.cocci
Normal file
74
scripts/coccinelle/locks/call_kern.cocci
Normal file
|
@ -0,0 +1,74 @@
|
|||
/// Find functions that refer to GFP_KERNEL but are called with locks held.
|
||||
/// The proposed change of converting the GFP_KERNEL is not necessarily the
|
||||
/// correct one. It may be desired to unlock the lock, or to not call the
|
||||
/// function under the lock in the first place.
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual patch
|
||||
|
||||
@gfp exists@
|
||||
identifier fn;
|
||||
position p;
|
||||
@@
|
||||
|
||||
fn(...) {
|
||||
... when != read_unlock_irq(...)
|
||||
when != write_unlock_irq(...)
|
||||
when != read_unlock_irqrestore(...)
|
||||
when != write_unlock_irqrestore(...)
|
||||
when != spin_unlock(...)
|
||||
when != spin_unlock_irq(...)
|
||||
when != spin_unlock_irqrestore(...)
|
||||
when != local_irq_enable(...)
|
||||
when any
|
||||
GFP_KERNEL@p
|
||||
... when any
|
||||
}
|
||||
|
||||
@locked@
|
||||
identifier gfp.fn;
|
||||
@@
|
||||
|
||||
(
|
||||
read_lock_irq
|
||||
|
|
||||
write_lock_irq
|
||||
|
|
||||
read_lock_irqsave
|
||||
|
|
||||
write_lock_irqsave
|
||||
|
|
||||
spin_lock
|
||||
|
|
||||
spin_trylock
|
||||
|
|
||||
spin_lock_irq
|
||||
|
|
||||
spin_lock_irqsave
|
||||
|
|
||||
local_irq_disable
|
||||
)
|
||||
(...)
|
||||
... when != read_unlock_irq(...)
|
||||
when != write_unlock_irq(...)
|
||||
when != read_unlock_irqrestore(...)
|
||||
when != write_unlock_irqrestore(...)
|
||||
when != spin_unlock(...)
|
||||
when != spin_unlock_irq(...)
|
||||
when != spin_unlock_irqrestore(...)
|
||||
when != local_irq_enable(...)
|
||||
fn(...)
|
||||
|
||||
@depends on locked@
|
||||
position gfp.p;
|
||||
@@
|
||||
|
||||
- GFP_KERNEL@p
|
||||
+ GFP_ATOMIC
|
92
scripts/coccinelle/locks/double_lock.cocci
Normal file
92
scripts/coccinelle/locks/double_lock.cocci
Normal file
|
@ -0,0 +1,92 @@
|
|||
/// Find double locks. False positives may occur when some paths cannot
|
||||
/// occur at execution, due to the values of variables, and when there is
|
||||
/// an intervening function call that releases the lock.
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@locked@
|
||||
position p1;
|
||||
expression E1;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(
|
||||
mutex_lock@p1
|
||||
|
|
||||
mutex_trylock@p1
|
||||
|
|
||||
spin_lock@p1
|
||||
|
|
||||
spin_trylock@p1
|
||||
|
|
||||
read_lock@p1
|
||||
|
|
||||
read_trylock@p1
|
||||
|
|
||||
write_lock@p1
|
||||
|
|
||||
write_trylock@p1
|
||||
) (E1@p,...);
|
||||
|
||||
@balanced@
|
||||
position p1 != locked.p1;
|
||||
position locked.p;
|
||||
identifier lock,unlock;
|
||||
expression x <= locked.E1;
|
||||
expression E,locked.E1;
|
||||
expression E2;
|
||||
@@
|
||||
|
||||
if (E) {
|
||||
<+... when != E1
|
||||
lock(E1@p,...)
|
||||
...+>
|
||||
}
|
||||
... when != E1
|
||||
when != \(x = E2\|&x\)
|
||||
when forall
|
||||
if (E) {
|
||||
<+... when != E1
|
||||
unlock@p1(E1,...)
|
||||
...+>
|
||||
}
|
||||
|
||||
@r depends on !balanced exists@
|
||||
expression x <= locked.E1;
|
||||
expression locked.E1;
|
||||
expression E2;
|
||||
identifier lock;
|
||||
position locked.p,p1,p2;
|
||||
@@
|
||||
|
||||
lock@p1 (E1@p,...);
|
||||
... when != E1
|
||||
when != \(x = E2\|&x\)
|
||||
lock@p2 (E1,...);
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
lock << r.lock;
|
||||
@@
|
||||
|
||||
cocci.print_main(lock,p1)
|
||||
cocci.print_secs("second lock",p2)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
lock << r.lock;
|
||||
@@
|
||||
|
||||
msg = "second lock on line %s" % (p2[0].line)
|
||||
coccilib.report.print_report(p1[0],msg)
|
80
scripts/coccinelle/locks/flags.cocci
Normal file
80
scripts/coccinelle/locks/flags.cocci
Normal file
|
@ -0,0 +1,80 @@
|
|||
/// Find nested lock+irqsave functions that use the same flags variables
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@r@
|
||||
expression lock1,lock2,flags;
|
||||
position p1,p2;
|
||||
@@
|
||||
|
||||
(
|
||||
spin_lock_irqsave@p1(lock1,flags)
|
||||
|
|
||||
read_lock_irqsave@p1(lock1,flags)
|
||||
|
|
||||
write_lock_irqsave@p1(lock1,flags)
|
||||
)
|
||||
... when != flags
|
||||
(
|
||||
spin_lock_irqsave(lock1,flags)
|
||||
|
|
||||
read_lock_irqsave(lock1,flags)
|
||||
|
|
||||
write_lock_irqsave(lock1,flags)
|
||||
|
|
||||
spin_lock_irqsave@p2(lock2,flags)
|
||||
|
|
||||
read_lock_irqsave@p2(lock2,flags)
|
||||
|
|
||||
write_lock_irqsave@p2(lock2,flags)
|
||||
)
|
||||
|
||||
@d@
|
||||
expression f <= r.flags;
|
||||
expression lock1,lock2,flags;
|
||||
position r.p1, r.p2;
|
||||
@@
|
||||
|
||||
(
|
||||
*spin_lock_irqsave@p1(lock1,flags)
|
||||
|
|
||||
*read_lock_irqsave@p1(lock1,flags)
|
||||
|
|
||||
*write_lock_irqsave@p1(lock1,flags)
|
||||
)
|
||||
... when != f
|
||||
(
|
||||
*spin_lock_irqsave@p2(lock2,flags)
|
||||
|
|
||||
*read_lock_irqsave@p2(lock2,flags)
|
||||
|
|
||||
*write_lock_irqsave@p2(lock2,flags)
|
||||
)
|
||||
|
||||
// ----------------------------------------------------------------------
|
||||
|
||||
@script:python depends on d && org@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
cocci.print_main("original lock",p1)
|
||||
cocci.print_secs("nested lock+irqsave that reuses flags",p2)
|
||||
|
||||
@script:python depends on d && report@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
msg="ERROR: nested lock+irqsave that reuses flags from %s." % (p1[0].line)
|
||||
coccilib.report.print_report(p2[0], msg)
|
95
scripts/coccinelle/locks/mini_lock.cocci
Normal file
95
scripts/coccinelle/locks/mini_lock.cocci
Normal file
|
@ -0,0 +1,95 @@
|
|||
/// Find missing unlocks. This semantic match considers the specific case
|
||||
/// where the unlock is missing from an if branch, and there is a lock
|
||||
/// before the if and an unlock after the if. False positives are due to
|
||||
/// cases where the if branch represents a case where the function is
|
||||
/// supposed to exit with the lock held, or where there is some preceding
|
||||
/// function call that releases the lock.
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@prelocked@
|
||||
position p1,p;
|
||||
expression E1;
|
||||
@@
|
||||
|
||||
(
|
||||
mutex_lock@p1
|
||||
|
|
||||
mutex_trylock@p1
|
||||
|
|
||||
spin_lock@p1
|
||||
|
|
||||
spin_trylock@p1
|
||||
|
|
||||
read_lock@p1
|
||||
|
|
||||
read_trylock@p1
|
||||
|
|
||||
write_lock@p1
|
||||
|
|
||||
write_trylock@p1
|
||||
|
|
||||
read_lock_irq@p1
|
||||
|
|
||||
write_lock_irq@p1
|
||||
|
|
||||
read_lock_irqsave@p1
|
||||
|
|
||||
write_lock_irqsave@p1
|
||||
|
|
||||
spin_lock_irq@p1
|
||||
|
|
||||
spin_lock_irqsave@p1
|
||||
) (E1@p,...);
|
||||
|
||||
@looped@
|
||||
position r;
|
||||
@@
|
||||
|
||||
for(...;...;...) { <+... return@r ...; ...+> }
|
||||
|
||||
@err@
|
||||
expression E1;
|
||||
position prelocked.p;
|
||||
position up != prelocked.p1;
|
||||
position r!=looped.r;
|
||||
identifier lock,unlock;
|
||||
@@
|
||||
|
||||
lock(E1@p,...);
|
||||
<+... when != E1
|
||||
if (...) {
|
||||
... when != E1
|
||||
return@r ...;
|
||||
}
|
||||
...+>
|
||||
unlock@up(E1,...);
|
||||
|
||||
@script:python depends on org@
|
||||
p << prelocked.p1;
|
||||
lock << err.lock;
|
||||
unlock << err.unlock;
|
||||
p2 << err.r;
|
||||
@@
|
||||
|
||||
cocci.print_main(lock,p)
|
||||
cocci.print_secs(unlock,p2)
|
||||
|
||||
@script:python depends on report@
|
||||
p << prelocked.p1;
|
||||
lock << err.lock;
|
||||
unlock << err.unlock;
|
||||
p2 << err.r;
|
||||
@@
|
||||
|
||||
msg = "preceding lock on line %s" % (p[0].line)
|
||||
coccilib.report.print_report(p2[0],msg)
|
53
scripts/coccinelle/misc/doubleinit.cocci
Normal file
53
scripts/coccinelle/misc/doubleinit.cocci
Normal file
|
@ -0,0 +1,53 @@
|
|||
/// Find duplicate field initializations. This has a high rate of false
|
||||
/// positives due to #ifdefs, which Coccinelle is not aware of in a structure
|
||||
/// initialization.
|
||||
///
|
||||
// Confidence: Low
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@r@
|
||||
identifier I, s, fld;
|
||||
position p0,p;
|
||||
expression E;
|
||||
@@
|
||||
|
||||
struct I s =@p0 { ... .fld@p = E, ...};
|
||||
|
||||
@s@
|
||||
identifier I, s, r.fld;
|
||||
position r.p0,p;
|
||||
expression E;
|
||||
@@
|
||||
|
||||
struct I s =@p0 { ... .fld@p = E, ...};
|
||||
|
||||
@script:python depends on org@
|
||||
p0 << r.p0;
|
||||
fld << r.fld;
|
||||
ps << s.p;
|
||||
pr << r.p;
|
||||
@@
|
||||
|
||||
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)):
|
||||
cocci.print_main(fld,p0)
|
||||
cocci.print_secs("s",ps)
|
||||
cocci.print_secs("r",pr)
|
||||
|
||||
@script:python depends on report@
|
||||
p0 << r.p0;
|
||||
fld << r.fld;
|
||||
ps << s.p;
|
||||
pr << r.p;
|
||||
@@
|
||||
|
||||
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)):
|
||||
msg = "%s: first occurrence %s, second occurrence %s" % (fld,ps[0].line,pr[0].line)
|
||||
coccilib.report.print_report(p0[0],msg)
|
48
scripts/coccinelle/misc/ifcol.cocci
Normal file
48
scripts/coccinelle/misc/ifcol.cocci
Normal file
|
@ -0,0 +1,48 @@
|
|||
/// Find confusingly indented code in or after an if. An if branch should
|
||||
/// be indented. The code following an if should not be indented.
|
||||
/// Sometimes, code after an if that is indented is actually intended to be
|
||||
/// part of the if branch.
|
||||
///
|
||||
/// This has a high rate of false positives, because Coccinelle's column
|
||||
/// calculation does not distinguish between spaces and tabs, so code that
|
||||
/// is not visually aligned may be considered to be in the same column.
|
||||
///
|
||||
// Confidence: Low
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@r disable braces4@
|
||||
position p1,p2;
|
||||
statement S1,S2;
|
||||
@@
|
||||
|
||||
(
|
||||
if (...) { ... }
|
||||
|
|
||||
if (...) S1@p1 S2@p2
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
if (p1[0].column == p2[0].column):
|
||||
cocci.print_main("branch",p1)
|
||||
cocci.print_secs("after",p2)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << r.p1;
|
||||
p2 << r.p2;
|
||||
@@
|
||||
|
||||
if (p1[0].column == p2[0].column):
|
||||
msg = "code aligned with following code on line %s" % (p2[0].line)
|
||||
coccilib.report.print_report(p1[0],msg)
|
20
scripts/coccinelle/null/eno.cocci
Normal file
20
scripts/coccinelle/null/eno.cocci
Normal file
|
@ -0,0 +1,20 @@
|
|||
/// The various basic memory allocation functions don't return ERR_PTR
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual patch
|
||||
|
||||
@@
|
||||
expression x,E;
|
||||
@@
|
||||
|
||||
x = \(kmalloc\|kzalloc\|kcalloc\|kmem_cache_alloc\|kmem_cache_zalloc\|kmem_cache_alloc_node\|kmalloc_node\|kzalloc_node\)(...)
|
||||
... when != x = E
|
||||
- IS_ERR(x)
|
||||
+ !x
|
72
scripts/coccinelle/null/kmerr.cocci
Normal file
72
scripts/coccinelle/null/kmerr.cocci
Normal file
|
@ -0,0 +1,72 @@
|
|||
/// This semantic patch looks for kmalloc etc that are not followed by a
|
||||
/// NULL check. It only gives a report in the case where there is some
|
||||
/// error handling code later in the function, which may be helpful
|
||||
/// in determining what the error handling code for the call to kmalloc etc
|
||||
/// should be.
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@withtest@
|
||||
expression x;
|
||||
position p;
|
||||
identifier f,fld;
|
||||
@@
|
||||
|
||||
x@p = f(...);
|
||||
... when != x->fld
|
||||
\(x == NULL \| x != NULL\)
|
||||
|
||||
@fixed depends on context && !org && !report@
|
||||
expression x,x1;
|
||||
position p1 != withtest.p;
|
||||
statement S;
|
||||
position any withtest.p;
|
||||
identifier f;
|
||||
@@
|
||||
|
||||
*x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
|
||||
...
|
||||
*x1@p = f(...);
|
||||
if (!x1) S
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
|
||||
@rfixed depends on (org || report) && !context exists@
|
||||
expression x,x1;
|
||||
position p1 != withtest.p;
|
||||
position p2;
|
||||
statement S;
|
||||
position any withtest.p;
|
||||
identifier f;
|
||||
@@
|
||||
|
||||
x@p1 = \(kmalloc\|kzalloc\|kcalloc\)(...);
|
||||
...
|
||||
x1@p = f@p2(...);
|
||||
if (!x1) S
|
||||
|
||||
@script:python depends on org@
|
||||
p1 << rfixed.p1;
|
||||
p2 << rfixed.p2;
|
||||
@@
|
||||
|
||||
cocci.print_main("alloc call",p1)
|
||||
cocci.print_secs("possible model",p2)
|
||||
|
||||
@script:python depends on report@
|
||||
p1 << rfixed.p1;
|
||||
p2 << rfixed.p2;
|
||||
@@
|
||||
|
||||
msg = "alloc with no test, possible model on line %s" % (p2[0].line)
|
||||
coccilib.report.print_report(p1[0],msg)
|
54
scripts/coccinelle/tests/doublebitand.cocci
Normal file
54
scripts/coccinelle/tests/doublebitand.cocci
Normal file
|
@ -0,0 +1,54 @@
|
|||
/// Find bit operations that include the same argument more than once
|
||||
//# One source of false positives is when the argument performs a side
|
||||
//# effect. Another source of false positives is when a neutral value
|
||||
//# such as 0 for | is used to indicate no information, to maintain the
|
||||
//# same structure as other similar expressions
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@r expression@
|
||||
expression E;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(
|
||||
* E@p
|
||||
& ... & E
|
||||
|
|
||||
* E@p
|
||||
| ... | E
|
||||
|
|
||||
* E@p
|
||||
& ... & !E
|
||||
|
|
||||
* E@p
|
||||
| ... | !E
|
||||
|
|
||||
* !E@p
|
||||
& ... & E
|
||||
|
|
||||
* !E@p
|
||||
| ... | E
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
cocci.print_main("duplicated argument to & or |",p)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0],"duplicated argument to & or |")
|
40
scripts/coccinelle/tests/doubletest.cocci
Normal file
40
scripts/coccinelle/tests/doubletest.cocci
Normal file
|
@ -0,0 +1,40 @@
|
|||
/// Find &&/|| operations that include the same argument more than once
|
||||
//# A common source of false positives is when the argument performs a side
|
||||
//# effect.
|
||||
///
|
||||
// Confidence: Moderate
|
||||
// Copyright: (C) 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Comments:
|
||||
// Options: -no_includes -include_headers
|
||||
|
||||
virtual context
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@r expression@
|
||||
expression E;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(
|
||||
* E@p
|
||||
|| ... || E
|
||||
|
|
||||
* E@p
|
||||
&& ... && E
|
||||
)
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
cocci.print_main("duplicated argument to && or ||",p)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
@@
|
||||
|
||||
coccilib.report.print_report(p[0],"duplicated argument to && or ||")
|
|
@ -7,12 +7,10 @@
|
|||
# The obscure use of the "tr" filter is to work around older versions of
|
||||
# "grep" that report the byte offset of the line instead of the pattern.
|
||||
#
|
||||
# (c) 2009, Dick Streefland <dick@streefland.net>
|
||||
# (c) 2009,2010 Dick Streefland <dick@streefland.net>
|
||||
# Licensed under the terms of the GNU General Public License.
|
||||
# ----------------------------------------------------------------------
|
||||
|
||||
gz1='\037\213\010'
|
||||
gz2='01'
|
||||
cf1='IKCFG_ST\037\213\010'
|
||||
cf2='0123456789'
|
||||
|
||||
|
@ -21,11 +19,25 @@ dump_config()
|
|||
if pos=`tr "$cf1\n$cf2" "\n$cf2=" < "$1" | grep -abo "^$cf2"`
|
||||
then
|
||||
pos=${pos%%:*}
|
||||
tail -c+$(($pos+8)) "$1" | zcat -q
|
||||
exit 0
|
||||
tail -c+$(($pos+8)) "$1" | zcat > $tmp1 2> /dev/null
|
||||
if [ $? != 1 ]
|
||||
then # exit status must be 0 or 2 (trailing garbage warning)
|
||||
cat $tmp1
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
try_decompress()
|
||||
{
|
||||
for pos in `tr "$1\n$2" "\n$2=" < "$img" | grep -abo "^$2"`
|
||||
do
|
||||
pos=${pos%%:*}
|
||||
tail -c+$pos "$img" | $3 > $tmp2 2> /dev/null
|
||||
dump_config $tmp2
|
||||
done
|
||||
}
|
||||
|
||||
# Check invocation:
|
||||
me=${0##*/}
|
||||
img=$1
|
||||
|
@ -35,18 +47,19 @@ then
|
|||
exit 2
|
||||
fi
|
||||
|
||||
# Prepare temp files:
|
||||
tmp1=/tmp/ikconfig$$.1
|
||||
tmp2=/tmp/ikconfig$$.2
|
||||
trap "rm -f $tmp1 $tmp2" 0
|
||||
|
||||
# Initial attempt for uncompressed images or objects:
|
||||
dump_config "$img"
|
||||
|
||||
# That didn't work, so decompress and try again:
|
||||
tmp=/tmp/ikconfig$$
|
||||
trap "rm -f $tmp" 0
|
||||
for pos in `tr "$gz1\n$gz2" "\n$gz2=" < "$img" | grep -abo "^$gz2"`
|
||||
do
|
||||
pos=${pos%%:*}
|
||||
tail -c+$pos "$img" | zcat 2> /dev/null > $tmp
|
||||
dump_config $tmp
|
||||
done
|
||||
# That didn't work, so retry after decompression.
|
||||
try_decompress '\037\213\010' xy gunzip
|
||||
try_decompress 'BZh' xy bunzip2
|
||||
try_decompress '\135\0\0\0' xxx unlzma
|
||||
try_decompress '\211\114\132' xy 'lzop -d'
|
||||
|
||||
# Bail out:
|
||||
echo "$me: Cannot find kernel config." >&2
|
||||
|
|
|
@ -84,6 +84,64 @@ my %ksymtab = (); # names that appear in __ksymtab_
|
|||
my %ref = (); # $ref{$name} exists if there is a true external reference to $name
|
||||
my %export = (); # $export{$name} exists if there is an EXPORT_... of $name
|
||||
|
||||
my %nmexception = (
|
||||
'fs/ext3/bitmap' => 1,
|
||||
'fs/ext4/bitmap' => 1,
|
||||
'arch/x86/lib/thunk_32' => 1,
|
||||
'arch/x86/lib/cmpxchg' => 1,
|
||||
'arch/x86/vdso/vdso32/note' => 1,
|
||||
'lib/irq_regs' => 1,
|
||||
'usr/initramfs_data' => 1,
|
||||
'drivers/scsi/aic94xx/aic94xx_dump' => 1,
|
||||
'drivers/scsi/libsas/sas_dump' => 1,
|
||||
'lib/dec_and_lock' => 1,
|
||||
'drivers/ide/ide-probe-mini' => 1,
|
||||
'usr/initramfs_data' => 1,
|
||||
'drivers/acpi/acpia/exdump' => 1,
|
||||
'drivers/acpi/acpia/rsdump' => 1,
|
||||
'drivers/acpi/acpia/nsdumpdv' => 1,
|
||||
'drivers/acpi/acpia/nsdump' => 1,
|
||||
'arch/ia64/sn/kernel/sn2/io' => 1,
|
||||
'arch/ia64/kernel/gate-data' => 1,
|
||||
'security/capability' => 1,
|
||||
'fs/ntfs/sysctl' => 1,
|
||||
'fs/jfs/jfs_debug' => 1,
|
||||
);
|
||||
|
||||
my %nameexception = (
|
||||
'mod_use_count_' => 1,
|
||||
'__initramfs_end' => 1,
|
||||
'__initramfs_start' => 1,
|
||||
'_einittext' => 1,
|
||||
'_sinittext' => 1,
|
||||
'kallsyms_names' => 1,
|
||||
'kallsyms_num_syms' => 1,
|
||||
'kallsyms_addresses'=> 1,
|
||||
'__this_module' => 1,
|
||||
'_etext' => 1,
|
||||
'_edata' => 1,
|
||||
'_end' => 1,
|
||||
'__bss_start' => 1,
|
||||
'_text' => 1,
|
||||
'_stext' => 1,
|
||||
'__gp' => 1,
|
||||
'ia64_unw_start' => 1,
|
||||
'ia64_unw_end' => 1,
|
||||
'__init_begin' => 1,
|
||||
'__init_end' => 1,
|
||||
'__bss_stop' => 1,
|
||||
'__nosave_begin' => 1,
|
||||
'__nosave_end' => 1,
|
||||
'pg0' => 1,
|
||||
'vdso_enabled' => 1,
|
||||
'__stack_chk_fail' => 1,
|
||||
'VDSO32_PRELINK' => 1,
|
||||
'VDSO32_vsyscall' => 1,
|
||||
'VDSO32_rt_sigreturn'=>1,
|
||||
'VDSO32_sigreturn' => 1,
|
||||
);
|
||||
|
||||
|
||||
&find(\&linux_objects, '.'); # find the objects and do_nm on them
|
||||
&list_multiply_defined();
|
||||
&resolve_external_references();
|
||||
|
@ -105,7 +163,8 @@ sub linux_objects
|
|||
if (/.*\.o$/ &&
|
||||
! (
|
||||
m:/built-in.o$:
|
||||
|| m:arch/x86/kernel/vsyscall-syms.o$:
|
||||
|| m:arch/x86/vdso/:
|
||||
|| m:arch/x86/boot/:
|
||||
|| m:arch/ia64/ia32/ia32.o$:
|
||||
|| m:arch/ia64/kernel/gate-syms.o$:
|
||||
|| m:arch/ia64/lib/__divdi3.o$:
|
||||
|
@ -148,6 +207,7 @@ sub linux_objects
|
|||
|| m:^.*/\.tmp_:
|
||||
|| m:^\.tmp_:
|
||||
|| m:/vmlinux-obj.o$:
|
||||
|| m:^tools/:
|
||||
)
|
||||
) {
|
||||
do_nm($basename, $_);
|
||||
|
@ -167,11 +227,11 @@ sub do_nm
|
|||
printf STDERR "$fullname is not an object file\n";
|
||||
return;
|
||||
}
|
||||
($source = $fullname) =~ s/\.o$//;
|
||||
if (-e "$objtree$source.c" || -e "$objtree$source.S") {
|
||||
$source = "$objtree$source";
|
||||
($source = $basename) =~ s/\.o$//;
|
||||
if (-e "$source.c" || -e "$source.S") {
|
||||
$source = "$objtree$File::Find::dir/$source";
|
||||
} else {
|
||||
$source = "$srctree$source";
|
||||
$source = "$srctree$File::Find::dir/$source";
|
||||
}
|
||||
if (! -e "$source.c" && ! -e "$source.S") {
|
||||
# No obvious source, exclude the object if it is conglomerate
|
||||
|
@ -214,6 +274,7 @@ sub do_nm
|
|||
# T global label/procedure
|
||||
# U external reference
|
||||
# W weak external reference to text that has been resolved
|
||||
# V similar to W, but the value of the weak symbol becomes zero with no error.
|
||||
# a assembler equate
|
||||
# b static variable, uninitialised
|
||||
# d static variable, initialised
|
||||
|
@ -222,8 +283,9 @@ sub do_nm
|
|||
# s static variable, uninitialised, small bss
|
||||
# t static label/procedures
|
||||
# w weak external reference to text that has not been resolved
|
||||
# v similar to w
|
||||
# ? undefined type, used a lot by modules
|
||||
if ($type !~ /^[ABCDGRSTUWabdgrstw?]$/) {
|
||||
if ($type !~ /^[ABCDGRSTUWVabdgrstwv?]$/) {
|
||||
printf STDERR "nm output for $fullname contains unknown type '$_'\n";
|
||||
}
|
||||
elsif ($name =~ /\./) {
|
||||
|
@ -234,7 +296,7 @@ sub do_nm
|
|||
# binutils keeps changing the type for exported symbols, force it to R
|
||||
$type = 'R' if ($name =~ /^__ksymtab/ || $name =~ /^__kstrtab/);
|
||||
$name =~ s/_R[a-f0-9]{8}$//; # module versions adds this
|
||||
if ($type =~ /[ABCDGRSTW]/ &&
|
||||
if ($type =~ /[ABCDGRSTWV]/ &&
|
||||
$name ne 'init_module' &&
|
||||
$name ne 'cleanup_module' &&
|
||||
$name ne 'Using_Versions' &&
|
||||
|
@ -270,27 +332,9 @@ sub do_nm
|
|||
close($nmdata);
|
||||
|
||||
if ($#nmdata < 0) {
|
||||
if (
|
||||
$fullname ne "lib/brlock.o"
|
||||
&& $fullname ne "lib/dec_and_lock.o"
|
||||
&& $fullname ne "fs/xfs/xfs_macros.o"
|
||||
&& $fullname ne "drivers/ide/ide-probe-mini.o"
|
||||
&& $fullname ne "usr/initramfs_data.o"
|
||||
&& $fullname ne "drivers/acpi/executer/exdump.o"
|
||||
&& $fullname ne "drivers/acpi/resources/rsdump.o"
|
||||
&& $fullname ne "drivers/acpi/namespace/nsdumpdv.o"
|
||||
&& $fullname ne "drivers/acpi/namespace/nsdump.o"
|
||||
&& $fullname ne "arch/ia64/sn/kernel/sn2/io.o"
|
||||
&& $fullname ne "arch/ia64/kernel/gate-data.o"
|
||||
&& $fullname ne "drivers/ieee1394/oui.o"
|
||||
&& $fullname ne "security/capability.o"
|
||||
&& $fullname ne "sound/core/wrappers.o"
|
||||
&& $fullname ne "fs/ntfs/sysctl.o"
|
||||
&& $fullname ne "fs/jfs/jfs_debug.o"
|
||||
) {
|
||||
printf "No nm data for $fullname\n";
|
||||
}
|
||||
return;
|
||||
printf "No nm data for $fullname\n"
|
||||
unless $nmexception{$fullname};
|
||||
return;
|
||||
}
|
||||
$nmdata{$fullname} = \@nmdata;
|
||||
}
|
||||
|
@ -319,18 +363,14 @@ sub list_multiply_defined
|
|||
foreach my $name (keys(%def)) {
|
||||
if ($#{$def{$name}} > 0) {
|
||||
# Special case for cond_syscall
|
||||
if ($#{$def{$name}} == 1 && $name =~ /^sys_/ &&
|
||||
($def{$name}[0] eq "kernel/sys.o" ||
|
||||
$def{$name}[1] eq "kernel/sys.o")) {
|
||||
&drop_def("kernel/sys.o", $name);
|
||||
next;
|
||||
}
|
||||
# Special case for i386 entry code
|
||||
if ($#{$def{$name}} == 1 && $name =~ /^__kernel_/ &&
|
||||
$def{$name}[0] eq "arch/x86/kernel/vsyscall-int80_32.o" &&
|
||||
$def{$name}[1] eq "arch/x86/kernel/vsyscall-sysenter_32.o") {
|
||||
&drop_def("arch/x86/kernel/vsyscall-sysenter_32.o", $name);
|
||||
next;
|
||||
if ($#{$def{$name}} == 1 &&
|
||||
($name =~ /^sys_/ || $name =~ /^compat_sys_/ ||
|
||||
$name =~ /^sys32_/)) {
|
||||
if($def{$name}[0] eq "kernel/sys_ni.o" ||
|
||||
$def{$name}[1] eq "kernel/sys_ni.o") {
|
||||
&drop_def("kernel/sys_ni.o", $name);
|
||||
next;
|
||||
}
|
||||
}
|
||||
|
||||
printf "$name is multiply defined in :-\n";
|
||||
|
@ -372,31 +412,7 @@ sub resolve_external_references
|
|||
$ref{$name} = ""
|
||||
}
|
||||
}
|
||||
elsif ( $name ne "mod_use_count_"
|
||||
&& $name ne "__initramfs_end"
|
||||
&& $name ne "__initramfs_start"
|
||||
&& $name ne "_einittext"
|
||||
&& $name ne "_sinittext"
|
||||
&& $name ne "kallsyms_names"
|
||||
&& $name ne "kallsyms_num_syms"
|
||||
&& $name ne "kallsyms_addresses"
|
||||
&& $name ne "__this_module"
|
||||
&& $name ne "_etext"
|
||||
&& $name ne "_edata"
|
||||
&& $name ne "_end"
|
||||
&& $name ne "__bss_start"
|
||||
&& $name ne "_text"
|
||||
&& $name ne "_stext"
|
||||
&& $name ne "__gp"
|
||||
&& $name ne "ia64_unw_start"
|
||||
&& $name ne "ia64_unw_end"
|
||||
&& $name ne "__init_begin"
|
||||
&& $name ne "__init_end"
|
||||
&& $name ne "__bss_stop"
|
||||
&& $name ne "__nosave_begin"
|
||||
&& $name ne "__nosave_end"
|
||||
&& $name ne "pg0"
|
||||
&& $name ne "__module_text_address"
|
||||
elsif ( ! $nameexception{$name}
|
||||
&& $name !~ /^__sched_text_/
|
||||
&& $name !~ /^__start_/
|
||||
&& $name !~ /^__end_/
|
||||
|
@ -407,7 +423,6 @@ sub resolve_external_references
|
|||
&& $name !~ /^__.*per_cpu_end/
|
||||
&& $name !~ /^__alt_instructions/
|
||||
&& $name !~ /^__setup_/
|
||||
&& $name !~ /^jiffies/
|
||||
&& $name !~ /^__mod_timer/
|
||||
&& $name !~ /^__mod_page_state/
|
||||
&& $name !~ /^init_module/
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue