Skip to content

Commit

Permalink
scripts: Coccinelle script for namespace dependencies.
Browse files Browse the repository at this point in the history
A script that uses the '<module>.ns_deps' files generated by modpost to
automatically add the required symbol namespace dependencies to each
module.

Usage:
1) Move some symbols to a namespace with EXPORT_SYMBOL_NS() or define
   DEFAULT_SYMBOL_NAMESPACE
2) Run 'make' (or 'make modules') and get warnings about modules not
   importing that namespace.
3) Run 'make nsdeps' to automatically add required import statements
   to said modules.

This makes it easer for subsystem maintainers to introduce and maintain
symbol namespaces into their codebase.

Co-developed-by: Martijn Coenen <[email protected]>
Signed-off-by: Martijn Coenen <[email protected]>
Acked-by: Julia Lawall <[email protected]>
Reviewed-by: Greg Kroah-Hartman <[email protected]>
Signed-off-by: Matthias Maennich <[email protected]>
Signed-off-by: Jessica Yu <[email protected]>
  • Loading branch information
metti authored and Jessica Yu committed Sep 10, 2019
1 parent 1d08277 commit eb8305a
Show file tree
Hide file tree
Showing 5 changed files with 101 additions and 1 deletion.
5 changes: 5 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -11436,6 +11436,11 @@ S: Maintained
T: git git://git.kernel.org/pub/scm/linux/kernel/git/wtarreau/nolibc.git
F: tools/include/nolibc/

NSDEPS
M: Matthias Maennich <[email protected]>
S: Maintained
F: scripts/nsdeps

NTB AMD DRIVER
M: Shyam Sundar S K <[email protected]>
L: [email protected]
Expand Down
12 changes: 12 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -1500,6 +1500,9 @@ help:
@echo ' headerdep - Detect inclusion cycles in headers'
@echo ' coccicheck - Check with Coccinelle'
@echo ''
@echo 'Tools:'
@echo ' nsdeps - Generate missing symbol namespace dependencies'
@echo ''
@echo 'Kernel selftest:'
@echo ' kselftest - Build and run kernel selftest (run as root)'
@echo ' Build, install, and boot kernel before'
Expand Down Expand Up @@ -1687,6 +1690,15 @@ quiet_cmd_tags = GEN $@
tags TAGS cscope gtags: FORCE
$(call cmd,tags)

# Script to generate missing namespace dependencies
# ---------------------------------------------------------------------------

PHONY += nsdeps

nsdeps: modules
$(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost nsdeps
$(Q)$(CONFIG_SHELL) $(srctree)/scripts/$@

# Scripts to check various things for consistency
# ---------------------------------------------------------------------------

Expand Down
4 changes: 3 additions & 1 deletion scripts/Makefile.modpost
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ MODPOST = scripts/mod/modpost \
$(if $(KBUILD_EXTMOD),$(addprefix -e ,$(KBUILD_EXTRA_SYMBOLS))) \
$(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
$(if $(CONFIG_SECTION_MISMATCH_WARN_ONLY),,-E) \
$(if $(KBUILD_MODPOST_WARN),-w)
$(if $(KBUILD_MODPOST_WARN),-w) \
$(if $(filter nsdeps,$(MAKECMDGOALS)),-d)

ifdef MODPOST_VMLINUX

Expand Down Expand Up @@ -134,6 +135,7 @@ $(modules): %.ko :%.o %.mod.o FORCE

targets += $(modules)

nsdeps: __modpost

# Add FORCE to the prequisites of a target to force it to be always rebuilt.
# ---------------------------------------------------------------------------
Expand Down
23 changes: 23 additions & 0 deletions scripts/coccinelle/misc/add_namespace.cocci
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// SPDX-License-Identifier: GPL-2.0-only
//
/// Adds missing MODULE_IMPORT_NS statements to source files
///
/// This script is usually called from scripts/nsdeps with -D ns=<namespace> to
/// add a missing namespace tag to a module source file.
///

@has_ns_import@
declarer name MODULE_IMPORT_NS;
identifier virtual.ns;
@@
MODULE_IMPORT_NS(ns);

// Add missing imports, but only adjacent to a MODULE_LICENSE statement.
// That ensures we are adding it only to the main module source file.
@do_import depends on !has_ns_import@
declarer name MODULE_LICENSE;
expression license;
identifier virtual.ns;
@@
MODULE_LICENSE(license);
+ MODULE_IMPORT_NS(ns);
58 changes: 58 additions & 0 deletions scripts/nsdeps
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#!/bin/bash
# SPDX-License-Identifier: GPL-2.0
# Linux kernel symbol namespace import generator
#
# This script requires a minimum spatch version.
SPATCH_REQ_VERSION="1.0.4"

DIR="$(dirname $(readlink -f $0))/.."
SPATCH="`which ${SPATCH:=spatch}`"
if [ ! -x "$SPATCH" ]; then
echo 'spatch is part of the Coccinelle project and is available at http://coccinelle.lip6.fr/'
exit 1
fi

SPATCH_REQ_VERSION_NUM=$(echo $SPATCH_REQ_VERSION | ${DIR}/scripts/ld-version.sh)
SPATCH_VERSION=$($SPATCH --version | head -1 | awk '{print $3}')
SPATCH_VERSION_NUM=$(echo $SPATCH_VERSION | ${DIR}/scripts/ld-version.sh)

if [ "$SPATCH_VERSION_NUM" -lt "$SPATCH_REQ_VERSION_NUM" ] ; then
echo "spatch needs to be version $SPATCH_REQ_VERSION or higher"
exit 1
fi

generate_deps_for_ns() {
$SPATCH --very-quiet --in-place --sp-file \
$srctree/scripts/coccinelle/misc/add_namespace.cocci -D ns=$1 $2
}

generate_deps() {
local mod_name=`basename $@ .ko`
local mod_file=`echo $@ | sed -e 's/\.ko/\.mod/'`
local ns_deps_file=`echo $@ | sed -e 's/\.ko/\.ns_deps/'`
if [ ! -f "$ns_deps_file" ]; then return; fi
local mod_source_files=`cat $mod_file | sed -n 1p \
| sed -e 's/\.o/\.c/g' \
| sed "s/[^ ]* */${srctree}\/&/g"`
for ns in `cat $ns_deps_file`; do
echo "Adding namespace $ns to module $mod_name (if needed)."
generate_deps_for_ns $ns $mod_source_files
# sort the imports
for source_file in $mod_source_files; do
sed '/MODULE_IMPORT_NS/Q' $source_file > ${source_file}.tmp
offset=$(wc -l ${source_file}.tmp | awk '{print $1;}')
cat $source_file | grep MODULE_IMPORT_NS | sort -u >> ${source_file}.tmp
tail -n +$((offset +1)) ${source_file} | grep -v MODULE_IMPORT_NS >> ${source_file}.tmp
if ! diff -q ${source_file} ${source_file}.tmp; then
mv ${source_file}.tmp ${source_file}
else
rm ${source_file}.tmp
fi
done
done
}

for f in `cat $objtree/modules.order`; do
generate_deps $f
done

0 comments on commit eb8305a

Please sign in to comment.