From b92021b09df70c1609e3547f3d6128dd560be97f Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 15 Mar 2013 15:04:17 +1030 Subject: CONFIG_SYMBOL_PREFIX: cleanup. We have CONFIG_SYMBOL_PREFIX, which three archs define to the string "_". But Al Viro broke this in "consolidate cond_syscall and SYSCALL_ALIAS declarations" (in linux-next), and he's not the first to do so. Using CONFIG_SYMBOL_PREFIX is awkward, since we usually just want to prefix it so something. So various places define helpers which are defined to nothing if CONFIG_SYMBOL_PREFIX isn't set: 1) include/asm-generic/unistd.h defines __SYMBOL_PREFIX. 2) include/asm-generic/vmlinux.lds.h defines VMLINUX_SYMBOL(sym) 3) include/linux/export.h defines MODULE_SYMBOL_PREFIX. 4) include/linux/kernel.h defines SYMBOL_PREFIX (which differs from #7) 5) kernel/modsign_certificate.S defines ASM_SYMBOL(sym) 6) scripts/modpost.c defines MODULE_SYMBOL_PREFIX 7) scripts/Makefile.lib defines SYMBOL_PREFIX on the commandline if CONFIG_SYMBOL_PREFIX is set, so that we have a non-string version for pasting. (arch/h8300/include/asm/linkage.h defines SYMBOL_NAME(), too). Let's solve this properly: 1) No more generic prefix, just CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX. 2) Make linux/export.h usable from asm. 3) Define VMLINUX_SYMBOL() and VMLINUX_SYMBOL_STR(). 4) Make everyone use them. Signed-off-by: Rusty Russell Reviewed-by: James Hogan Tested-by: James Hogan (metag) --- scripts/mod/modpost.c | 36 +++++++++++++++--------------------- 1 file changed, 15 insertions(+), 21 deletions(-) (limited to 'scripts/mod') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 78b30c1548e..282decfa29a 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -18,14 +18,7 @@ #include "modpost.h" #include "../../include/generated/autoconf.h" #include "../../include/linux/license.h" - -/* Some toolchains use a `_' prefix for all user symbols. */ -#ifdef CONFIG_SYMBOL_PREFIX -#define MODULE_SYMBOL_PREFIX CONFIG_SYMBOL_PREFIX -#else -#define MODULE_SYMBOL_PREFIX "" -#endif - +#include "../../include/linux/export.h" /* Are we using CONFIG_MODVERSIONS? */ int modversions = 0; @@ -562,7 +555,7 @@ static void parse_elf_finish(struct elf_info *info) static int ignore_undef_symbol(struct elf_info *info, const char *symname) { /* ignore __this_module, it will be resolved shortly */ - if (strcmp(symname, MODULE_SYMBOL_PREFIX "__this_module") == 0) + if (strcmp(symname, VMLINUX_SYMBOL_STR(__this_module)) == 0) return 1; /* ignore global offset table */ if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0) @@ -583,8 +576,8 @@ static int ignore_undef_symbol(struct elf_info *info, const char *symname) return 0; } -#define CRC_PFX MODULE_SYMBOL_PREFIX "__crc_" -#define KSYMTAB_PFX MODULE_SYMBOL_PREFIX "__ksymtab_" +#define CRC_PFX VMLINUX_SYMBOL_STR(__crc_) +#define KSYMTAB_PFX VMLINUX_SYMBOL_STR(__ksymtab_) static void handle_modversions(struct module *mod, struct elf_info *info, Elf_Sym *sym, const char *symname) @@ -637,14 +630,15 @@ static void handle_modversions(struct module *mod, struct elf_info *info, } #endif - if (memcmp(symname, MODULE_SYMBOL_PREFIX, - strlen(MODULE_SYMBOL_PREFIX)) == 0) { - mod->unres = - alloc_symbol(symname + - strlen(MODULE_SYMBOL_PREFIX), - ELF_ST_BIND(sym->st_info) == STB_WEAK, - mod->unres); - } +#ifdef CONFIG_HAVE_UNDERSCORE_SYMBOL_PREFIX + if (symname[0] != '_') + break; + else + symname++; +#endif + mod->unres = alloc_symbol(symname, + ELF_ST_BIND(sym->st_info) == STB_WEAK, + mod->unres); break; default: /* All exported symbols */ @@ -652,9 +646,9 @@ static void handle_modversions(struct module *mod, struct elf_info *info, sym_add_exported(symname + strlen(KSYMTAB_PFX), mod, export); } - if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) + if (strcmp(symname, VMLINUX_SYMBOL_STR(init_module)) == 0) mod->has_init = 1; - if (strcmp(symname, MODULE_SYMBOL_PREFIX "cleanup_module") == 0) + if (strcmp(symname, VMLINUX_SYMBOL_STR(cleanup_module)) == 0) mod->has_cleanup = 1; break; } -- cgit v1.2.3 From a4b6a77b77ba4f526392612c2365797fab956014 Mon Sep 17 00:00:00 2001 From: James Hogan Date: Mon, 18 Mar 2013 19:38:56 +1030 Subject: module: fix symbol versioning with symbol prefixes Fix symbol versioning on architectures with symbol prefixes. Although the build was free from warnings the actual modules still wouldn't load as the ____versions table contained unprefixed symbol names, which were being compared against the prefixed symbol names when checking the symbol versions. This is fixed by modifying modpost to add the symbol prefix to the ____versions table it outputs (Modules.symvers still contains unprefixed symbol names). The check_modstruct_version() function is also fixed as it checks the version of the unprefixed "module_layout" symbol which would no longer work. Signed-off-by: James Hogan Cc: Michal Marek Cc: Sam Ravnborg Cc: Greg Kroah-Hartman Cc: Jonathan Kliegman Signed-off-by: Rusty Russell (use VMLINUX_SYMBOL_STR) --- scripts/mod/modpost.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'scripts/mod') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 282decfa29a..f6913db7762 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1928,7 +1928,8 @@ static int add_versions(struct buffer *b, struct module *mod) s->name, mod->name); continue; } - buf_printf(b, "\t{ %#8x, \"%s\" },\n", s->crc, s->name); + buf_printf(b, "\t{ %#8x, VMLINUX_SYMBOL_STR(%s) },\n", + s->crc, s->name); } buf_printf(b, "};\n"); -- cgit v1.2.3 From d4ef1c30e89ce8e7f1030501d74b6b812c3c179d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 4 Apr 2013 17:37:32 +1030 Subject: modpost: minor cleanup. We want a strends() function next, so make one and use it appropriately, making new_module() arg const while we're at it. Signed-off-by: Rusty Russell --- scripts/mod/modpost.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'scripts/mod') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index f6913db7762..f7a0392ad1c 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -15,6 +15,7 @@ #include #include #include +#include #include "modpost.h" #include "../../include/generated/autoconf.h" #include "../../include/linux/license.h" @@ -78,6 +79,14 @@ PRINTF void merror(const char *fmt, ...) va_end(arglist); } +static inline bool strends(const char *str, const char *postfix) +{ + if (strlen(str) < strlen(postfix)) + return false; + + return strcmp(str + strlen(str) - strlen(postfix), postfix) == 0; +} + static int is_vmlinux(const char *modname) { const char *myname; @@ -113,22 +122,20 @@ static struct module *find_module(char *modname) return mod; } -static struct module *new_module(char *modname) +static struct module *new_module(const char *modname) { struct module *mod; - char *p, *s; + char *p; mod = NOFAIL(malloc(sizeof(*mod))); memset(mod, 0, sizeof(*mod)); p = NOFAIL(strdup(modname)); /* strip trailing .o */ - s = strrchr(p, '.'); - if (s != NULL) - if (strcmp(s, ".o") == 0) { - *s = '\0'; - mod->is_dot_o = 1; - } + if (strends(p, ".o")) { + p[strlen(p) - 2] = '\0'; + mod->is_dot_o = 1; + } /* add to list */ mod->name = p; -- cgit v1.2.3 From 712f9b46843d941347e86dcd2e1d63f9d3b112cb Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 4 Apr 2013 17:37:38 +1030 Subject: modpost: add -T option to read module names from file/stdin. Because there are too many modules in the world. Signed-off-by: Rusty Russell --- scripts/mod/modpost.c | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) (limited to 'scripts/mod') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index f7a0392ad1c..1f90961ada7 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -15,6 +15,7 @@ #include #include #include +#include #include #include "modpost.h" #include "../../include/generated/autoconf.h" @@ -1763,6 +1764,27 @@ static void read_symbols(char *modname) mod->unres = alloc_symbol("module_layout", 0, mod->unres); } +static void read_symbols_from_files(const char *filename) +{ + FILE *in = stdin; + char fname[PATH_MAX]; + + if (strcmp(filename, "-") != 0) { + in = fopen(filename, "r"); + if (!in) + fatal("Can't open filenames file %s: %m", filename); + } + + while (fgets(fname, PATH_MAX, in) != NULL) { + if (strends(fname, "\n")) + fname[strlen(fname)-1] = '\0'; + read_symbols(fname); + } + + if (in != stdin) + fclose(in); +} + #define SZ 500 /* We first write the generated file into memory using the @@ -2124,13 +2146,13 @@ int main(int argc, char **argv) struct module *mod; struct buffer buf = { }; char *kernel_read = NULL, *module_read = NULL; - char *dump_write = NULL; + char *dump_write = NULL, *files_source = NULL; int opt; int err; struct ext_sym_list *extsym_iter; struct ext_sym_list *extsym_start = NULL; - while ((opt = getopt(argc, argv, "i:I:e:msSo:awM:K:")) != -1) { + while ((opt = getopt(argc, argv, "i:I:e:msST:o:awM:K:")) != -1) { switch (opt) { case 'i': kernel_read = optarg; @@ -2162,6 +2184,9 @@ int main(int argc, char **argv) case 'S': sec_mismatch_verbose = 0; break; + case 'T': + files_source = optarg; + break; case 'w': warn_unresolved = 1; break; @@ -2184,6 +2209,9 @@ int main(int argc, char **argv) while (optind < argc) read_symbols(argv[optind++]); + if (files_source) + read_symbols_from_files(files_source); + for (mod = modules; mod; mod = mod->next) { if (mod->skip) continue; -- cgit v1.2.3 From a53a11f35762ff1d5e268adedf2ab9ce313f871d Mon Sep 17 00:00:00 2001 From: James Hogan Date: Mon, 29 Apr 2013 11:36:59 +0930 Subject: modpost: fix unwanted VMLINUX_SYMBOL_STR expansion Commit a4b6a77b77ba4f526392612c2365797fab956014 ("module: fix symbol versioning with symbol prefixes") broke the MODVERSIONS loading of any module using memcmp (e.g. ipv6) on x86_32, as it's defined to __builtin_memcmp which is expanded by VMLINUX_SYMBOL_STR. Use __VMLINUX_SYMBOL_STR instead which doesn't expand the argument. Reported-by: Tetsuo Handa Reported-by: Andy Shevchenko Signed-off-by: James Hogan Cc: H. Peter Anvin Tested-by: Tetsuo Handa Tested-by: Andy Shevchenko Signed-off-by: Rusty Russell Cc: # 3.9 --- scripts/mod/modpost.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'scripts/mod') diff --git a/scripts/mod/modpost.c b/scripts/mod/modpost.c index 1f90961ada7..a4be8e112bb 100644 --- a/scripts/mod/modpost.c +++ b/scripts/mod/modpost.c @@ -1957,7 +1957,7 @@ static int add_versions(struct buffer *b, struct module *mod) s->name, mod->name); continue; } - buf_printf(b, "\t{ %#8x, VMLINUX_SYMBOL_STR(%s) },\n", + buf_printf(b, "\t{ %#8x, __VMLINUX_SYMBOL_STR(%s) },\n", s->crc, s->name); } -- cgit v1.2.3