History

modpost: distinguish same module paths from different dump files

Since commit 13b25489b6f8 ("kbuild: change working directory to external module directory with M="), module paths are always relative to the top of the external module tree. The module paths recorded in Module.symvers are no longer globally unique when they are passed via KBUILD_EXTRA_SYMBOLS for building other external modules, which may result in false-positive "exported twice" errors. Such errors should not occur because external modules should be able to override in-tree modules. To address this, record the dump file path in struct module and check it when searching for a module.

Masahiro Yamada committed 1 year ago

Commit 9435dc71 parent 54956562 files · +11 −9Browse files

Unified · Split

2 files
  1. scripts/mod/modpost.c +9 −8
  2. scripts/mod/modpost.h +2 −1
scripts/mod/modpost.c+9−8
@@ -155,12 +155,13 @@ char *get_line(char **stringp) · 154 unmodified lines
155155 /* A list of all modules we processed */
156156 LIST_HEAD(modules);
157157
158−static struct module *find_module(const char *modname)
158+static struct module *find_module(const char *filename, const char *modname)
159159 {
160160 struct module *mod;
161161
162162 list_for_each_entry(mod, &modules, list) {
163− if (strcmp(mod->name, modname) == 0)
163+ if (!strcmp(mod->dump_file, filename) &&
164+ !strcmp(mod->name, modname))
164165 return mod;
165166 }
166167 return NULL;
@@ -2030,10 +2031,10 @@ static void read_dump(const char *fname) · 1863 unmodified lines
20302031 continue;
20312032 }
20322033
2033− mod = find_module(modname);
2034+ mod = find_module(fname, modname);
20342035 if (!mod) {
20352036 mod = new_module(modname, strlen(modname));
2036− mod->from_dump = true;
2037+ mod->dump_file = fname;
20372038 }
20382039 s = sym_add_exported(symname, mod, gpl_only, namespace);
20392040 sym_set_crc(s, crc);
@@ -2052,7 +2053,7 @@ static void write_dump(const char *fname) · 12 unmodified lines
20522053 struct symbol *sym;
20532054
20542055 list_for_each_entry(mod, &modules, list) {
2055− if (mod->from_dump)
2056+ if (mod->dump_file)
20562057 continue;
20572058 list_for_each_entry(sym, &mod->exported_symbols, list) {
20582059 if (trim_unused_exports && !sym->used)
@@ -2076,7 +2077,7 @@ static void write_namespace_deps_files(const char *fname) · 17 unmodified lines
20762077
20772078 list_for_each_entry(mod, &modules, list) {
20782079
2079− if (mod->from_dump || list_empty(&mod->missing_namespaces))
2080+ if (mod->dump_file || list_empty(&mod->missing_namespaces))
20802081 continue;
20812082
20822083 buf_printf(&ns_deps_buf, "%s.ko:", mod->name);
@@ -2194,7 +2195,7 @@ int main(int argc, char **argv) · 111 unmodified lines
21942195 read_symbols_from_files(files_source);
21952196
21962197 list_for_each_entry(mod, &modules, list) {
2197− if (mod->from_dump || mod->is_vmlinux)
2198+ if (mod->dump_file || mod->is_vmlinux)
21982199 continue;
21992200
22002201 check_modname_len(mod);
@@ -2205,7 +2206,7 @@ int main(int argc, char **argv) · 4 unmodified lines
22052206 handle_white_list_exports(unused_exports_white_list);
22062207
22072208 list_for_each_entry(mod, &modules, list) {
2208− if (mod->from_dump)
2209+ if (mod->dump_file)
22092210 continue;
22102211
22112212 if (mod->is_vmlinux)
scripts/mod/modpost.h+2−1
@@ -95,14 +95,15 @@ struct module_alias { · 94 unmodified lines
9595 /**
9696 * struct module - represent a module (vmlinux or *.ko)
9797 *
98+ * @dump_file: path to the .symvers file if loaded from a file
9899 * @aliases: list head for module_aliases
99100 */
100101 struct module {
101102 struct list_head list;
102103 struct list_head exported_symbols;
103104 struct list_head unresolved_symbols;
105+ const char *dump_file;
104106 bool is_gpl_compatible;
105− bool from_dump; /* true if module was loaded from *.symvers */
106107 bool is_vmlinux;
107108 bool seen;
108109 bool has_init;