From bcfe020ed939fa1e8474efaf31a86d80d0e5c5fe Mon Sep 17 00:00:00 2001 From: Luc Van Oostenryck Date: Thu, 25 May 2017 15:51:35 +0200 Subject: [PATCH] add support for -fmemcpy-max-count By default, sparse will warn if memcpy() (or memset(), copy_from_user(), copy_to_user()) is called with a very large static byte-count. But the limit is currently fixed at 100000, which may be fine for some uses but not for others. For example, this value is too low for sparse to be used on the git tree where, for example, some array used to sort the index is cleared with memset(). Change this by making the limit configurable via a new flag: -fmemcpy-max-count. Signed-off-by: Luc Van Oostenryck --- cgcc | 2 +- lib.c | 18 ++++++++++++++++++ lib.h | 1 + sparse.1 | 9 +++++++++ sparse.c | 3 +-- 5 files changed, 30 insertions(+), 3 deletions(-) diff --git a/cgcc b/cgcc index b7bad803..fd9d482f 100755 --- a/cgcc +++ b/cgcc @@ -103,7 +103,7 @@ sub check_only_option { my ($arg) = @_; return 1 if $arg =~ /^-W(no-?)?(address-space|bitwise|cast-to-as|cast-truncate|context|decl|default-bitfield-sign|designated-init|do-while|enum-mismatch|init-cstring|memcpy-max-count|non-pointer-null|old-initializer|one-bit-signed-bitfield|override-init-all|paren-string|ptr-subtraction-blows|return-void|sizeof-bool|sparse-all|sparse-error|transparent-union|typesign|undef|unknown-attribute)$/; return 1 if $arg =~ /^-v(no-?)?(entry|dead)$/; - return 1 if $arg =~ /^-f(dump-linearize)(=\S*)?$/; + return 1 if $arg =~ /^-f(dump-linearize|memcpy-max-count)(=\S*)?$/; return 0; } diff --git a/lib.c b/lib.c index 8bee1bfd..eac84ee3 100644 --- a/lib.c +++ b/lib.c @@ -257,6 +257,7 @@ int dbg_dead = 0; int fmem_report = 0; int fdump_linearize; +unsigned long long fmemcpy_max_count = 100000; int preprocess_only; @@ -671,6 +672,21 @@ static char **handle_switch_O(char *arg, char **next) return next; } +static char **handle_switch_fmemcpy_max_count(char *arg, char **next) +{ + unsigned long long val; + char *end; + + val = strtoull(arg, &end, 0); + if (*end != '\0' || end == arg) + die("error: missing argument to \"-fmemcpy-max-count=\""); + + if (val == 0) + val = ~0ULL; + fmemcpy_max_count = val; + return next; +} + static char **handle_switch_ftabstop(char *arg, char **next) { char *end; @@ -714,6 +730,8 @@ static char **handle_switch_f(char *arg, char **next) return handle_switch_ftabstop(arg+8, next); if (!strncmp(arg, "dump-", 5)) return handle_switch_fdump(arg+5, next); + if (!strncmp(arg, "memcpy-max-count=", 17)) + return handle_switch_fmemcpy_max_count(arg+17, next); /* handle switches w/ arguments above, boolean and only boolean below */ if (handle_simple_switch(arg, "mem-report", &fmem_report)) diff --git a/lib.h b/lib.h index da5307f7..e09f47f1 100644 --- a/lib.h +++ b/lib.h @@ -147,6 +147,7 @@ extern int dbg_dead; extern int fmem_report; extern int fdump_linearize; +extern unsigned long long fmemcpy_max_count; extern int arch_m64; diff --git a/sparse.1 b/sparse.1 index df3c7f44..b79c5876 100644 --- a/sparse.1 +++ b/sparse.1 @@ -216,6 +216,9 @@ Warn about call of \fBmemcpy()\fR, \fBmemset()\fR, \fBcopy_from_user()\fR, or Sparse issues these warnings by default. To turn them off, use \fB\-Wno\-memcpy\-max\-count\fR. + +The limit can be changed with \fB\-fmemcpy\-max\-count=COUNT\fR, +the default being \fB100000\fR. . .TP .B \-Wnon\-pointer\-null @@ -364,6 +367,12 @@ Report some statistics about memory allocation used by the tool. . .SH OTHER OPTIONS .TP +.B \-fmemcpy-max-count=COUNT +Set the limit for the warnings given by \fB-Wmemcpy-max-count\fR. +A COUNT of 0, useless in itself, will effectively disable the warning. +The default limit is 100000. +. +.TP .B \-ftabstop=WIDTH Set the distance between tab stops. This helps sparse report correct column numbers in warnings or errors. If the value is less than 1 or diff --git a/sparse.c b/sparse.c index aa5979f1..bceacd94 100644 --- a/sparse.c +++ b/sparse.c @@ -153,8 +153,7 @@ static void check_byte_count(struct instruction *insn, pseudo_t count) return; if (count->type == PSEUDO_VAL) { unsigned long long val = count->value; - if (Wmemcpy_max_count && val > 100000ULL) - + if (Wmemcpy_max_count && val > fmemcpy_max_count) warning(insn->pos, "%s with byte count of %llu", show_ident(insn->func->sym->ident), val); return; -- 2.11.4.GIT