You've already forked linux-apfs
mirror of
https://github.com/linux-apfs/linux-apfs.git
synced 2026-05-01 15:00:59 -07:00
Merge commit 'v2.6.36-rc1' into kbuild/rc-fixes
This commit is contained in:
+20
-17
@@ -115,7 +115,10 @@ endif
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
# Default is built-in, unless we know otherwise
|
||||
modkern_cflags = $(if $(part-of-module), $(CFLAGS_MODULE), $(CFLAGS_KERNEL))
|
||||
modkern_cflags = \
|
||||
$(if $(part-of-module), \
|
||||
$(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE), \
|
||||
$(KBUILD_CFLAGS_KERNEL) $(CFLAGS_KERNEL))
|
||||
quiet_modtag := $(empty) $(empty)
|
||||
|
||||
$(real-objs-m) : part-of-module := y
|
||||
@@ -156,14 +159,14 @@ $(obj)/%.i: $(src)/%.c FORCE
|
||||
|
||||
cmd_gensymtypes = \
|
||||
$(CPP) -D__GENKSYMS__ $(c_flags) $< | \
|
||||
$(GENKSYMS) -T $@ -a $(ARCH) \
|
||||
$(GENKSYMS) $(if $(1), -T $(2)) -a $(ARCH) \
|
||||
$(if $(KBUILD_PRESERVE),-p) \
|
||||
$(if $(1),-r $(firstword $(wildcard $(@:.symtypes=.symref) /dev/null)))
|
||||
-r $(firstword $(wildcard $(2:.symtypes=.symref) /dev/null))
|
||||
|
||||
quiet_cmd_cc_symtypes_c = SYM $(quiet_modtag) $@
|
||||
cmd_cc_symtypes_c = \
|
||||
set -e; \
|
||||
$(call cmd_gensymtypes, true) >/dev/null; \
|
||||
$(call cmd_gensymtypes,true,$@) >/dev/null; \
|
||||
test -s $@ || rm -f $@
|
||||
|
||||
$(obj)/%.symtypes : $(src)/%.c FORCE
|
||||
@@ -192,16 +195,16 @@ else
|
||||
# the actual value of the checksum generated by genksyms
|
||||
|
||||
cmd_cc_o_c = $(CC) $(c_flags) -c -o $(@D)/.tmp_$(@F) $<
|
||||
cmd_modversions = \
|
||||
if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
|
||||
$(call cmd_gensymtypes, $(KBUILD_SYMTYPES)) \
|
||||
> $(@D)/.tmp_$(@F:.o=.ver); \
|
||||
\
|
||||
$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
|
||||
-T $(@D)/.tmp_$(@F:.o=.ver); \
|
||||
rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \
|
||||
else \
|
||||
mv -f $(@D)/.tmp_$(@F) $@; \
|
||||
cmd_modversions = \
|
||||
if $(OBJDUMP) -h $(@D)/.tmp_$(@F) | grep -q __ksymtab; then \
|
||||
$(call cmd_gensymtypes,$(KBUILD_SYMTYPES),$(@:.o=.symtypes)) \
|
||||
> $(@D)/.tmp_$(@F:.o=.ver); \
|
||||
\
|
||||
$(LD) $(LDFLAGS) -r -o $@ $(@D)/.tmp_$(@F) \
|
||||
-T $(@D)/.tmp_$(@F:.o=.ver); \
|
||||
rm -f $(@D)/.tmp_$(@F) $(@D)/.tmp_$(@F:.o=.ver); \
|
||||
else \
|
||||
mv -f $(@D)/.tmp_$(@F) $@; \
|
||||
fi;
|
||||
endif
|
||||
|
||||
@@ -248,10 +251,10 @@ $(obj)/%.lst: $(src)/%.c FORCE
|
||||
# Compile assembler sources (.S)
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
modkern_aflags := $(AFLAGS_KERNEL)
|
||||
modkern_aflags := $(KBUILD_AFLAGS_KERNEL) $(AFLAGS_KERNEL)
|
||||
|
||||
$(real-objs-m) : modkern_aflags := $(AFLAGS_MODULE)
|
||||
$(real-objs-m:.o=.s): modkern_aflags := $(AFLAGS_MODULE)
|
||||
$(real-objs-m) : modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
|
||||
$(real-objs-m:.o=.s): modkern_aflags := $(KBUILD_AFLAGS_MODULE) $(AFLAGS_MODULE)
|
||||
|
||||
quiet_cmd_as_s_S = CPP $(quiet_modtag) $@
|
||||
cmd_as_s_S = $(CPP) $(a_flags) -o $@ $<
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#
|
||||
# header-y - list files to be installed. They are preprocessed
|
||||
# to remove __KERNEL__ section of the file
|
||||
# unifdef-y - Same as header-y. Obsolete
|
||||
# objhdr-y - Same as header-y but for generated files
|
||||
#
|
||||
# ==========================================================================
|
||||
@@ -20,7 +19,7 @@ include scripts/Kbuild.include
|
||||
|
||||
install := $(INSTALL_HDR_PATH)/$(_dst)
|
||||
|
||||
header-y := $(sort $(header-y) $(unifdef-y))
|
||||
header-y := $(sort $(header-y))
|
||||
subdirs := $(patsubst %/,%,$(filter %/, $(header-y)))
|
||||
header-y := $(filter-out %/, $(header-y))
|
||||
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
|
||||
checker-help:
|
||||
@echo ' coccicheck - Check with Coccinelle.'
|
||||
@@ -30,7 +30,7 @@
|
||||
# - See include/linux/module.h for more details
|
||||
|
||||
# Step 4 is solely used to allow module versioning in external modules,
|
||||
# where the CRC of each module is retrieved from the Module.symers file.
|
||||
# where the CRC of each module is retrieved from the Module.symvers file.
|
||||
|
||||
# KBUILD_MODPOST_WARN can be set to avoid error out in case of undefined
|
||||
# symbols in the final module linking stage
|
||||
@@ -107,7 +107,7 @@ $(modules:.ko=.mod.c): __modpost ;
|
||||
modname = $(notdir $(@:.mod.o=))
|
||||
|
||||
quiet_cmd_cc_o_c = CC $@
|
||||
cmd_cc_o_c = $(CC) $(c_flags) $(CFLAGS_MODULE) \
|
||||
cmd_cc_o_c = $(CC) $(c_flags) $(KBUILD_CFLAGS_MODULE) $(CFLAGS_MODULE) \
|
||||
-c -o $@ $<
|
||||
|
||||
$(modules:.ko=.mod.o): %.mod.o: %.mod.c FORCE
|
||||
@@ -117,8 +117,9 @@ targets += $(modules:.ko=.mod.o)
|
||||
|
||||
# Step 6), final link of the modules
|
||||
quiet_cmd_ld_ko_o = LD [M] $@
|
||||
cmd_ld_ko_o = $(LD) -r $(LDFLAGS) $(LDFLAGS_MODULE) -o $@ \
|
||||
$(filter-out FORCE,$^)
|
||||
cmd_ld_ko_o = $(LD) -r $(LDFLAGS) \
|
||||
$(KBUILD_LDFLAGS_MODULE) $(LDFLAGS_MODULE) \
|
||||
-o $@ $(filter-out FORCE,$^)
|
||||
|
||||
$(modules): %.ko :%.o %.mod.o FORCE
|
||||
$(call if_changed,ld_ko_o)
|
||||
|
||||
@@ -14,7 +14,7 @@ find $paths -name '*.[chS]' -o -name 'Makefile' -o -name 'Makefile*[^~]'| while
|
||||
do
|
||||
# Output the bare Kconfig variable and the filename; the _MODULE part at
|
||||
# the end is not removed here (would need perl an not-hungry regexp for that).
|
||||
sed -ne 's!^.*\<\(UML_\)\?CONFIG_\([0-9A-Z_]\+\).*!\2 '$i'!p' < $i
|
||||
sed -ne 's!^.*\<\(UML_\)\?CONFIG_\([0-9A-Za-z_]\+\).*!\2 '$i'!p' < $i
|
||||
done | \
|
||||
# Smart "sort|uniq" implemented in awk and tuned to collect the names of all
|
||||
# files which use a given symbol
|
||||
|
||||
+37
-5
@@ -195,7 +195,7 @@ our $typeTypedefs = qr{(?x:
|
||||
our $logFunctions = qr{(?x:
|
||||
printk|
|
||||
pr_(debug|dbg|vdbg|devel|info|warning|err|notice|alert|crit|emerg|cont)|
|
||||
dev_(printk|dbg|vdbg|info|warn|err|notice|alert|crit|emerg|WARN)|
|
||||
(dev|netdev|netif)_(printk|dbg|vdbg|info|warn|err|notice|alert|crit|emerg|WARN)|
|
||||
WARN|
|
||||
panic
|
||||
)};
|
||||
@@ -224,6 +224,12 @@ our @modifierList = (
|
||||
qr{fastcall},
|
||||
);
|
||||
|
||||
our $allowed_asm_includes = qr{(?x:
|
||||
irq|
|
||||
memory
|
||||
)};
|
||||
# memory.h: ARM has a custom one
|
||||
|
||||
sub build_types {
|
||||
my $mods = "(?x: \n" . join("|\n ", @modifierList) . "\n)";
|
||||
my $all = "(?x: \n" . join("|\n ", @typeList) . "\n)";
|
||||
@@ -552,6 +558,9 @@ sub ctx_statement_block {
|
||||
$type = ($level != 0)? '{' : '';
|
||||
|
||||
if ($level == 0) {
|
||||
if (substr($blk, $off + 1, 1) eq ';') {
|
||||
$off++;
|
||||
}
|
||||
last;
|
||||
}
|
||||
}
|
||||
@@ -1403,7 +1412,8 @@ sub process {
|
||||
#80 column limit
|
||||
if ($line =~ /^\+/ && $prevrawline !~ /\/\*\*/ &&
|
||||
$rawline !~ /^.\s*\*\s*\@$Ident\s/ &&
|
||||
$line !~ /^\+\s*$logFunctions\s*\(\s*(?:KERN_\S+\s*)?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ &&
|
||||
!($line =~ /^\+\s*$logFunctions\s*\(\s*(?:(KERN_\S+\s*|[^"]*))?"[X\t]*"\s*(?:,|\)\s*;)\s*$/ ||
|
||||
$line =~ /^\+\s*"[^"]*"\s*(?:\s*|,|\)\s*;)\s*$/) &&
|
||||
$length > 80)
|
||||
{
|
||||
WARN("line over 80 characters\n" . $herecurr);
|
||||
@@ -1448,6 +1458,13 @@ sub process {
|
||||
WARN("please, no space before tabs\n" . $herevet);
|
||||
}
|
||||
|
||||
# check for spaces at the beginning of a line.
|
||||
if ($rawline =~ /^\+ / && $rawline !~ /\+ +\*/) {
|
||||
my $herevet = "$here\n" . cat_vet($rawline) . "\n";
|
||||
WARN("please, no space for starting a line, \
|
||||
excluding comments\n" . $herevet);
|
||||
}
|
||||
|
||||
# check we are in a valid C source file if not then ignore this hunk
|
||||
next if ($realfile !~ /\.(h|c)$/);
|
||||
|
||||
@@ -1778,9 +1795,9 @@ sub process {
|
||||
WARN("EXPORT_SYMBOL(foo); should immediately follow its function/variable\n" . $herecurr);
|
||||
}
|
||||
|
||||
# check for external initialisers.
|
||||
# check for global initialisers.
|
||||
if ($line =~ /^.$Type\s*$Ident\s*(?:\s+$Modifier)*\s*=\s*(0|NULL|false)\s*;/) {
|
||||
ERROR("do not initialise externals to 0 or NULL\n" .
|
||||
ERROR("do not initialise globals to 0 or NULL\n" .
|
||||
$herecurr);
|
||||
}
|
||||
# check for static initialisers.
|
||||
@@ -2308,7 +2325,7 @@ sub process {
|
||||
my $checkfile = "include/linux/$file";
|
||||
if (-f "$root/$checkfile" &&
|
||||
$realfile ne $checkfile &&
|
||||
$1 ne 'irq')
|
||||
$1 !~ /$allowed_asm_includes/)
|
||||
{
|
||||
if ($realfile =~ m{^arch/}) {
|
||||
CHK("Consider using #include <linux/$file> instead of <asm/$file>\n" . $herecurr);
|
||||
@@ -2570,6 +2587,21 @@ sub process {
|
||||
}
|
||||
}
|
||||
|
||||
# prefer usleep_range over udelay
|
||||
if ($line =~ /\budelay\s*\(\s*(\w+)\s*\)/) {
|
||||
# ignore udelay's < 10, however
|
||||
if (! (($1 =~ /(\d+)/) && ($1 < 10)) ) {
|
||||
CHK("usleep_range is preferred over udelay; see Documentation/timers/timers-howto.txt\n" . $line);
|
||||
}
|
||||
}
|
||||
|
||||
# warn about unexpectedly long msleep's
|
||||
if ($line =~ /\bmsleep\s*\((\d+)\);/) {
|
||||
if ($1 < 20) {
|
||||
WARN("msleep < 20ms can sleep for up to 20ms; see Documentation/timers/timers-howto.txt\n" . $line);
|
||||
}
|
||||
}
|
||||
|
||||
# warn about #ifdefs in C files
|
||||
# if ($line =~ /^.\s*\#\s*if(|n)def/ && ($realfile =~ /\.c$/)) {
|
||||
# print "#ifdef in C files should be avoided\n";
|
||||
|
||||
@@ -183,7 +183,6 @@ cat << EOF
|
||||
#define __IGNORE_ustat /* statfs */
|
||||
#define __IGNORE_utime /* utimes */
|
||||
#define __IGNORE_vfork /* clone */
|
||||
#define __IGNORE_wait4 /* waitid */
|
||||
|
||||
/* sync_file_range had a stupid ABI. Allow sync_file_range2 instead */
|
||||
#ifdef __NR_sync_file_range2
|
||||
|
||||
Executable
+80
@@ -0,0 +1,80 @@
|
||||
#!/bin/sh
|
||||
|
||||
SPATCH="`which ${SPATCH:=spatch}`"
|
||||
|
||||
if [ "$C" = "1" -o "$C" = "2" ]; then
|
||||
ONLINE=1
|
||||
|
||||
# This requires Coccinelle >= 0.2.3
|
||||
# FLAGS="-ignore_unknown_options -very_quiet"
|
||||
# OPTIONS=$*
|
||||
|
||||
# Workaround for Coccinelle < 0.2.3
|
||||
FLAGS="-I $srctree/include -very_quiet"
|
||||
shift $(( $# - 1 ))
|
||||
OPTIONS=$1
|
||||
else
|
||||
ONLINE=0
|
||||
FLAGS="-very_quiet"
|
||||
fi
|
||||
|
||||
if [ ! -x "$SPATCH" ]; then
|
||||
echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/'
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$MODE" = "" ] ; then
|
||||
if [ "$ONLINE" = "0" ] ; then
|
||||
echo 'You have not explicitly specify the mode to use. Fallback to "report".'
|
||||
echo 'You can specify the mode with "make coccicheck MODE=<mode>"'
|
||||
echo 'Available modes are: report, patch, context, org'
|
||||
fi
|
||||
MODE="report"
|
||||
fi
|
||||
|
||||
if [ "$ONLINE" = "0" ] ; then
|
||||
echo ''
|
||||
echo 'Please check for false positives in the output before submitting a patch.'
|
||||
echo 'When using "patch" mode, carefully review the patch before submitting it.'
|
||||
echo ''
|
||||
fi
|
||||
|
||||
coccinelle () {
|
||||
COCCI="$1"
|
||||
|
||||
OPT=`grep "Option" $COCCI | cut -d':' -f2`
|
||||
|
||||
# The option '-parse_cocci' can be used to syntaxically check the SmPL files.
|
||||
#
|
||||
# $SPATCH -D $MODE $FLAGS -parse_cocci $COCCI $OPT > /dev/null
|
||||
|
||||
if [ "$ONLINE" = "0" ] ; then
|
||||
|
||||
FILE=`echo $COCCI | sed "s|$srctree/||"`
|
||||
|
||||
echo "Processing `basename $COCCI` with option(s) \"$OPT\""
|
||||
echo 'Message example to submit a patch:'
|
||||
|
||||
sed -e '/\/\/\//!d' -e 's|^///||' $COCCI
|
||||
|
||||
echo ' The semantic patch that makes this change is available'
|
||||
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
|
||||
else
|
||||
$SPATCH -D $MODE $FLAGS -sp_file $COCCI $OPT $OPTIONS || exit 1
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
if [ "$COCCI" = "" ] ; then
|
||||
for f in `find $srctree/scripts/coccinelle/ -name '*.cocci' -type f | sort`; do
|
||||
coccinelle $f
|
||||
done
|
||||
else
|
||||
coccinelle $COCCI
|
||||
fi
|
||||
@@ -0,0 +1,67 @@
|
||||
///
|
||||
/// Casting (void *) value returned by kmalloc is useless
|
||||
/// as mentioned in Documentation/CodingStyle, Chap 14.
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: 2009,2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Options: -no_includes -include_headers
|
||||
//
|
||||
// Keywords: kmalloc, kzalloc, kcalloc
|
||||
// Version min: < 2.6.12 kmalloc
|
||||
// Version min: < 2.6.12 kcalloc
|
||||
// Version min: 2.6.14 kzalloc
|
||||
//
|
||||
|
||||
virtual context
|
||||
virtual patch
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For context mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on context@
|
||||
type T;
|
||||
@@
|
||||
|
||||
* (T *)
|
||||
\(kmalloc\|kzalloc\|kcalloc\)(...)
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For patch mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on patch@
|
||||
type T;
|
||||
@@
|
||||
|
||||
- (T *)
|
||||
\(kmalloc\|kzalloc\|kcalloc\)(...)
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For org and report mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@r depends on org || report@
|
||||
type T;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(T@p *)\(kmalloc\|kzalloc\|kcalloc\)(...)
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
t << r.T;
|
||||
@@
|
||||
|
||||
coccilib.org.print_safe_todo(p[0], t)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
t << r.T;
|
||||
@@
|
||||
|
||||
msg="WARNING: casting value returned by k[cmz]alloc to (%s *) is useless." % (t)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
@@ -0,0 +1,82 @@
|
||||
///
|
||||
/// kzalloc should be used rather than kmalloc followed by memset 0
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2009-2010 Julia Lawall, Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2009-2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/rules/kzalloc.html
|
||||
// Options: -no_includes -include_headers
|
||||
//
|
||||
// Keywords: kmalloc, kzalloc
|
||||
// Version min: < 2.6.12 kmalloc
|
||||
// Version min: 2.6.14 kzalloc
|
||||
//
|
||||
|
||||
virtual context
|
||||
virtual patch
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For context mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on context@
|
||||
type T, T2;
|
||||
expression x;
|
||||
expression E1,E2;
|
||||
statement S;
|
||||
@@
|
||||
|
||||
* x = (T)kmalloc(E1,E2);
|
||||
if ((x==NULL) || ...) S
|
||||
* memset((T2)x,0,E1);
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For patch mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@depends on patch@
|
||||
type T, T2;
|
||||
expression x;
|
||||
expression E1,E2;
|
||||
statement S;
|
||||
@@
|
||||
|
||||
- x = (T)kmalloc(E1,E2);
|
||||
+ x = kzalloc(E1,E2);
|
||||
if ((x==NULL) || ...) S
|
||||
- memset((T2)x,0,E1);
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For org mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@r depends on org || report@
|
||||
type T, T2;
|
||||
expression x;
|
||||
expression E1,E2;
|
||||
statement S;
|
||||
position p;
|
||||
@@
|
||||
|
||||
x = (T)kmalloc@p(E1,E2);
|
||||
if ((x==NULL) || ...) S
|
||||
memset((T2)x,0,E1);
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
|
||||
msg="%s" % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
coccilib.org.print_todo(p[0], msg_safe)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
|
||||
msg="WARNING: kzalloc should be used for %s, instead of kmalloc/memset" % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
@@ -0,0 +1,293 @@
|
||||
///
|
||||
/// A variable is dereference under a NULL test.
|
||||
/// Even though it is know to be NULL.
|
||||
///
|
||||
// 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: -I ... -all_includes can give more complete results
|
||||
// Options:
|
||||
|
||||
virtual context
|
||||
virtual patch
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
@initialize:python depends on !context && patch && !org && !report@
|
||||
|
||||
import sys
|
||||
print >> sys.stderr, "This semantic patch does not support the 'patch' mode."
|
||||
|
||||
@depends on patch@
|
||||
@@
|
||||
|
||||
this_rule_should_never_matches();
|
||||
|
||||
@ifm depends on !patch@
|
||||
expression *E;
|
||||
statement S1,S2;
|
||||
position p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...) S1 else S2
|
||||
|
||||
// The following two rules are separate, because both can match a single
|
||||
// expression in different ways
|
||||
@pr1 depends on !patch expression@
|
||||
expression *ifm.E;
|
||||
identifier f;
|
||||
position p1;
|
||||
@@
|
||||
|
||||
(E != NULL && ...) ? <+...E->f@p1...+> : ...
|
||||
|
||||
@pr2 depends on !patch expression@
|
||||
expression *ifm.E;
|
||||
identifier f;
|
||||
position p2;
|
||||
@@
|
||||
|
||||
(
|
||||
(E != NULL) && ... && <+...E->f@p2...+>
|
||||
|
|
||||
(E == NULL) || ... || <+...E->f@p2...+>
|
||||
|
|
||||
sizeof(<+...E->f@p2...+>)
|
||||
)
|
||||
|
||||
// For org and report modes
|
||||
|
||||
@r depends on !context && !patch && (org || report) exists@
|
||||
expression subE <= ifm.E;
|
||||
expression *ifm.E;
|
||||
expression E1,E2;
|
||||
identifier f;
|
||||
statement S1,S2,S3,S4;
|
||||
iterator iter;
|
||||
position p!={pr1.p1,pr2.p2};
|
||||
position ifm.p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...)
|
||||
{
|
||||
... when != if (...) S1 else S2
|
||||
(
|
||||
iter(subE,...) S4 // no use
|
||||
|
|
||||
list_remove_head(E2,subE,...)
|
||||
|
|
||||
subE = E1
|
||||
|
|
||||
for(subE = E1;...;...) S4
|
||||
|
|
||||
subE++
|
||||
|
|
||||
++subE
|
||||
|
|
||||
--subE
|
||||
|
|
||||
subE--
|
||||
|
|
||||
&subE
|
||||
|
|
||||
E->f@p // bad use
|
||||
)
|
||||
... when any
|
||||
return ...;
|
||||
}
|
||||
else S3
|
||||
|
||||
@script:python depends on !context && !patch && !org && report@
|
||||
p << r.p;
|
||||
p1 << ifm.p1;
|
||||
x << ifm.E;
|
||||
@@
|
||||
|
||||
msg="ERROR: %s is NULL but dereferenced." % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
cocci.include_match(False)
|
||||
|
||||
@script:python depends on !context && !patch && org && !report@
|
||||
p << r.p;
|
||||
p1 << ifm.p1;
|
||||
x << ifm.E;
|
||||
@@
|
||||
|
||||
msg="ERROR: %s is NULL but dereferenced." % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
cocci.print_main(msg_safe,p)
|
||||
cocci.include_match(False)
|
||||
|
||||
@s depends on !context && !patch && (org || report) exists@
|
||||
expression subE <= ifm.E;
|
||||
expression *ifm.E;
|
||||
expression E1,E2;
|
||||
identifier f;
|
||||
statement S1,S2,S3,S4;
|
||||
iterator iter;
|
||||
position p!={pr1.p1,pr2.p2};
|
||||
position ifm.p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...)
|
||||
{
|
||||
... when != if (...) S1 else S2
|
||||
(
|
||||
iter(subE,...) S4 // no use
|
||||
|
|
||||
list_remove_head(E2,subE,...)
|
||||
|
|
||||
subE = E1
|
||||
|
|
||||
for(subE = E1;...;...) S4
|
||||
|
|
||||
subE++
|
||||
|
|
||||
++subE
|
||||
|
|
||||
--subE
|
||||
|
|
||||
subE--
|
||||
|
|
||||
&subE
|
||||
|
|
||||
E->f@p // bad use
|
||||
)
|
||||
... when any
|
||||
}
|
||||
else S3
|
||||
|
||||
@script:python depends on !context && !patch && !org && report@
|
||||
p << s.p;
|
||||
p1 << ifm.p1;
|
||||
x << ifm.E;
|
||||
@@
|
||||
|
||||
msg="ERROR: %s is NULL but dereferenced." % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
|
||||
@script:python depends on !context && !patch && org && !report@
|
||||
p << s.p;
|
||||
p1 << ifm.p1;
|
||||
x << ifm.E;
|
||||
@@
|
||||
|
||||
msg="ERROR: %s is NULL but dereferenced." % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
cocci.print_main(msg_safe,p)
|
||||
|
||||
// For context mode
|
||||
|
||||
@depends on context && !patch && !org && !report exists@
|
||||
expression subE <= ifm.E;
|
||||
expression *ifm.E;
|
||||
expression E1,E2;
|
||||
identifier f;
|
||||
statement S1,S2,S3,S4;
|
||||
iterator iter;
|
||||
position p!={pr1.p1,pr2.p2};
|
||||
position ifm.p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...)
|
||||
{
|
||||
... when != if (...) S1 else S2
|
||||
(
|
||||
iter(subE,...) S4 // no use
|
||||
|
|
||||
list_remove_head(E2,subE,...)
|
||||
|
|
||||
subE = E1
|
||||
|
|
||||
for(subE = E1;...;...) S4
|
||||
|
|
||||
subE++
|
||||
|
|
||||
++subE
|
||||
|
|
||||
--subE
|
||||
|
|
||||
subE--
|
||||
|
|
||||
&subE
|
||||
|
|
||||
* E->f@p // bad use
|
||||
)
|
||||
... when any
|
||||
return ...;
|
||||
}
|
||||
else S3
|
||||
|
||||
// The following three rules are duplicates of ifm, pr1 and pr2 respectively.
|
||||
// It is need because the previous rule as already made a "change".
|
||||
|
||||
@ifm1 depends on !patch@
|
||||
expression *E;
|
||||
statement S1,S2;
|
||||
position p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...) S1 else S2
|
||||
|
||||
@pr11 depends on !patch expression@
|
||||
expression *ifm1.E;
|
||||
identifier f;
|
||||
position p1;
|
||||
@@
|
||||
|
||||
(E != NULL && ...) ? <+...E->f@p1...+> : ...
|
||||
|
||||
@pr12 depends on !patch expression@
|
||||
expression *ifm1.E;
|
||||
identifier f;
|
||||
position p2;
|
||||
@@
|
||||
|
||||
(
|
||||
(E != NULL) && ... && <+...E->f@p2...+>
|
||||
|
|
||||
(E == NULL) || ... || <+...E->f@p2...+>
|
||||
|
|
||||
sizeof(<+...E->f@p2...+>)
|
||||
)
|
||||
|
||||
@depends on context && !patch && !org && !report exists@
|
||||
expression subE <= ifm1.E;
|
||||
expression *ifm1.E;
|
||||
expression E1,E2;
|
||||
identifier f;
|
||||
statement S1,S2,S3,S4;
|
||||
iterator iter;
|
||||
position p!={pr11.p1,pr12.p2};
|
||||
position ifm1.p1;
|
||||
@@
|
||||
|
||||
if@p1 ((E == NULL && ...) || ...)
|
||||
{
|
||||
... when != if (...) S1 else S2
|
||||
(
|
||||
iter(subE,...) S4 // no use
|
||||
|
|
||||
list_remove_head(E2,subE,...)
|
||||
|
|
||||
subE = E1
|
||||
|
|
||||
for(subE = E1;...;...) S4
|
||||
|
|
||||
subE++
|
||||
|
|
||||
++subE
|
||||
|
|
||||
--subE
|
||||
|
|
||||
subE--
|
||||
|
|
||||
&subE
|
||||
|
|
||||
* E->f@p // bad use
|
||||
)
|
||||
... when any
|
||||
}
|
||||
else S3
|
||||
@@ -0,0 +1,56 @@
|
||||
///
|
||||
/// Use ERR_CAST inlined function instead of ERR_PTR(PTR_ERR(...))
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Options:
|
||||
//
|
||||
// Keywords: ERR_PTR, PTR_ERR, ERR_CAST
|
||||
// Version min: 2.6.25
|
||||
//
|
||||
|
||||
virtual context
|
||||
virtual patch
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
|
||||
@ depends on context && !patch && !org && !report@
|
||||
expression x;
|
||||
@@
|
||||
|
||||
* ERR_PTR(PTR_ERR(x))
|
||||
|
||||
@ depends on !context && patch && !org && !report @
|
||||
expression x;
|
||||
@@
|
||||
|
||||
- ERR_PTR(PTR_ERR(x))
|
||||
+ ERR_CAST(x)
|
||||
|
||||
@r depends on !context && !patch && (org || report)@
|
||||
expression x;
|
||||
position p;
|
||||
@@
|
||||
|
||||
ERR_PTR@p(PTR_ERR(x))
|
||||
|
||||
@script:python depends on org@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
|
||||
msg="WARNING ERR_CAST can be used with %s" % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
coccilib.org.print_todo(p[0], msg_safe)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r.p;
|
||||
x << r.x;
|
||||
@@
|
||||
|
||||
msg="WARNING: ERR_CAST can be used with %s" % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
@@ -0,0 +1,93 @@
|
||||
///
|
||||
/// Use resource_size function on resource object
|
||||
/// instead of explicit computation.
|
||||
///
|
||||
// Confidence: High
|
||||
// Copyright: (C) 2009, 2010 Nicolas Palix, DIKU. GPLv2.
|
||||
// Copyright: (C) 2009, 2010 Julia Lawall, DIKU. GPLv2.
|
||||
// Copyright: (C) 2009, 2010 Gilles Muller, INRIA/LiP6. GPLv2.
|
||||
// URL: http://coccinelle.lip6.fr/
|
||||
// Options:
|
||||
//
|
||||
// Keywords: resource_size
|
||||
// Version min: 2.6.27 resource_size
|
||||
//
|
||||
|
||||
virtual context
|
||||
virtual patch
|
||||
virtual org
|
||||
virtual report
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For context mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@r_context depends on context && !patch && !org@
|
||||
struct resource *res;
|
||||
@@
|
||||
|
||||
* (res->end - res->start) + 1
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For patch mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
@r_patch depends on !context && patch && !org@
|
||||
struct resource *res;
|
||||
@@
|
||||
|
||||
- (res->end - res->start) + 1
|
||||
+ resource_size(res)
|
||||
|
||||
//----------------------------------------------------------
|
||||
// For org mode
|
||||
//----------------------------------------------------------
|
||||
|
||||
|
||||
@r_org depends on !context && !patch && (org || report)@
|
||||
struct resource *res;
|
||||
position p;
|
||||
@@
|
||||
|
||||
(res->end@p - res->start) + 1
|
||||
|
||||
@rbad_org depends on !context && !patch && (org || report)@
|
||||
struct resource *res;
|
||||
position p != r_org.p;
|
||||
@@
|
||||
|
||||
res->end@p - res->start
|
||||
|
||||
@script:python depends on org@
|
||||
p << r_org.p;
|
||||
x << r_org.res;
|
||||
@@
|
||||
|
||||
msg="ERROR with %s" % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
coccilib.org.print_todo(p[0], msg_safe)
|
||||
|
||||
@script:python depends on report@
|
||||
p << r_org.p;
|
||||
x << r_org.res;
|
||||
@@
|
||||
|
||||
msg="ERROR: Missing resource_size with %s" % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
|
||||
@script:python depends on org@
|
||||
p << rbad_org.p;
|
||||
x << rbad_org.res;
|
||||
@@
|
||||
|
||||
msg="WARNING with %s" % (x)
|
||||
msg_safe=msg.replace("[","@(").replace("]",")")
|
||||
coccilib.org.print_todo(p[0], msg_safe)
|
||||
|
||||
@script:python depends on report@
|
||||
p << rbad_org.p;
|
||||
x << rbad_org.res;
|
||||
@@
|
||||
|
||||
msg="WARNING: Suspicious code. resource_size is maybe missing with %s" % (x)
|
||||
coccilib.report.print_report(p[0], msg)
|
||||
+5
-5
@@ -40,7 +40,7 @@ echo $code
|
||||
code=`echo $code | sed -e 's/.*Code: //'`
|
||||
|
||||
width=`expr index "$code" ' '`
|
||||
width=$[($width-1)/2]
|
||||
width=$((($width-1)/2))
|
||||
case $width in
|
||||
1) type=byte ;;
|
||||
2) type=2byte ;;
|
||||
@@ -48,10 +48,10 @@ case $width in
|
||||
esac
|
||||
|
||||
disas() {
|
||||
${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s &> /dev/null
|
||||
${CROSS_COMPILE}as $AFLAGS -o $1.o $1.s > /dev/null 2>&1
|
||||
|
||||
if [ "$ARCH" == "arm" ]; then
|
||||
if [ $width == 2 ]; then
|
||||
if [ "$ARCH" = "arm" ]; then
|
||||
if [ $width -eq 2 ]; then
|
||||
OBJDUMPFLAGS="-M force-thumb"
|
||||
fi
|
||||
|
||||
@@ -59,7 +59,7 @@ disas() {
|
||||
fi
|
||||
|
||||
${CROSS_COMPILE}objdump $OBJDUMPFLAGS -S $1.o | \
|
||||
grep -v "/tmp\|Disassembly\|\.text\|^$" &> $1.dis
|
||||
grep -v "/tmp\|Disassembly\|\.text\|^$" > $1.dis 2>&1
|
||||
}
|
||||
|
||||
marker=`expr index "$code" "\<"`
|
||||
|
||||
@@ -77,6 +77,7 @@ static struct node *read_fstree(const char *dirname)
|
||||
free(tmpnam);
|
||||
}
|
||||
|
||||
closedir(d);
|
||||
return tree;
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ gconf.glade.h
|
||||
#
|
||||
conf
|
||||
mconf
|
||||
nconf
|
||||
qconf
|
||||
gconf
|
||||
kxgettext
|
||||
|
||||
@@ -599,12 +599,12 @@ int main(int ac, char **av)
|
||||
break;
|
||||
case savedefconfig:
|
||||
break;
|
||||
case oldconfig:
|
||||
case oldaskconfig:
|
||||
rootEntry = &rootmenu;
|
||||
conf(&rootmenu);
|
||||
input_mode = silentoldconfig;
|
||||
/* fall through */
|
||||
case oldconfig:
|
||||
case listnewconfig:
|
||||
case oldnoconfig:
|
||||
case silentoldconfig:
|
||||
|
||||
@@ -1454,6 +1454,8 @@ sub dump_enum($$) {
|
||||
my $file = shift;
|
||||
|
||||
$x =~ s@/\*.*?\*/@@gos; # strip comments.
|
||||
$x =~ s/^#\s*define\s+.*$//; # strip #define macros inside enums
|
||||
|
||||
if ($x =~ /enum\s+(\w+)\s*{(.*)}/) {
|
||||
$declaration_name = $1;
|
||||
my $members = $2;
|
||||
|
||||
@@ -884,16 +884,16 @@ void handle_moddevtable(struct module *mod, struct elf_info *info,
|
||||
char *zeros = NULL;
|
||||
|
||||
/* We're looking for a section relative symbol */
|
||||
if (!sym->st_shndx || sym->st_shndx >= info->hdr->e_shnum)
|
||||
if (!sym->st_shndx || get_secindex(info, sym) >= info->num_sections)
|
||||
return;
|
||||
|
||||
/* Handle all-NULL symbols allocated into .bss */
|
||||
if (info->sechdrs[sym->st_shndx].sh_type & SHT_NOBITS) {
|
||||
if (info->sechdrs[get_secindex(info, sym)].sh_type & SHT_NOBITS) {
|
||||
zeros = calloc(1, sym->st_size);
|
||||
symval = zeros;
|
||||
} else {
|
||||
symval = (void *)info->hdr
|
||||
+ info->sechdrs[sym->st_shndx].sh_offset
|
||||
+ info->sechdrs[get_secindex(info, sym)].sh_offset
|
||||
+ sym->st_value;
|
||||
}
|
||||
|
||||
|
||||
+133
-42
@@ -14,6 +14,7 @@
|
||||
#define _GNU_SOURCE
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include "modpost.h"
|
||||
#include "../../include/generated/autoconf.h"
|
||||
#include "../../include/linux/license.h"
|
||||
@@ -253,7 +254,7 @@ static enum export export_no(const char *s)
|
||||
return export_unknown;
|
||||
}
|
||||
|
||||
static enum export export_from_sec(struct elf_info *elf, Elf_Section sec)
|
||||
static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
|
||||
{
|
||||
if (sec == elf->export_sec)
|
||||
return export_plain;
|
||||
@@ -373,6 +374,8 @@ static int parse_elf(struct elf_info *info, const char *filename)
|
||||
Elf_Ehdr *hdr;
|
||||
Elf_Shdr *sechdrs;
|
||||
Elf_Sym *sym;
|
||||
const char *secstrings;
|
||||
unsigned int symtab_idx = ~0U, symtab_shndx_idx = ~0U;
|
||||
|
||||
hdr = grab_file(filename, &info->size);
|
||||
if (!hdr) {
|
||||
@@ -417,8 +420,27 @@ static int parse_elf(struct elf_info *info, const char *filename)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (hdr->e_shnum == 0) {
|
||||
/*
|
||||
* There are more than 64k sections,
|
||||
* read count from .sh_size.
|
||||
* note: it doesn't need shndx2secindex()
|
||||
*/
|
||||
info->num_sections = TO_NATIVE(sechdrs[0].sh_size);
|
||||
}
|
||||
else {
|
||||
info->num_sections = hdr->e_shnum;
|
||||
}
|
||||
if (hdr->e_shstrndx == SHN_XINDEX) {
|
||||
info->secindex_strings =
|
||||
shndx2secindex(TO_NATIVE(sechdrs[0].sh_link));
|
||||
}
|
||||
else {
|
||||
info->secindex_strings = hdr->e_shstrndx;
|
||||
}
|
||||
|
||||
/* Fix endianness in section headers */
|
||||
for (i = 0; i < hdr->e_shnum; i++) {
|
||||
for (i = 0; i < info->num_sections; i++) {
|
||||
sechdrs[i].sh_name = TO_NATIVE(sechdrs[i].sh_name);
|
||||
sechdrs[i].sh_type = TO_NATIVE(sechdrs[i].sh_type);
|
||||
sechdrs[i].sh_flags = TO_NATIVE(sechdrs[i].sh_flags);
|
||||
@@ -431,9 +453,8 @@ static int parse_elf(struct elf_info *info, const char *filename)
|
||||
sechdrs[i].sh_entsize = TO_NATIVE(sechdrs[i].sh_entsize);
|
||||
}
|
||||
/* Find symbol table. */
|
||||
for (i = 1; i < hdr->e_shnum; i++) {
|
||||
const char *secstrings
|
||||
= (void *)hdr + sechdrs[hdr->e_shstrndx].sh_offset;
|
||||
secstrings = (void *)hdr + sechdrs[info->secindex_strings].sh_offset;
|
||||
for (i = 1; i < info->num_sections; i++) {
|
||||
const char *secname;
|
||||
int nobits = sechdrs[i].sh_type == SHT_NOBITS;
|
||||
|
||||
@@ -461,14 +482,26 @@ static int parse_elf(struct elf_info *info, const char *filename)
|
||||
else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
|
||||
info->export_gpl_future_sec = i;
|
||||
|
||||
if (sechdrs[i].sh_type != SHT_SYMTAB)
|
||||
continue;
|
||||
if (sechdrs[i].sh_type == SHT_SYMTAB) {
|
||||
unsigned int sh_link_idx;
|
||||
symtab_idx = i;
|
||||
info->symtab_start = (void *)hdr +
|
||||
sechdrs[i].sh_offset;
|
||||
info->symtab_stop = (void *)hdr +
|
||||
sechdrs[i].sh_offset + sechdrs[i].sh_size;
|
||||
sh_link_idx = shndx2secindex(sechdrs[i].sh_link);
|
||||
info->strtab = (void *)hdr +
|
||||
sechdrs[sh_link_idx].sh_offset;
|
||||
}
|
||||
|
||||
info->symtab_start = (void *)hdr + sechdrs[i].sh_offset;
|
||||
info->symtab_stop = (void *)hdr + sechdrs[i].sh_offset
|
||||
+ sechdrs[i].sh_size;
|
||||
info->strtab = (void *)hdr +
|
||||
sechdrs[sechdrs[i].sh_link].sh_offset;
|
||||
/* 32bit section no. table? ("more than 64k sections") */
|
||||
if (sechdrs[i].sh_type == SHT_SYMTAB_SHNDX) {
|
||||
symtab_shndx_idx = i;
|
||||
info->symtab_shndx_start = (void *)hdr +
|
||||
sechdrs[i].sh_offset;
|
||||
info->symtab_shndx_stop = (void *)hdr +
|
||||
sechdrs[i].sh_offset + sechdrs[i].sh_size;
|
||||
}
|
||||
}
|
||||
if (!info->symtab_start)
|
||||
fatal("%s has no symtab?\n", filename);
|
||||
@@ -480,6 +513,21 @@ static int parse_elf(struct elf_info *info, const char *filename)
|
||||
sym->st_value = TO_NATIVE(sym->st_value);
|
||||
sym->st_size = TO_NATIVE(sym->st_size);
|
||||
}
|
||||
|
||||
if (symtab_shndx_idx != ~0U) {
|
||||
Elf32_Word *p;
|
||||
if (symtab_idx !=
|
||||
shndx2secindex(sechdrs[symtab_shndx_idx].sh_link))
|
||||
fatal("%s: SYMTAB_SHNDX has bad sh_link: %u!=%u\n",
|
||||
filename,
|
||||
shndx2secindex(sechdrs[symtab_shndx_idx].sh_link),
|
||||
symtab_idx);
|
||||
/* Fix endianness */
|
||||
for (p = info->symtab_shndx_start; p < info->symtab_shndx_stop;
|
||||
p++)
|
||||
*p = TO_NATIVE(*p);
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -519,7 +567,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
|
||||
Elf_Sym *sym, const char *symname)
|
||||
{
|
||||
unsigned int crc;
|
||||
enum export export = export_from_sec(info, sym->st_shndx);
|
||||
enum export export = export_from_sec(info, get_secindex(info, sym));
|
||||
|
||||
switch (sym->st_shndx) {
|
||||
case SHN_COMMON:
|
||||
@@ -661,19 +709,19 @@ static const char *sym_name(struct elf_info *elf, Elf_Sym *sym)
|
||||
return "(unknown)";
|
||||
}
|
||||
|
||||
static const char *sec_name(struct elf_info *elf, int shndx)
|
||||
static const char *sec_name(struct elf_info *elf, int secindex)
|
||||
{
|
||||
Elf_Shdr *sechdrs = elf->sechdrs;
|
||||
return (void *)elf->hdr +
|
||||
elf->sechdrs[elf->hdr->e_shstrndx].sh_offset +
|
||||
sechdrs[shndx].sh_name;
|
||||
elf->sechdrs[elf->secindex_strings].sh_offset +
|
||||
sechdrs[secindex].sh_name;
|
||||
}
|
||||
|
||||
static const char *sech_name(struct elf_info *elf, Elf_Shdr *sechdr)
|
||||
{
|
||||
return (void *)elf->hdr +
|
||||
elf->sechdrs[elf->hdr->e_shstrndx].sh_offset +
|
||||
sechdr->sh_name;
|
||||
elf->sechdrs[elf->secindex_strings].sh_offset +
|
||||
sechdr->sh_name;
|
||||
}
|
||||
|
||||
/* if sym is empty or point to a string
|
||||
@@ -742,6 +790,7 @@ static const char *section_white_list[] =
|
||||
{
|
||||
".comment*",
|
||||
".debug*",
|
||||
".GCC-command-line", /* mn10300 */
|
||||
".mdebug*", /* alpha, score, mips etc. */
|
||||
".pdr", /* alpha, score, mips etc. */
|
||||
".stab*",
|
||||
@@ -986,6 +1035,13 @@ static const struct sectioncheck *section_mismatch(
|
||||
* fromsec = .data*
|
||||
* atsym =__param*
|
||||
*
|
||||
* Pattern 1a:
|
||||
* module_param_call() ops can refer to __init set function if permissions=0
|
||||
* The pattern is identified by:
|
||||
* tosec = .init.text
|
||||
* fromsec = .data*
|
||||
* atsym = __param_ops_*
|
||||
*
|
||||
* Pattern 2:
|
||||
* Many drivers utilise a *driver container with references to
|
||||
* add, remove, probe functions etc.
|
||||
@@ -1020,6 +1076,12 @@ static int secref_whitelist(const struct sectioncheck *mismatch,
|
||||
(strncmp(fromsym, "__param", strlen("__param")) == 0))
|
||||
return 0;
|
||||
|
||||
/* Check for pattern 1a */
|
||||
if (strcmp(tosec, ".init.text") == 0 &&
|
||||
match(fromsec, data_sections) &&
|
||||
(strncmp(fromsym, "__param_ops_", strlen("__param_ops_")) == 0))
|
||||
return 0;
|
||||
|
||||
/* Check for pattern 2 */
|
||||
if (match(tosec, init_exit_sections) &&
|
||||
match(fromsec, data_sections) &&
|
||||
@@ -1052,11 +1114,14 @@ static Elf_Sym *find_elf_symbol(struct elf_info *elf, Elf64_Sword addr,
|
||||
Elf_Sym *near = NULL;
|
||||
Elf64_Sword distance = 20;
|
||||
Elf64_Sword d;
|
||||
unsigned int relsym_secindex;
|
||||
|
||||
if (relsym->st_name != 0)
|
||||
return relsym;
|
||||
|
||||
relsym_secindex = get_secindex(elf, relsym);
|
||||
for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
|
||||
if (sym->st_shndx != relsym->st_shndx)
|
||||
if (get_secindex(elf, sym) != relsym_secindex)
|
||||
continue;
|
||||
if (ELF_ST_TYPE(sym->st_info) == STT_SECTION)
|
||||
continue;
|
||||
@@ -1118,9 +1183,9 @@ static Elf_Sym *find_elf_symbol2(struct elf_info *elf, Elf_Addr addr,
|
||||
for (sym = elf->symtab_start; sym < elf->symtab_stop; sym++) {
|
||||
const char *symsec;
|
||||
|
||||
if (sym->st_shndx >= SHN_LORESERVE)
|
||||
if (is_shndx_special(sym->st_shndx))
|
||||
continue;
|
||||
symsec = sec_name(elf, sym->st_shndx);
|
||||
symsec = sec_name(elf, get_secindex(elf, sym));
|
||||
if (strcmp(symsec, sec) != 0)
|
||||
continue;
|
||||
if (!is_valid_name(elf, sym))
|
||||
@@ -1167,7 +1232,7 @@ static char *sec2annotation(const char *s)
|
||||
strcat(p, " ");
|
||||
return r; /* we leak her but we do not care */
|
||||
} else {
|
||||
return "";
|
||||
return strdup("");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1195,6 +1260,8 @@ static void report_sec_mismatch(const char *modname,
|
||||
{
|
||||
const char *from, *from_p;
|
||||
const char *to, *to_p;
|
||||
char *prl_from;
|
||||
char *prl_to;
|
||||
|
||||
switch (from_is_func) {
|
||||
case 0: from = "variable"; from_p = ""; break;
|
||||
@@ -1218,16 +1285,21 @@ static void report_sec_mismatch(const char *modname,
|
||||
|
||||
switch (mismatch->mismatch) {
|
||||
case TEXT_TO_ANY_INIT:
|
||||
prl_from = sec2annotation(fromsec);
|
||||
prl_to = sec2annotation(tosec);
|
||||
fprintf(stderr,
|
||||
"The function %s%s() references\n"
|
||||
"the %s %s%s%s.\n"
|
||||
"This is often because %s lacks a %s\n"
|
||||
"annotation or the annotation of %s is wrong.\n",
|
||||
sec2annotation(fromsec), fromsym,
|
||||
to, sec2annotation(tosec), tosym, to_p,
|
||||
fromsym, sec2annotation(tosec), tosym);
|
||||
prl_from, fromsym,
|
||||
to, prl_to, tosym, to_p,
|
||||
fromsym, prl_to, tosym);
|
||||
free(prl_from);
|
||||
free(prl_to);
|
||||
break;
|
||||
case DATA_TO_ANY_INIT: {
|
||||
prl_to = sec2annotation(tosec);
|
||||
const char *const *s = mismatch->symbol_white_list;
|
||||
fprintf(stderr,
|
||||
"The variable %s references\n"
|
||||
@@ -1235,20 +1307,24 @@ static void report_sec_mismatch(const char *modname,
|
||||
"If the reference is valid then annotate the\n"
|
||||
"variable with __init* or __refdata (see linux/init.h) "
|
||||
"or name the variable:\n",
|
||||
fromsym, to, sec2annotation(tosec), tosym, to_p);
|
||||
fromsym, to, prl_to, tosym, to_p);
|
||||
while (*s)
|
||||
fprintf(stderr, "%s, ", *s++);
|
||||
fprintf(stderr, "\n");
|
||||
free(prl_to);
|
||||
break;
|
||||
}
|
||||
case TEXT_TO_ANY_EXIT:
|
||||
prl_to = sec2annotation(tosec);
|
||||
fprintf(stderr,
|
||||
"The function %s() references a %s in an exit section.\n"
|
||||
"Often the %s %s%s has valid usage outside the exit section\n"
|
||||
"and the fix is to remove the %sannotation of %s.\n",
|
||||
fromsym, to, to, tosym, to_p, sec2annotation(tosec), tosym);
|
||||
fromsym, to, to, tosym, to_p, prl_to, tosym);
|
||||
free(prl_to);
|
||||
break;
|
||||
case DATA_TO_ANY_EXIT: {
|
||||
prl_to = sec2annotation(tosec);
|
||||
const char *const *s = mismatch->symbol_white_list;
|
||||
fprintf(stderr,
|
||||
"The variable %s references\n"
|
||||
@@ -1256,24 +1332,31 @@ static void report_sec_mismatch(const char *modname,
|
||||
"If the reference is valid then annotate the\n"
|
||||
"variable with __exit* (see linux/init.h) or "
|
||||
"name the variable:\n",
|
||||
fromsym, to, sec2annotation(tosec), tosym, to_p);
|
||||
fromsym, to, prl_to, tosym, to_p);
|
||||
while (*s)
|
||||
fprintf(stderr, "%s, ", *s++);
|
||||
fprintf(stderr, "\n");
|
||||
free(prl_to);
|
||||
break;
|
||||
}
|
||||
case XXXINIT_TO_SOME_INIT:
|
||||
case XXXEXIT_TO_SOME_EXIT:
|
||||
prl_from = sec2annotation(fromsec);
|
||||
prl_to = sec2annotation(tosec);
|
||||
fprintf(stderr,
|
||||
"The %s %s%s%s references\n"
|
||||
"a %s %s%s%s.\n"
|
||||
"If %s is only used by %s then\n"
|
||||
"annotate %s with a matching annotation.\n",
|
||||
from, sec2annotation(fromsec), fromsym, from_p,
|
||||
to, sec2annotation(tosec), tosym, to_p,
|
||||
from, prl_from, fromsym, from_p,
|
||||
to, prl_to, tosym, to_p,
|
||||
tosym, fromsym, tosym);
|
||||
free(prl_from);
|
||||
free(prl_to);
|
||||
break;
|
||||
case ANY_INIT_TO_ANY_EXIT:
|
||||
prl_from = sec2annotation(fromsec);
|
||||
prl_to = sec2annotation(tosec);
|
||||
fprintf(stderr,
|
||||
"The %s %s%s%s references\n"
|
||||
"a %s %s%s%s.\n"
|
||||
@@ -1282,11 +1365,15 @@ static void report_sec_mismatch(const char *modname,
|
||||
"uses functionality in the exit path.\n"
|
||||
"The fix is often to remove the %sannotation of\n"
|
||||
"%s%s so it may be used outside an exit section.\n",
|
||||
from, sec2annotation(fromsec), fromsym, from_p,
|
||||
to, sec2annotation(tosec), tosym, to_p,
|
||||
sec2annotation(tosec), tosym, to_p);
|
||||
from, prl_from, fromsym, from_p,
|
||||
to, prl_to, tosym, to_p,
|
||||
prl_to, tosym, to_p);
|
||||
free(prl_from);
|
||||
free(prl_to);
|
||||
break;
|
||||
case ANY_EXIT_TO_ANY_INIT:
|
||||
prl_from = sec2annotation(fromsec);
|
||||
prl_to = sec2annotation(tosec);
|
||||
fprintf(stderr,
|
||||
"The %s %s%s%s references\n"
|
||||
"a %s %s%s%s.\n"
|
||||
@@ -1295,16 +1382,20 @@ static void report_sec_mismatch(const char *modname,
|
||||
"uses functionality in the init path.\n"
|
||||
"The fix is often to remove the %sannotation of\n"
|
||||
"%s%s so it may be used outside an init section.\n",
|
||||
from, sec2annotation(fromsec), fromsym, from_p,
|
||||
to, sec2annotation(tosec), tosym, to_p,
|
||||
sec2annotation(tosec), tosym, to_p);
|
||||
from, prl_from, fromsym, from_p,
|
||||
to, prl_to, tosym, to_p,
|
||||
prl_to, tosym, to_p);
|
||||
free(prl_from);
|
||||
free(prl_to);
|
||||
break;
|
||||
case EXPORT_TO_INIT_EXIT:
|
||||
prl_to = sec2annotation(tosec);
|
||||
fprintf(stderr,
|
||||
"The symbol %s is exported and annotated %s\n"
|
||||
"Fix this by removing the %sannotation of %s "
|
||||
"or drop the export.\n",
|
||||
tosym, sec2annotation(tosec), sec2annotation(tosec), tosym);
|
||||
tosym, prl_to, prl_to, tosym);
|
||||
free(prl_to);
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
@@ -1316,7 +1407,7 @@ static void check_section_mismatch(const char *modname, struct elf_info *elf,
|
||||
const char *tosec;
|
||||
const struct sectioncheck *mismatch;
|
||||
|
||||
tosec = sec_name(elf, sym->st_shndx);
|
||||
tosec = sec_name(elf, get_secindex(elf, sym));
|
||||
mismatch = section_mismatch(fromsec, tosec);
|
||||
if (mismatch) {
|
||||
Elf_Sym *to;
|
||||
@@ -1344,7 +1435,7 @@ static unsigned int *reloc_location(struct elf_info *elf,
|
||||
Elf_Shdr *sechdr, Elf_Rela *r)
|
||||
{
|
||||
Elf_Shdr *sechdrs = elf->sechdrs;
|
||||
int section = sechdr->sh_info;
|
||||
int section = shndx2secindex(sechdr->sh_info);
|
||||
|
||||
return (void *)elf->hdr + sechdrs[section].sh_offset +
|
||||
r->r_offset - sechdrs[section].sh_addr;
|
||||
@@ -1452,7 +1543,7 @@ static void section_rela(const char *modname, struct elf_info *elf,
|
||||
r.r_addend = TO_NATIVE(rela->r_addend);
|
||||
sym = elf->symtab_start + r_sym;
|
||||
/* Skip special sections */
|
||||
if (sym->st_shndx >= SHN_LORESERVE)
|
||||
if (is_shndx_special(sym->st_shndx))
|
||||
continue;
|
||||
check_section_mismatch(modname, elf, &r, sym, fromsec);
|
||||
}
|
||||
@@ -1510,7 +1601,7 @@ static void section_rel(const char *modname, struct elf_info *elf,
|
||||
}
|
||||
sym = elf->symtab_start + r_sym;
|
||||
/* Skip special sections */
|
||||
if (sym->st_shndx >= SHN_LORESERVE)
|
||||
if (is_shndx_special(sym->st_shndx))
|
||||
continue;
|
||||
check_section_mismatch(modname, elf, &r, sym, fromsec);
|
||||
}
|
||||
@@ -1535,7 +1626,7 @@ static void check_sec_ref(struct module *mod, const char *modname,
|
||||
Elf_Shdr *sechdrs = elf->sechdrs;
|
||||
|
||||
/* Walk through all sections */
|
||||
for (i = 0; i < elf->hdr->e_shnum; i++) {
|
||||
for (i = 0; i < elf->num_sections; i++) {
|
||||
check_section(modname, elf, &elf->sechdrs[i]);
|
||||
/* We want to process only relocation sections and not .init */
|
||||
if (sechdrs[i].sh_type == SHT_RELA)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user