Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 414fd31b authored by Tim Abbott's avatar Tim Abbott Committed by Rusty Russell
Browse files

module: Make find_symbol return a struct kernel_symbol



Impact: Cleanup, internal API change

Ksplice needs access to the kernel_symbol structure in order to support
modifications to the exported symbol table.

Cc: Anders Kaseorg <andersk@mit.edu>
Cc: Jeff Arnold <jbarnold@mit.edu>
Signed-off-by: default avatarTim Abbott <tabbott@mit.edu>
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> (bugfix and style)
parent b10153fe
Loading
Loading
Loading
Loading
+37 −38
Original line number Diff line number Diff line
@@ -283,7 +283,7 @@ struct find_symbol_arg {
	/* Output */
	struct module *owner;
	const unsigned long *crc;
	unsigned long value;
	const struct kernel_symbol *sym;
};

static bool find_symbol_in_section(const struct symsearch *syms,
@@ -324,13 +324,13 @@ static bool find_symbol_in_section(const struct symsearch *syms,

	fsa->owner = owner;
	fsa->crc = symversion(syms->crcs, symnum);
	fsa->value = syms->start[symnum].value;
	fsa->sym = &syms->start[symnum];
	return true;
}

/* Find a symbol, return value, (optional) crc and (optional) module
 * which owns it */
static unsigned long find_symbol(const char *name,
/* Find a symbol and return it, along with, (optional) crc and
 * (optional) module which owns it */
static const struct kernel_symbol *find_symbol(const char *name,
					       struct module **owner,
					       const unsigned long **crc,
					       bool gplok,
@@ -347,11 +347,11 @@ static unsigned long find_symbol(const char *name,
			*owner = fsa.owner;
		if (crc)
			*crc = fsa.crc;
		return fsa.value;
		return fsa.sym;
	}

	DEBUGP("Failed to find symbol %s\n", name);
	return -ENOENT;
	return NULL;
}

/* Search for module by name: must hold module_mutex. */
@@ -894,7 +894,7 @@ void __symbol_put(const char *symbol)
	struct module *owner;

	preempt_disable();
	if (IS_ERR_VALUE(find_symbol(symbol, &owner, NULL, true, false)))
	if (!find_symbol(symbol, &owner, NULL, true, false))
		BUG();
	module_put(owner);
	preempt_enable();
@@ -1057,7 +1057,7 @@ static inline int check_modstruct_version(Elf_Shdr *sechdrs,
{
	const unsigned long *crc;

	if (IS_ERR_VALUE(find_symbol("struct_module", NULL, &crc, true, false)))
	if (!find_symbol("struct_module", NULL, &crc, true, false))
		BUG();
	return check_version(sechdrs, versindex, "struct_module", mod, crc);
}
@@ -1098,25 +1098,25 @@ static inline int same_magic(const char *amagic, const char *bmagic,

/* Resolve a symbol for this module.  I.e. if we find one, record usage.
   Must be holding module_mutex. */
static unsigned long resolve_symbol(Elf_Shdr *sechdrs,
static const struct kernel_symbol *resolve_symbol(Elf_Shdr *sechdrs,
						  unsigned int versindex,
						  const char *name,
						  struct module *mod)
{
	struct module *owner;
	unsigned long ret;
	const struct kernel_symbol *sym;
	const unsigned long *crc;

	ret = find_symbol(name, &owner, &crc,
	sym = find_symbol(name, &owner, &crc,
			  !(mod->taints & (1 << TAINT_PROPRIETARY_MODULE)), true);
	if (!IS_ERR_VALUE(ret)) {
	/* use_module can fail due to OOM,
	   or module initialization or unloading */
	if (sym) {
		if (!check_version(sechdrs, versindex, name, mod, crc) ||
		    !use_module(mod, owner))
			ret = -EINVAL;
			sym = NULL;
	}
	return ret;
	return sym;
}

/*
@@ -1516,17 +1516,15 @@ static void free_module(struct module *mod)
void *__symbol_get(const char *symbol)
{
	struct module *owner;
	unsigned long value;
	const struct kernel_symbol *sym;

	preempt_disable();
	value = find_symbol(symbol, &owner, NULL, true, true);
	if (IS_ERR_VALUE(value))
		value = 0;
	else if (strong_try_module_get(owner))
		value = 0;
	sym = find_symbol(symbol, &owner, NULL, true, true);
	if (sym && strong_try_module_get(owner))
		sym = NULL;
	preempt_enable();

	return (void *)value;
	return sym ? (void *)sym->value : NULL;
}
EXPORT_SYMBOL_GPL(__symbol_get);

@@ -1554,8 +1552,7 @@ static int verify_export_symbols(struct module *mod)

	for (i = 0; i < ARRAY_SIZE(arr); i++) {
		for (s = arr[i].sym; s < arr[i].sym + arr[i].num; s++) {
			if (!IS_ERR_VALUE(find_symbol(s->name, &owner,
						      NULL, true, false))) {
			if (find_symbol(s->name, &owner, NULL, true, false)) {
				printk(KERN_ERR
				       "%s: exports duplicate symbol %s"
				       " (owned by %s)\n",
@@ -1579,6 +1576,7 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
	unsigned long secbase;
	unsigned int i, n = sechdrs[symindex].sh_size / sizeof(Elf_Sym);
	int ret = 0;
	const struct kernel_symbol *ksym;

	for (i = 1; i < n; i++) {
		switch (sym[i].st_shndx) {
@@ -1598,13 +1596,14 @@ static int simplify_symbols(Elf_Shdr *sechdrs,
			break;

		case SHN_UNDEF:
			sym[i].st_value
			  = resolve_symbol(sechdrs, versindex,
			ksym = resolve_symbol(sechdrs, versindex,
					      strtab + sym[i].st_name, mod);

			/* Ok if resolved.  */
			if (!IS_ERR_VALUE(sym[i].st_value))
			if (ksym) {
				sym[i].st_value = ksym->value;
				break;
			}

			/* Ok if weak.  */
			if (ELF_ST_BIND(sym[i].st_info) == STB_WEAK)
				break;