Commit 9e2dd2ca authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge tag 'modules-for-v5.4-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux

Pull modules fixes from Jessica Yu:

 - Revert __ksymtab_$namespace.$symbol naming scheme back to
   __ksymtab_$symbol, as it was causing issues with depmod.

   Instead, have modpost extract a symbol's namespace from __kstrtabns
   and __ksymtab_strings.

 - Fix `make nsdeps` for out of tree kernel builds (make O=...) caused
   by unescaped '/'.

   Use a different sed delimiter to avoid this problem.

* tag 'modules-for-v5.4-rc5' of git://git.kernel.org/pub/scm/linux/kernel/git/jeyu/linux:
  scripts/nsdeps: use alternative sed delimiter
  symbol namespaces: revert to previous __ksymtab name scheme
  modpost: make updating the symbol namespace explicit
  modpost: delegate updating namespaces to separate function
parents 63cbb3b3 09684950
Loading
Loading
Loading
Loading
+5 −9
Original line number Diff line number Diff line
@@ -18,8 +18,6 @@ extern struct module __this_module;
#define THIS_MODULE ((struct module *)0)
#endif

#define NS_SEPARATOR "."

#ifdef CONFIG_MODVERSIONS
/* Mark the CRC weak since genksyms apparently decides not to
 * generate a checksums for some symbols */
@@ -48,11 +46,11 @@ extern struct module __this_module;
 * absolute relocations that require runtime processing on relocatable
 * kernels.
 */
