lkml.org 
[lkml]   [2019]   [Sep]   [3]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    Date
    Subject[PATCH v4 07/12] modpost: add support for generating namespace dependencies
    From
    This patch adds an option to modpost to generate a <module>.ns_deps file
    per module, containing the namespace dependencies for that module.

    E.g. if the linked module my-module.ko would depend on the symbol
    myfunc.MY_NS in the namespace MY_NS, the my-module.ns_deps file created
    by modpost would contain the entry MY_NS to express the namespace
    dependency of my-module imposed by using the symbol myfunc.

    These files can subsequently be used by static analysis tools (like
    coccinelle scripts) to address issues with missing namespace imports. A
    later patch of this series will introduce such a script 'nsdeps' and a
    corresponding make target to automatically add missing
    MODULE_IMPORT_NS() definitions to the module's sources. For that it uses
    the information provided in the generated .ns_deps files.

    Co-developed-by: Martijn Coenen <maco@android.com>
    Signed-off-by: Martijn Coenen <maco@android.com>
    Reviewed-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
    Signed-off-by: Matthias Maennich <maennich@google.com>
    ---
    .gitignore | 1 +
    Makefile | 2 +-
    scripts/mod/modpost.c | 54 +++++++++++++++++++++++++++++++++++++++----
    scripts/mod/modpost.h | 2 ++
    4 files changed, 53 insertions(+), 6 deletions(-)

    diff --git a/.gitignore b/.gitignore
    index 2030c7a4d2f8..9ee63aa2a3fb 100644
    --- a/.gitignore
    +++ b/.gitignore
    @@ -32,6 +32,7 @@
    *.lzo
    *.mod
    *.mod.c
    +*.ns_deps
    *.o
    *.o.*
    *.order
    diff --git a/Makefile b/Makefile
    index 0cbe8717bdb3..0cdb957ae2c3 100644
    --- a/Makefile
    +++ b/Makefile
    @@ -1669,7 +1669,7 @@ clean: $(clean-dirs)
    -o -name '*.ko.*' \
    -o -name '*.dtb' -o -name '*.dtb.S' -o -name '*.dt.yaml' \
    -o -name '*.dwo' -o -name '*.lst' \
    - -o -name '*.su' -o -name '*.mod' \
    + -o -name '*.su' -o -name '*.mod' -o -name '*.ns_deps' \
    -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \
    -o -name '*.lex.c' -o -name '*.tab.[ch]' \
    -o -name '*.asn1.[ch]' \
    diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c
    index c2d49afaea1c..be72da25fe7c 100644
    --- a/scripts/mod/modpost.c
    +++ b/scripts/mod/modpost.c
    @@ -38,6 +38,8 @@ static int sec_mismatch_count = 0;
    static int sec_mismatch_fatal = 0;
    /* ignore missing files */
    static int ignore_missing_files;
    +/* write namespace dependencies */
    +static int write_namespace_deps;

    enum export {
    export_plain, export_unused, export_gpl,
    @@ -2176,10 +2178,15 @@ static int check_exports(struct module *mod)
    else
    basename = mod->name;

    - if (exp->namespace &&
    - !module_imports_namespace(mod, exp->namespace)) {
    - warn("module %s uses symbol %s from namespace %s, but does not import it.\n",
    - basename, exp->name, exp->namespace);
    + if (exp->namespace) {
    + add_namespace(&mod->required_namespaces,
    + exp->namespace);
    +
    + if (!write_namespace_deps &&
    + !module_imports_namespace(mod, exp->namespace)) {
    + warn("module %s uses symbol %s from namespace %s, but does not import it.\n",
    + basename, exp->name, exp->namespace);
    + }
    }

    if (!mod->gpl_compatible)
    @@ -2484,6 +2491,31 @@ static void write_dump(const char *fname)
    free(buf.p);
    }

    +static void write_namespace_deps_files(void)
    +{
    + struct module *mod;
    + struct namespace_list *ns;
    + struct buffer ns_deps_buf = {};
    +
    + for (mod = modules; mod; mod = mod->next) {
    + char fname[PATH_MAX];
    +
    + if (mod->skip)
    + continue;
    +
    + ns_deps_buf.pos = 0;
    +
    + for (ns = mod->required_namespaces; ns; ns = ns->next)
    + buf_printf(&ns_deps_buf, "%s\n", ns->namespace);
    +
    + if (ns_deps_buf.pos == 0)
    + continue;
    +
    + sprintf(fname, "%s.ns_deps", mod->name);
    + write_if_changed(&ns_deps_buf, fname);
    + }
    +}
    +
    struct ext_sym_list {
    struct ext_sym_list *next;
    const char *file;
    @@ -2500,7 +2532,7 @@ int main(int argc, char **argv)
    struct ext_sym_list *extsym_iter;
    struct ext_sym_list *extsym_start = NULL;

    - while ((opt = getopt(argc, argv, "i:I:e:mnsT:o:awE")) != -1) {
    + while ((opt = getopt(argc, argv, "i:I:e:mnsT:o:awEd")) != -1) {
    switch (opt) {
    case 'i':
    kernel_read = optarg;
    @@ -2541,6 +2573,9 @@ int main(int argc, char **argv)
    case 'E':
    sec_mismatch_fatal = 1;
    break;
    + case 'd':
    + write_namespace_deps = 1;
    + break;
    default:
    exit(1);
    }
    @@ -2575,6 +2610,9 @@ int main(int argc, char **argv)

    err |= check_modname_len(mod);
    err |= check_exports(mod);
    + if (write_namespace_deps)
    + continue;
    +
    add_header(&buf, mod);
    add_intree_flag(&buf, !external_module);
    add_retpoline(&buf);
    @@ -2587,6 +2625,12 @@ int main(int argc, char **argv)
    sprintf(fname, "%s.mod.c", mod->name);
    write_if_changed(&buf, fname);
    }
    +
    + if (write_namespace_deps) {
    + write_namespace_deps_files();
    + return 0;
    + }
    +
    if (dump_write)
    write_dump(dump_write);
    if (sec_mismatch_count && sec_mismatch_fatal)
    diff --git a/scripts/mod/modpost.h b/scripts/mod/modpost.h
    index 9626bf3e7424..92a926d375d2 100644
    --- a/scripts/mod/modpost.h
    +++ b/scripts/mod/modpost.h
    @@ -126,6 +126,8 @@ struct module {
    struct buffer dev_table_buf;
    char srcversion[25];
    int is_dot_o;
    + // Required namespace dependencies
    + struct namespace_list *required_namespaces;
    // Actual imported namespaces
    struct namespace_list *imported_namespaces;
    };
    --
    2.23.0.187.g17f5b7556c-goog
    \
     
     \ /
      Last update: 2019-09-03 17:10    [W:4.380 / U:0.108 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site