All of lore.kernel.org
 help / color / mirror / Atom feed
From: Richard Palethorpe <rpalethorpe@suse.com>
To: ltp@lists.linux.it
Subject: [LTP] [PATCH v2 1/8] Add Sparse based checker and TST_RET/ERR check
Date: Wed, 14 Jul 2021 08:11:51 +0100	[thread overview]
Message-ID: <20210714071158.15868-2-rpalethorpe@suse.com> (raw)
In-Reply-To: <20210714071158.15868-1-rpalethorpe@suse.com>

Vendors in Sparse as a git module. Then uses it to check for stores to
TST_RET/ERR within the library.

Signed-off-by: Richard Palethorpe <rpalethorpe@suse.com>
---
 .gitmodules             |   3 +
 tools/Makefile          |   2 +
 tools/sparse/.gitignore |   1 +
 tools/sparse/Makefile   |  27 ++++++++
 tools/sparse/README.md  |  38 +++++++++++
 tools/sparse/main.c     | 148 ++++++++++++++++++++++++++++++++++++++++
 tools/sparse/sparse-src |   1 +
 7 files changed, 220 insertions(+)
 create mode 100644 tools/sparse/.gitignore
 create mode 100644 tools/sparse/Makefile
 create mode 100644 tools/sparse/README.md
 create mode 100644 tools/sparse/main.c
 create mode 160000 tools/sparse/sparse-src

diff --git a/.gitmodules b/.gitmodules
index 1c9e9c38a..a3c34af4b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,6 @@
 [submodule "testcases/kernel/mce-test"]
 	path = testcases/kernel/mce-test
 	url = git://git.kernel.org/pub/scm/linux/kernel/git/gong.chen/mce-test.git
+[submodule "tools/sparse/sparse-src"]
+	path = tools/sparse/sparse-src
+	url = git://git.kernel.org/pub/scm/devel/sparse/sparse.git
diff --git a/tools/Makefile b/tools/Makefile
index def1c6fa9..adbf4fe70 100644
--- a/tools/Makefile
+++ b/tools/Makefile
@@ -28,4 +28,6 @@ INSTALL_TARGETS		:= *.awk *.pl *.sh html_report_header.txt
 
 INSTALL_DIR		:= bin
 
+FILTER_OUT_DIRS		+= sparse
+
 include $(top_srcdir)/include/mk/generic_trunk_target.mk