#define __KSYMTAB_ENTRY_NS(sym, sec, ns)				\
#define __KSYMTAB_ENTRY_NS(sym, sec)					\
	__ADDRESSABLE(sym)						\
	asm("	.section \"___ksymtab" sec "+" #sym "\", \"a\"	\n"	\
	    "	.balign	4					\n"	\
	    "__ksymtab_" #ns NS_SEPARATOR #sym ":		\n"	\
	    "__ksymtab_" #sym ":				\n"	\
	    "	.long	" #sym "- .				\n"	\
	    "	.long	__kstrtab_" #sym "- .			\n"	\
	    "	.long	__kstrtabns_" #sym "- .			\n"	\
@@ -74,16 +72,14 @@ struct kernel_symbol {
	int namespace_offset;
};
#else
#define __KSYMTAB_ENTRY_NS(sym, sec, ns)				\
	static const struct kernel_symbol __ksymtab_##sym##__##ns	\
	asm("__ksymtab_" #ns NS_SEPARATOR #sym)				\
#define __KSYMTAB_ENTRY_NS(sym, sec)					\
	static const struct kernel_symbol __ksymtab_##sym		\
	__attribute__((section("___ksymtab" sec "+" #sym), used))	\
	__aligned(sizeof(void *))					\
	= { (unsigned long)&sym, __kstrtab_##sym, __kstrtabns_##sym }

#define __KSYMTAB_ENTRY(sym, sec)					\
	static const struct kernel_symbol __ksymtab_##sym		\
	asm("__ksymtab_" #sym)						\
	__attribute__((section("___ksymtab" sec "+" #sym), used))	\
	__aligned(sizeof(void *))					\
	= { (unsigned long)&sym, __kstrtab_##sym, NULL }
@@ -115,7 +111,7 @@ struct kernel_symbol {
	static const char __kstrtabns_##sym[]				\
	__attribute__((section("__ksymtab_strings"), used, aligned(1)))	\
	= #ns;								\
	__KSYMTAB_ENTRY_NS(sym, sec, ns)
	__KSYMTAB_ENTRY_NS(sym, sec)

#define ___EXPORT_SYMBOL(sym, sec)					\
	___export_symbol_common(sym, sec);				\
+40 −19
Original line number Diff line number Diff line
@@ -348,26 +348,38 @@ static enum export export_from_sec(struct elf_info *elf, unsigned int sec)
		return export_unknown;
}

static char *sym_extract_namespace(const char **symname)
static const char *namespace_from_kstrtabns(struct elf_info *info,
					    Elf_Sym *kstrtabns)
{
	char *namespace = NULL;
	char *ns_separator;
	char *value = info->ksymtab_strings + kstrtabns->st_value;
	return value[0] ? value : NULL;
}

static void sym_update_namespace(const char *symname, const char *namespace)
{
	struct symbol *s = find_symbol(symname);

	ns_separator = strchr(*symname, '.');
	if (ns_separator) {
		namespace = NOFAIL(strndup(*symname, ns_separator - *symname));
		*symname = ns_separator + 1;
	/*
	 * That symbol should have been created earlier and thus this is
	 * actually an assertion.
	 */
	if (!s) {
		merror("Could not update namespace(%s) for symbol %s\n",
		       namespace, symname);
		return;
	}

	return namespace;
	free(s->namespace);
	s->namespace =
		namespace && namespace[0] ? NOFAIL(strdup(namespace)) : NULL;
}

/**
 * Add an exported symbol - it may have already been added without a
 * CRC, in this case just update the CRC
 **/
static struct symbol *sym_add_exported(const char *name, const char *namespace,
				       struct module *mod, enum export export)
static struct symbol *sym_add_exported(const char *name, struct module *mod,
				       enum export export)
{
	struct symbol *s = find_symbol(name);

@@ -383,8 +395,6 @@ static struct symbol *sym_add_exported(const char *name, const char *namespace,
			s->module = mod;
		}
	}
	free(s->namespace);
	s->namespace = namespace ? strdup(namespace) : NULL;
	s->preloaded = 0;
	s->vmlinux   = is_vmlinux(mod->name);
	s->kernel    = 0;
@@ -583,6 +593,10 @@ static int parse_elf(struct elf_info *info, const char *filename)
			info->export_unused_gpl_sec = i;
		else if (strcmp(secname, "__ksymtab_gpl_future") == 0)
			info->export_gpl_future_sec = i;
		else if (strcmp(secname, "__ksymtab_strings") == 0)
			info->ksymtab_strings = (void *)hdr +
						sechdrs[i].sh_offset -
						sechdrs[i].sh_addr;

		if (sechdrs[i].sh_type == SHT_SYMTAB) {
			unsigned int sh_link_idx;
@@ -672,7 +686,6 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
	enum export export;
	bool is_crc = false;
	const char *name;
	char *namespace;

	if ((!is_vmlinux(mod->name) || mod->is_dot_o) &&
	    strstarts(symname, "__ksymtab"))
@@ -745,9 +758,7 @@ static void handle_modversions(struct module *mod, struct elf_info *info,
		/* All exported symbols */
		if (strstarts(symname, "__ksymtab_")) {
			name = symname + strlen("__ksymtab_");
			namespace = sym_extract_namespace(&name);
			sym_add_exported(name, namespace, mod, export);
			free(namespace);
			sym_add_exported(name, mod, export);
		}
		if (strcmp(symname, "init_module") == 0)
			mod->has_init = 1;
@@ -2043,6 +2054,16 @@ static void read_symbols(const char *modname)
		handle_moddevtable(mod, &info, sym, symname);
	}

	/* Apply symbol namespaces from __kstrtabns_<symbol> entries. */
	for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
		symname = remove_dot(info.strtab + sym->st_name);

		if (strstarts(symname, "__kstrtabns_"))
			sym_update_namespace(symname + strlen("__kstrtabns_"),
					     namespace_from_kstrtabns(&info,
								      sym));
	}

	// check for static EXPORT_SYMBOL_* functions && global vars
	for (sym = info.symtab_start; sym < info.symtab_stop; sym++) {
		unsigned char bind = ELF_ST_BIND(sym->st_info);
@@ -2196,7 +2217,7 @@ static int check_exports(struct module *mod)
		else
			basename = mod->name;

		if (exp->namespace && exp->namespace[0]) {
		if (exp->namespace) {
			add_namespace(&mod->required_namespaces,
				      exp->namespace);

@@ -2454,12 +2475,12 @@ static void read_dump(const char *fname, unsigned int kernel)
			mod = new_module(modname);
			mod->skip = 1;
		}
		s = sym_add_exported(symname, namespace, mod,
				     export_no(export));
		s = sym_add_exported(symname, mod, export_no(export));
		s->kernel    = kernel;
		s->preloaded = 1;
		s->is_static = 0;
		sym_update_crc(symname, mod, crc, export_no(export));
		sym_update_namespace(symname, namespace);
	}
	release_file(file, size);
	return;
+1 −0
Original line number Diff line number Diff line
@@ -143,6 +143,7 @@ struct elf_info {
	Elf_Section  export_gpl_sec;
	Elf_Section  export_unused_gpl_sec;
	Elf_Section  export_gpl_future_sec;
	char	     *ksymtab_strings;
	char         *strtab;
	char	     *modinfo;
	unsigned int modinfo_len;
+1 −1
Original line number Diff line number Diff line
@@ -33,7 +33,7 @@ generate_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"`
					      | 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