From 4ba8ec797e702788a322b9a2f2811b6d1ffb3e3a Mon Sep 17 00:00:00 2001 From: Nick Alcock Date: Wed, 19 Jul 2017 15:34:14 +0100 Subject: [PATCH] ctf: decouple CTF building from the kernel build This change causes CTF types for the core kernel and modules to be generated only when the new 'ctf' make target is invoked. The CTF content is emitted into a CTF archive with the default name of vmlinux.ctfa (the name read by DTrace userspace): this can be changed via the CTF_FILENAME makefile variable. If 'make ctf' has been run, 'make modules_install' will install the generated CTF archive into the appropriate place. (If CTF_FILENAME was specified on the 'make ctf' line, it needs to be passed to 'make modules_install' as well for this to work.) The existing link-into-modules machinery is still used for out-of-tree modules, since these obviously cannot be visible when the vmlinux.ctfa is built. Usually the ctf target is invoked by kernel-uek.spec, but it can also be invoked by developers if they know they have changed type or global variable info while developing and would like DTrace to be able to introspect the new data, or if they are building a kernel for the first time and would like DTrace to be able to see its types at all. (The archive format is fairly robust: you can often just copy vmlinux.ctfa from one kernel to another, and types that have not changed will continue to work with the new kernel.) This depends on new machinery in libdtrace-ctf 0.7 or higher. Signed-off-by: Nick Alcock Reviewed-by: Tomas Jedlicka Reviewed-by: Victor Erminpour Orabug: 25815362 --- Documentation/Changes | 2 +- Makefile | 19 ++- scripts/Makefile.modpost | 96 +++++++-------- scripts/dwarf2ctf/dedup.blacklist | 8 +- scripts/dwarf2ctf/dwarf2ctf.c | 189 ++++++++++++++++++------------ scripts/kallsyms.c | 10 +- 6 files changed, 189 insertions(+), 135 deletions(-) diff --git a/Documentation/Changes b/Documentation/Changes index a567f68b82ad..9a5a571eb2a4 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -49,7 +49,7 @@ Build-time requirements only, for DTrace: o elfutils 0.152 # eu-readelf --version o pkg-config 0.16 # pkg-config --version o glib 2.x # pkg-config --exists glib-2.0 && echo present -o libdtrace-ctf 0.3 +o libdtrace-ctf 0.7 Kernel compilation ================== diff --git a/Makefile b/Makefile index ba6da1cd85c9..4971f939d870 100644 --- a/Makefile +++ b/Makefile @@ -1112,6 +1112,9 @@ ifdef CONFIG_CTF # We need to force everything to be built, since we need the .o files below. KBUILD_BUILTIN := 1 +# Set a default CTF filename. +CTF_FILENAME := vmlinux.ctfa + # This contains all the object files that are unconditionally built into the # kernel, for consumption by dwarf2ctf in Makefile.modpost. # This is made doubly annoying by the presence of '.o' files which are actually @@ -1129,6 +1132,14 @@ endif ar t "$$archive" | grep '\.o$$' | \ sed "s,^,$${archive%/*}/," >> objects.builtin; \ done + +CTF_DEBUGDIR := . + +ctf: $(CTF_FILENAME) +PHONY += ctf +$(CTF_FILENAME): + $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modpost CTF_FILENAME=$(CTF_FILENAME) CTF_DEBUGDIR=$(CTF_DEBUGDIR) $(CTF_FILENAME) + else PHONY += objects.builtin objects.builtin: @@ -1154,6 +1165,9 @@ _modinst_: fi @cp -f $(objtree)/modules.order $(MODLIB)/ @cp -f $(objtree)/modules.builtin $(MODLIB)/ + @if [ -f $(objtree)/$(CTF_FILENAME) ] ; then \ + cp -f $(objtree)/$(CTF_FILENAME) $(MODLIB)/kernel ; \ + fi $(Q)$(MAKE) -f $(srctree)/scripts/Makefile.modinst # This depmod is only for convenience to give the initial @@ -1202,6 +1216,7 @@ modules.builtin: $(vmlinux-dirs:%=%/modules.builtin) # Directories & files removed with 'make clean' CLEAN_DIRS += $(MODVERDIR) .ctf +CLEAN_FILES += .ctf.filelist # Directories & files removed with 'make mrproper' MRPROPER_DIRS += include/config usr/include include/generated \ @@ -1297,6 +1312,8 @@ help: @echo ' (requires a recent binutils and recent build (System.map))' @echo ' dir/file.ko - Build module including final link' @echo ' modules_prepare - Set up for building external modules' + @echo ' ctf - Generate CTF type information for DTrace, installed by ' + @echo ' make modules_install' @echo ' tags/TAGS - Generate tags file for editors' @echo ' cscope - Generate cscope index' @echo ' gtags - Generate GNU GLOBAL index' @@ -1466,7 +1483,7 @@ clean: $(clean-dirs) -o -name '.*.d' -o -name '.*.tmp' -o -name '*.mod.c' \ -o -name '*.symtypes' -o -name 'modules.order' \ -o -name 'modules.builtin' -o -name 'objects.builtin' \ - -o -name '.tmp_*.o.*' \ + -o -name '.tmp_*.o.*' -o -name '*.ctfa' \ -o -name '*.gcno' \) -type f -print | xargs rm -f # Generate tags for editors diff --git a/scripts/Makefile.modpost b/scripts/Makefile.modpost index 6b522fac2144..0c3c924fbb11 100644 --- a/scripts/Makefile.modpost +++ b/scripts/Makefile.modpost @@ -14,8 +14,9 @@ # 3) create one .mod.c file pr. module # 4) create one Module.symvers file with CRC for all exported symbols # 5) compute SDT offsets, generate SDT stubs, and compile all .mod.c files -# 6) generate CTF for the entire kernel, or for the module alone if this is -# a build of an external module +# 6) for external modules, generate CTF for the module (there is an extra, +# externally-invoked target that does this for the entire kernel but does +# not invoke the rst of the module-building process) # 7) final link of the module to a file # Step 3 is used to place certain information in the module's ELF @@ -158,56 +159,54 @@ endif targets += $(modules:.ko=.mod.o) -# Step 6), generate CTF for the entire kernel, or for the module alone if this -# is a build of an external module. +# Step 6), generate CTF for the entire kernel (in a separate $(CTF_FILENAME)), +# or for the module alone if this is a build of an external module. ifdef CONFIG_CTF +# These are overridden below for standalone modules only. +module-ctfs-modular-prereq = +module-ctfs-modular = +module-ctf-flags = +cmd_touch_ctf = +ctf-dir = ///.nonexistent +cmd-touch-ctf = @: + # This is quite tricky. If called for non-external-modules, dwarf2ctf needs to # be told about all the built-in objects as well as all the external modules -- # but Makefile.modpost only knows about the latter. So the toplevel makefile # emits the names of the built-in objects into a temporary file, which is # then catted and its contents used as prerequisites by this rule. # -# Because we only run dwarf2ctf once (in non-standalone-module mode), and it -# depends on a stamp file (because its real targets cannot change unless the -# object files change, in which case a relink of the appropriate modules is -# triggered anyway), we don't emit a filename in this output. -# -# Out-of-tree module CTF gets its own per-module set of stamp files, since its -# CTF is rebuilt independently. -# # We write the names of the object files to be scanned for CTF content into a # file, then use that, to avoid hitting command-line length limits. ifeq ($(KBUILD_EXTMOD),) -ctf-dir := .ctf -quiet_cmd_ctf = CTF - cmd_ctf = scripts/dwarf2ctf/dwarf2ctf $(ctf-dir) $(srctree) objects.builtin modules.builtin $(srctree)/scripts/dwarf2ctf/dedup.blacklist $(srctree)/scripts/dwarf2ctf/member.blacklist $(ctf-filelist) -builtins := $(shell cat objects.builtin 2>/dev/null) -ctf-stamp := .ctf/ctf.stamp -ctf-filelist := .ctf/ctf.filelist - -# The CTF module depends on the CTF stamp file, in lieu of the builtin -# CTF files whose names we cannot determine until it is too late. - -kernel/ctf/ctf.ko: .ctf/ctf.stamp +ctf-dir-mk := +quiet_cmd_ctf = CTFA + cmd_ctf = scripts/dwarf2ctf/dwarf2ctf $(CTF_FILENAME) $(srctree) objects.builtin modules.builtin $(srctree)/scripts/dwarf2ctf/dedup.blacklist $(srctree)/scripts/dwarf2ctf/member.blacklist $(ctf-filelist) +ctf-builtins := $(CTF_DEBUGDIR)/vmlinux + ctf-modules := $(shell find $(CTF_DEBUGDIR) \( -name '*.ko' -o -name '*.ko.debug' \) -print) +ctf-filelist := .ctf.filelist +ctf-stamp := else ctf-dir := $(KBUILD_EXTMOD)/.ctf +ctf-dir-mk := $(ctf-dir) quiet_cmd_ctf = CTF cmd_ctf = scripts/dwarf2ctf/dwarf2ctf $(ctf-dir) -e $(ctf-filelist) -builtins := -ctf-stamp := $(ctf-dir)/$(notdir $(M)-extmod).stamp +ctf-builtins := +ctf-modules := $(modules:.ko=.o) ctf-filelist := $(ctf-dir)/$(notdir $(M)-extmod).ctf.filelist +ctf-stamp = $(ctf-dir)/$(notdir $(M)-extmod).stamp -endif - -# All the modules' CTF likewise depends on the stamp file. +# All the modules' CTF depends on the stamp file. all-module-ctfs = $(addprefix $(ctf-dir)/,$(notdir $(modules:.ko=.mod.ctf))) $(all-module-ctfs): $(ctf-stamp) +endif + # This ensures that the (possibly very long) prerequisite list is written out # using one shell invocation per prerequisite. # @@ -220,26 +219,30 @@ define add-ctf-filelists-cmd $(foreach file,$(1),$(call add-ctf-filelist-cmd,$(file))) endef -$(ctf-filelist): $(builtins) $(modules:.ko=.o) | $(sdtinfo-prereq) +$(ctf-filelist): $(ctf-builtins) $(ctf-modules) | $(sdtinfo-prereq) @rm -f $(ctf-filelist); - @mkdir -p $(ctf-dir); + @if [[ -n "$(ctf-dir-mk)" ]]; then \ + mkdir -p "$(ctf-dir-mk)"; \ + fi $(call add-ctf-filelists-cmd,$^) -# We depend upon a stamp file in lieu of the builtin modules' CTF files, because -# the names of the generated CTF files for the builtins are so variable. -# (Standalone modules get their own per-module stamp files.) -# The stamp file then depends on the .o files for the modules, and on the -# sdtinfo files, if any (for the same reason that the sdtstub does). +ifeq ($(KBUILD_EXTMOD),) +# The CTF depends on the output CTF file list, and that depends +# on the .ko files for the modules. +$(CTF_FILENAME): $(ctf-filelist) + $(call if_changed,ctf) +else + +# The CTF depends on the output CTF file list, and that depends +# on the .o files for the modules, and on the sdtinfo files, if any +# (for the same reason that the sdtstub does). $(ctf-stamp): $(ctf-filelist) $(call if_changed,ctf) @shopt -s nullglob; \ - for name in $(ctf-dir)/*.builtin.ctf; do \ - [[ -f $${name}.new ]] || rm -f $$name; \ - done; \ for name in $(ctf-dir)/*.ctf.new; do \ $(srctree)/scripts/move-if-change $$name $${name%.new}; \ - done - @touch $(ctf-stamp) + done; \ + touch $(ctf-stamp) # Expands to the names of the CTF files to be incorporated into this module. # The former is used in prerequisite lists, thanks to secondary expansion. @@ -259,9 +262,6 @@ ctf-module-name = $(addprefix $(ctf-dir)/,$(notdir $(basename $@)).mod.ctf) module-ctf-flags = $(if $(filter ctf.ko,$(notdir $@)), \ --strip-debug \ - $(shell for builtin in $(ctf-dir)/*.builtin.ctf; do \ - printf "%s" "--add-section .ctf.$$(basename $$builtin .builtin.ctf)=$$builtin "; \ - done), \ --add-section .ctf=$(ctf-module-name)) # We have to put content in our dummy no-CTF files because --add-section @@ -271,15 +271,9 @@ cmd_touch_ctf = @for name in $(filter $(ctf-dir)/%,$(module-ctfs-modular)); do \ test -f $$name || dd if=/dev/zero of=$$name bs=1 count=1 2>/dev/null; \ done -else # !CONFIG_CTF +endif # KBUILD_EXTMOD -module-ctfs-modular-prereq = -module-ctfs-builtin = -module-ctf-flags = -ctf-dir = ///.nonexistent -cmd-touch-ctf = @: - -endif +endif # !CONFIG_CTF # Step 7), final link of the modules quiet_cmd_ld_ko_o = LD [M] $@ diff --git a/scripts/dwarf2ctf/dedup.blacklist b/scripts/dwarf2ctf/dedup.blacklist index 5d588367556c..4898611d45b1 100644 --- a/scripts/dwarf2ctf/dedup.blacklist +++ b/scripts/dwarf2ctf/dedup.blacklist @@ -1,4 +1,4 @@ -snd-ens1371 -snd-opti93x -snd-opti92x-cs4231 -snd-interwave-stb +snd_ens1371 +snd_opti93x +snd_opti92x_cs4231 +snd_interwave_stb diff --git a/scripts/dwarf2ctf/dwarf2ctf.c b/scripts/dwarf2ctf/dwarf2ctf.c index 59f3ad02c88f..639198c70363 100644 --- a/scripts/dwarf2ctf/dwarf2ctf.c +++ b/scripts/dwarf2ctf/dwarf2ctf.c @@ -1,8 +1,9 @@ /* * dwarf2ctf.c: Read in DWARF[23] debugging information from some set of ELF - * files, and generate CTF in correspondingly-named files. + * files, and generate CTF in correspondingly-named files, or in a single + * representation meant for mmapping. * - * (C) 2011 -- 2017 Oracle, Inc. All rights reserved. + * Copyright (c) 2011, 2017, Oracle and/or its affiliates. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -21,6 +22,7 @@ #include #include #include +#include #include #include @@ -59,9 +61,10 @@ static const char *trace; /* * Run dwarf2ctf over a single object file or set thereof. * - * output_dir is the directory into which the CTF goes. + * output_dir is the directory into which the CTF goes, if 'standalone', or the + * CTF archive file name otherwise. */ -static void run(char *output_dir); +static void run(char *output, int standalone); /* * A fully descriptive CTF type ID: both file and type ID in one place. @@ -255,7 +258,7 @@ static void init_tu_to_modules(void); * If this is a local type table, and deduplication is active, make the global * type table its parent. */ -static ctf_file_t *init_ctf_table(const char *module_name); +static void init_ctf_table(const char *module_name); /* * A few useful singleton CTF type IDs in the global type table: a void pointer @@ -404,7 +407,7 @@ static void detect_duplicates(const char *module_name, const char *file_name, /* * Note in the detect_duplicates_id_file list that we will rescan a DIE in - * a later duplicate detection pass + * a later duplicate detection pass. * * A type_id() callback. */ @@ -507,9 +510,9 @@ static void construct_ctf(const char *module_name, const char *file_name, /* * Write out the CTF files from the per_module->ctf_file into files in the - * output_dir. + * output directory (if standalone), or into the output file (otherwise). */ -static void write_types(char *output_dir); +static void write_types(char *output, int standalone); /* * Construct CTF out of each type and return that type's ID and file. @@ -827,21 +830,21 @@ static void free_duplicates_id_file(void *id_file); int main(int argc, char *argv[]) { - char *output_dir; + char *output; trace = getenv("DWARF2CTF_TRACE"); if ((argc != 4 && argc != 8) || (argc == 4 && strcmp(argv[2], "-e") != 0)) { - fprintf(stderr, "Syntax: dwarf2ctf outputdir srcdir " + fprintf(stderr, "Syntax: dwarf2ctf output-file srcdir " "objects.builtin modules.builtin dedup.blacklist\n"); fprintf(stderr, " member.blacklist filelist\n"); - fprintf(stderr, " or dwarf2ctf outputdir -e filelist\n" + fprintf(stderr, " or dwarf2ctf output-dir -e filelist\n" "for external module use\n"); exit(1); } - output_dir = argv[1]; + output = argv[1]; elf_version(EV_CURRENT); @@ -876,7 +879,7 @@ int main(int argc, char *argv[]) init_member_blacklist(member_blacklist_file, srcdir); init_object_names(argv[7]); - run(output_dir); + run(output, 0); } else { char *single_object_name; char **all_object_names; @@ -897,7 +900,7 @@ int main(int argc, char *argv[]) for (i = 0; i < all_object_names_cnt; i++) { single_object_name = all_object_names[i]; - run(output_dir); + run(output, 1); } } @@ -910,9 +913,10 @@ int main(int argc, char *argv[]) /* * Run dwarf2ctf over a single object file or set thereof. * - * output_dir is the directory into which the CTF goes. + * output is the directory into which the CTF goes, if 'standalone', or the + * CTF archive file name otherwise. */ -static void run(char *output_dir) +static void run(char *output, int standalone) { size_t i; @@ -952,7 +956,7 @@ static void run(char *output_dir) * necessary linker scripts. */ dw_ctf_trace("Writeout.\n"); - write_types(output_dir); + write_types(output, standalone); g_hash_table_destroy(id_to_type); g_hash_table_destroy(id_to_module); @@ -1355,7 +1359,7 @@ static int member_blacklisted(Dwarf_Die *die, Dwarf_Die *parent_die) * If this is a local type table, and deduplication is active, make the global * type table its parent. */ -static ctf_file_t *init_ctf_table(const char *module_name) +static void init_ctf_table(const char *module_name) { ctf_file_t *ctf_file; per_module_t *new_per_mod; @@ -1433,7 +1437,7 @@ static ctf_file_t *init_ctf_table(const char *module_name) dw_ctf_trace("Created CTF file for module %s: %p\n", module_name, ctf_file); - return ctf_file; + return; } /* DWARF walkers. */ @@ -2034,6 +2038,20 @@ static void detect_duplicates_tu_init(const char *module_name, void *data) { struct detect_duplicates_state *state = data; + per_module_t *per_mod; + + /* + * Make sure that even if this module has no types in it we still end up + * generating a CTF file. (Userspace depends on this, since a CTF file + * with no types in means the module is known and typeless, while no CTF + * file at all means the module is not known.) + */ + + per_mod = g_hash_table_lookup(per_module, module_name); + if (per_mod == NULL) { + init_ctf_table(module_name); + dw_ctf_trace("%s: initialized CTF file.\n", module_name); + } state->structs_seen = g_hash_table_new_full(g_str_hash, g_str_equal, free, NULL); @@ -2801,12 +2819,6 @@ static ctf_full_id_t *construct_ctf_id(const char *module_name, ctf = lookup_ctf_file(ctf_module); - if (ctf == NULL) { - ctf = init_ctf_table(ctf_module); - dw_ctf_trace("%p: %s: initialized CTF file %p\n", &id, - ctf_module, ctf); - } - /* * Construct the CTF, then insert the top-level CTF entity into the * id->type hash so that references from other types can find it, and @@ -3290,6 +3302,7 @@ static int filter_ctf_uninteresting(Dwarf_Die *die, return ((dwarf_tag(parent_die) == DW_TAG_compile_unit) && !((strcmp(sym_name, "__per_cpu_start") == 0) || (strcmp(sym_name, "__per_cpu_end") == 0) || + (strcmp(sym_name, "_sdt_probes") == 0) || (strstarts(sym_name, "__crc_")) || (strstarts(sym_name, "__ksymtab_")) || (strstarts(sym_name, "__kcrctab_")) || @@ -4211,81 +4224,96 @@ static ctf_id_t assemble_ctf_variable(const char *module_name, /* Writeout. */ -static void write_types(char *output_dir) +static void write_types(char *output, int standalone) { GHashTableIter module_iter; char *module; per_module_t *per_mod; + ctf_file_t **ctfs; + const char **names; + size_t i = 0; + size_t ctf_count = g_hash_table_size(per_module); /* - * Work over all the modules and write their compressed CTF data out - * into the output directory. Built-in modules get names ending in - * .builtin.ctf.new; others get names ending in .mod.ctf.new. The - * makefile moves .ctf.new over the top of .ctf iff it has changed. + * Work over all the modules and write their compressed CTF data out. + * Standalone modules get placed in files in the output directory named + * with names ending in .mod.ctf.new, and the makefile moves .ctf.new + * over the top of .ctf iff it has changed; built-in modules and the + * core kernel and shared type repository are placed into a CTF archive. */ - - if ((mkdir(output_dir, 0777) < 0) && errno != EEXIST) { - fprintf(stderr, "Cannot create .ctf directory: %s\n", - strerror(errno)); - exit(1); + if (standalone) { + if ((mkdir(output, 0777) < 0) && errno != EEXIST) { + fprintf(stderr, "Cannot create .ctf directory: %s\n", + strerror(errno)); + exit(1); + } + } else { + ctfs = calloc(ctf_count, sizeof (ctf_file_t *)); + names = calloc(ctf_count, sizeof (char *)); + if (!ctfs || !names) { + fprintf (stderr, "Out of memory in CTF writeout\n"); + } } + /* + * Write the files out (in standalone mode), or construct the arrays of + * module names and files to put in the archive (otherwise). + */ g_hash_table_iter_init(&module_iter, per_module); while (g_hash_table_iter_next(&module_iter, (void **) &module, (void **)&per_mod)) { - char *path = NULL; - gzFile fd; - int builtin_module = 0; + int fd; dw_ctf_trace("Writing out %s\n", module); - if ((strcmp(module, "shared_ctf") == 0) || - (strcmp(module, "vmlinux") == 0)) - builtin_module = 1; - else { - size_t module_num; - - for (module_num = 0; module_num < builtin_modules_cnt; - module_num++) { - char *module_name = fn_to_module(builtin_modules[module_num]); - - if (strcmp(module_name, module) == 0) - builtin_module = 1; - - free(module_name); - } - } - - path = str_appendn(path, output_dir, "/", module, - builtin_module ? ".builtin" : ".mod", - ".ctf.new", NULL); - - dw_ctf_trace("Writeout path: %s\n", path); - if (ctf_update(per_mod->ctf_file) < 0) { fprintf(stderr, "Cannot serialize CTF file %s: %s\n", - path, ctf_errmsg(ctf_errno(per_mod->ctf_file))); + module, ctf_errmsg(ctf_errno(per_mod->ctf_file))); exit(1); } - if ((fd = gzopen(path, "wb")) == NULL) { - fprintf(stderr, "Cannot open CTF file %s for writing: " - "%s\n", path, strerror(errno)); - exit(1); - } - if (ctf_gzwrite(per_mod->ctf_file, fd) < 0) { - fprintf(stderr, "Cannot write to CTF file %s: " - "%s\n", path, - ctf_errmsg(ctf_errno(per_mod->ctf_file))); - exit(1); + if (!standalone) { + names[i] = module; + ctfs[i] = per_mod->ctf_file; + i++; + } else { + char *path = NULL; + path = str_appendn(path, output, "/", module, + ".mod.ctf.new", NULL); + + if ((fd = open(path, O_WRONLY | O_CREAT | O_TRUNC | + O_CLOEXEC, 0666)) < 0) { + fprintf(stderr, "Cannot open CTF file %s for " + "writing: %s\n", path, + strerror(errno)); + exit(1); + } + if (ctf_compress_write(per_mod->ctf_file, fd) < 0) { + fprintf(stderr, "Cannot write to CTF file %s: " + "%s\n", path, + ctf_errmsg(ctf_errno(per_mod->ctf_file))); + exit(1); + } + if (close(fd) != 0) { + fprintf(stderr, "Cannot close CTF file %s: %s\n", + path, strerror(errno)); + exit(1); + } + free(path); } + } - if (gzclose(fd) != Z_OK) { - fprintf(stderr, "Cannot close CTF file %s: %s\n", - path, strerror(errno)); + if (!standalone) { + int err; + if ((err = ctf_arc_write(output, ctfs, ctf_count, + names, 4096) != 0)) { + fprintf(stderr, "Cannot write to CTF archive %s: %s\n", + output, err < ECTF_BASE ? strerror(err) : + ctf_errmsg(err)); exit(1); } - free(path); + free(names); + free(ctfs); } } @@ -4576,7 +4604,7 @@ static GList *list_filter(GList *list, filter_pred_fun fun, static char *fn_to_module(const char *file_name) { char *module_name; - char *chop; + char *chop, *dash; if ((chop = strrchr(file_name, '/')) != NULL) module_name = xstrdup(++chop); @@ -4586,6 +4614,13 @@ static char *fn_to_module(const char *file_name) if ((chop = strrchr(module_name, '.')) != NULL) *chop = '\0'; + dash = module_name; + while (dash != NULL) { + dash = strchr(dash, '-'); + if (dash != NULL) + *dash = '_'; + } + return module_name; } diff --git a/scripts/kallsyms.c b/scripts/kallsyms.c index 907959f83ae7..6bca66f9dc94 100644 --- a/scripts/kallsyms.c +++ b/scripts/kallsyms.c @@ -935,7 +935,8 @@ static void read_modules(const char *modules_builtin) /* * Read in, stripping off the leading path element, if any, transforming * the suffix into .o from .ko, and also computing the suffixless, - * pathless name of the module. Any elements that don't have files + * pathless name of the module, translating - into _ to match what is + * done for real module names. Any elements that don't have files * corresponding to them elicit a warning, and do not have their names * recorded. */ @@ -960,11 +961,18 @@ static void read_modules(const char *modules_builtin) if (access(first_slash, R_OK) == 0) { char *module_name = strdup(last_slash); + char *dash = module_name; last_dot = strrchr(module_name, '.'); if (last_dot != NULL) *last_dot = '\0'; + while (dash != NULL) { + dash = strchr(dash, '-'); + if (dash != NULL) + *dash = '_'; + } + read_module_symbols(builtin_module_len, first_slash, module_symbol_seen); -- 2.50.1