diff --git a/tools/sparse/.gitignore b/tools/sparse/.gitignore
new file mode 100644
index 000000000..ba2906d06
--- /dev/null
+++ b/tools/sparse/.gitignore
@@ -0,0 +1 @@
+main
diff --git a/tools/sparse/Makefile b/tools/sparse/Makefile
new file mode 100644
index 000000000..b2e608d59
--- /dev/null
+++ b/tools/sparse/Makefile
@@ -0,0 +1,27 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+# Copyright (c) 2021 SUSE LLC <rpalethorpe@suse.com>
+
+top_srcdir		?= ../..
+
+include $(top_srcdir)/include/mk/env_pre.mk
+include $(top_srcdir)/include/mk/functions.mk
+
+SPARSE_SRC	?= sparse-src
+
+$(SPARSE_SRC)/Makefile:
+ifeq ($(SPARSE_SRC),sparse-src)
+	git submodule update --init
+else
+	$(error "Can't find $(SPARSE_SRC)/Makefile")
+endif
+
+$(SPARSE_SRC)/libsparse.a: $(SPARSE_SRC)/Makefile
+	$(MAKE) -C $(SPARSE_SRC) libsparse.a
+
+HOST_MAKE_TARGETS	:= main
+MAKE_DEPS		+= $(SPARSE_SRC)/libsparse.a
+HOST_CFLAGS		+= -I$(SPARSE_SRC)
+HOST_LDLIBS		+= $(SPARSE_SRC)/libsparse.a
+
+
+include $(top_srcdir)/include/mk/generic_leaf_target.mk
diff --git a/tools/sparse/README.md b/tools/sparse/README.md
new file mode 100644
index 000000000..7c605d5ce
--- /dev/null
+++ b/tools/sparse/README.md
@@ -0,0 +1,38 @@
+# Sparse based linting
+
+This tool checks LTP test and library code for common problems.
+
+## Usage
+
+It is integrated with the LTP build system. Just run `make check` or
+`make check-a_test01`, where `a_test01` is an arbitrary test
+executable or object file.
+
+## Building
+
+The bad news is you must get and build Sparse[^1]. The good news is
+that this only takes a minute and the build system does it for
+you. Just try running `make check` as described above.
+
+However if you want to reuse an existing Sparse checkout. Then you can
+do the following. Where `$SRC_PATH` is the path to the Sparse
+directory.
+
+```sh
+$ cd tools/sparse
+$ make SPARSE_SRC=$SRC_PATH
+```
+You can also manually fetch it via the git submodule
+
+```sh
+$ cd tools/sparse
+$ git submodule update --init
+```
+
+### Clang
+
+Note that while it is possible to build Sparse with Clang. This may
+cause some issues. Namely `GCC_BASE` is set to the Clang resource
+directory. This contains some headers Sparse can not parse.
+
+[1]: Many distributions have a Sparse package. This only contains some executables. There is no shared library
diff --git a/tools/sparse/main.c b/tools/sparse/main.c
new file mode 100644
index 000000000..58f9a549c
--- /dev/null
+++ b/tools/sparse/main.c
@@ -0,0 +1,148 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+/*
+ * Copyright (C) 2021 SUSE LLC <rpalethorpe@suse.com>
+ *
+ * Sparse allows us to perform checks on the AST (struct symbol) or on
+ * a linearized representation. In the latter case we are given a set
+ * of entry points (functions) containing basic blocks of
+ * instructions.
+ *
+ * The basic blocks contain byte code in SSA form. This is similar to
+ * the the intermediate representation most compilers use during
+ * optimisation.
+ */
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "lib.h"
+#include "allocate.h"
+#include "opcode.h"
+#include "token.h"
+#include "parse.h"
+#include "symbol.h"
+#include "expression.h"
+#include "linearize.h"
+
+/* The rules for test, library and tool code are different */
+enum ltp_tu_kind {
+	LTP_LIB,
+	LTP_OTHER,
+};
+
+static enum ltp_tu_kind tu_kind = LTP_OTHER;
+
+/* Check for LTP-002
+ *
+ * Inspects the destination symbol of each store instruction. If it is
+ * TST_RET or TST_ERR then emit a warning.
+ */
+static void check_lib_sets_TEST_vars(const struct instruction *insn)
+{
+	static struct ident *TST_RES_id, *TST_ERR_id;
+
+	if (!TST_RES_id) {
+		TST_RES_id = built_in_ident("TST_RET");
+		TST_ERR_id = built_in_ident("TST_ERR");
+	}
+
+	if (insn->opcode != OP_STORE)
+		return;
+	if (insn->src->ident != TST_RES_id &&
+	    insn->src->ident != TST_ERR_id)
+		return;
+
+	warning(insn->pos,
+		"LTP-002: Library should not write to TST_RET or TST_ERR");
+}
+
+static void do_basicblock_checks(struct basic_block *bb)
+{
+	struct instruction *insn;
+
+	FOR_EACH_PTR(bb->insns, insn) {
+		if (!bb_reachable(insn->bb))
+			continue;
+
+		if (tu_kind == LTP_LIB)
+			check_lib_sets_TEST_vars(insn);
+	} END_FOR_EACH_PTR(insn);
+}
+
+static void do_entrypoint_checks(struct entrypoint *ep)
+{
+	struct basic_block *bb;
+
+	FOR_EACH_PTR(ep->bbs, bb) {
+		do_basicblock_checks(bb);
+	} END_FOR_EACH_PTR(bb);
+}
+
+/* Compile the AST into a graph of basicblocks */
+static void process_symbols(struct symbol_list *list)
+{
+	struct symbol *sym;
+
+	FOR_EACH_PTR(list, sym) {
+		struct entrypoint *ep;
+
+		expand_symbol(sym);
+		ep = linearize_symbol(sym);
+		if (!ep || !ep->entry)
+			continue;
+
+		do_entrypoint_checks(ep);
+
+		if (dbg_entry)
+			show_entry(ep);
+	} END_FOR_EACH_PTR(sym);
+}
+
+static void collect_info_from_args(const int argc, char *const *const argv)
+{
+	int i;
+
+	for (i = 0; i < argc; i++) {
+		if (!strcmp("-DLTPLIB", argv[i])) {
+			tu_kind = LTP_LIB;
+		}
+	}
+}
+
+int main(int argc, char **argv)
+{
+	struct string_list *filelist = NULL;
+	char *file;
+
+	Waddress_space = 0;
+	Wbitwise = 0;
+	Wcast_truncate = 0;
+	Wcontext = 0;
+	Wdecl = 0;
+	Wexternal_function_has_definition = 0;
+	Wflexible_array_array = 0;
+	Wimplicit_int = 0;
+	Wint_to_pointer_cast = 0;
+	Wmemcpy_max_count = 0;
+	Wnon_pointer_null = 0;
+	Wone_bit_signed_bitfield = 0;
+	Woverride_init = 0;
+	Wpointer_to_int_cast = 0;
+	Wvla = 0;
+
+	do_output = 0;
+
+	collect_info_from_args(argc, argv);
+
+	process_symbols(sparse_initialize(argc, argv, &filelist));
+	FOR_EACH_PTR(filelist, file) {
+		process_symbols(sparse(file));
+	} END_FOR_EACH_PTR(file);
+
+	report_stats();
+	return 0;
+}
diff --git a/tools/sparse/sparse-src b/tools/sparse/sparse-src
new file mode 160000
index 000000000..8af243292
--- /dev/null
+++ b/tools/sparse/sparse-src
@@ -0,0 +1 @@
+Subproject commit 8af2432923486c753ab52cae70b94ee684121080
-- 
2.31.1


  reply	other threads:[~2021-07-14  7:11 UTC|newest]

Thread overview: 30+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-07-14  7:11 [LTP] [PATCH v2 0/8] Sparse based checker and rule proposal Richard Palethorpe
2021-07-14  7:11 ` Richard Palethorpe [this message]
2021-07-14 10:43   ` [LTP] [PATCH v2 1/8] Add Sparse based checker and TST_RET/ERR check Petr Vorel
2021-07-14 11:21   ` Joerg Vehlow
2021-07-14 13:06     ` Richard Palethorpe
2021-07-19 14:51   ` Cyril Hrubis
2021-07-14  7:11 ` [LTP] [PATCH v2 2/8] Add 'make check' to the build system Richard Palethorpe
2021-07-14 10:46   ` Petr Vorel
2021-07-14  7:11 ` [LTP] [PATCH v2 3/8] doc: Add rules and recommendations list Richard Palethorpe
2021-07-14 10:49   ` Petr Vorel
2021-07-14 13:15     ` Richard Palethorpe
2021-07-21 15:43       ` Petr Vorel
2021-07-14 10:54   ` Petr Vorel
2021-07-14 13:26     ` Richard Palethorpe
2021-07-14 14:34       ` Petr Vorel
2021-07-14  7:11 ` [LTP] [PATCH v2 4/8] doc: Remind authors and maintainers to run make check Richard Palethorpe
2021-07-14 10:56   ` Petr Vorel
2021-07-14 13:34     ` Richard Palethorpe
2021-07-14 14:30       ` Petr Vorel
2021-07-14  7:11 ` [LTP] [PATCH v2 5/8] doc: Document TEST macro and state TST_RET/ERR rule LTP-002 Richard Palethorpe
2021-07-14 11:16   ` Petr Vorel
2021-07-14 13:37     ` Richard Palethorpe
2021-07-14  7:11 ` [LTP] [PATCH v2 6/8] Reference LTP-002 rule in Cocci scripts Richard Palethorpe
2021-07-14 11:18   ` Petr Vorel
2021-07-14  7:11 ` [LTP] [PATCH v2 7/8] API: Move libtsc.h from realtime tests include to tst_tsc.h Richard Palethorpe
2021-07-14 11:21   ` Petr Vorel
2021-07-14  7:11 ` [LTP] [PATCH v2 8/8] API/tst_tsc: Add guards and remove some boilerplate Richard Palethorpe
2021-07-14 11:22   ` Petr Vorel
2021-07-14 11:23 ` [LTP] [PATCH v2 0/8] Sparse based checker and rule proposal Petr Vorel
2021-07-14 13:43   ` Richard Palethorpe

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20210714071158.15868-2-rpalethorpe@suse.com \
    --to=rpalethorpe@suse.com \
    --cc=ltp@lists.linux.it \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.