modpost_external_module_updates_sles9.patch 8.96 KiB
This patch updates the SLES 9 module build system to properly support
dependencies between external modules, similarly to the way they are
supported in newer kernels.
Index: linux-2.6.5-7.286/scripts/Makefile.modpost
===================================================================
--- linux-2.6.5-7.286.orig/scripts/Makefile.modpost
+++ linux-2.6.5-7.286/scripts/Makefile.modpost
@@ -38,7 +38,8 @@ _modpost: __modpost
include .config
include scripts/Makefile.lib
-symverfile := $(objtree)/Module.symvers
+kernelsymfile := $(objtree)/Module.symvers
+modulesymfile := $(KBUILD_EXTMOD)/Module.symvers
# Step 1), find all modules listed in $(MODVERDIR)/
__modules := $(shell head -q -n1 /dev/null $(wildcard $(MODVERDIR)/*.mod))
@@ -51,7 +52,9 @@ _modpost: $(modules)
# Includes step 3,4
quiet_cmd_modpost = MODPOST
cmd_modpost = scripts/modpost \
- $(if $(KBUILD_EXTMOD),-i,-o) $(symverfile) \
+ $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \
+ $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \
+ $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
-s $(firstword $(wildcard $(dir $(MODVERDIR))/Module.supported \
$(objtree)/Module.supported /dev/null)) \
$(filter-out FORCE,$^)
Index: linux-2.6.5-7.286/scripts/modpost.c
===================================================================
--- linux-2.6.5-7.286.orig/scripts/modpost.c
+++ linux-2.6.5-7.286/scripts/modpost.c
@@ -1,7 +1,8 @@
/* Postprocess module symbol versions
*
* Copyright 2003 Kai Germaschewski
- * 2002-2003 Rusty Russell, IBM Corporation
+ * 2002-2004 Rusty Russell, IBM Corporation
+ * Copyright 2006 Sam Ravnborg
*
* Based in part on module-init-tools/depmod.c,file2alias
*
@@ -18,6 +19,8 @@
int modversions = 0;
/* Warn about undefined symbols? (do so if we have vmlinux) */
int have_vmlinux = 0;
+/* If we are modposting external module set to 1 */
+static int external_module = 0;
void
fatal(const char *fmt, ...)
@@ -45,6 +48,19 @@ warn(const char *fmt, ...)
va_end(arglist);
}
+int
+is_vmlinux(const char *modname)
+{
+ const char *myname;
+
+ if ((myname = strrchr(modname, '/')))
+ myname++;
+ else
+ myname = modname;
+
+ return strcmp(myname, "vmlinux") == 0;
+}
+
void *do_nofail(void *ptr, const char *expr)
{
if (!ptr) {
@@ -101,6 +117,9 @@ struct symbol {
struct module *module;
unsigned int crc;
int crc_valid;
+ unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */
+ unsigned int kernel:1; /* 1 if symbol is from kernel
+ * (only for external modules) **/
char name[0];
};
@@ -135,8 +154,8 @@ alloc_symbol(const char *name, struct sy
/* For the hash of exported symbols */
-void
-new_symbol(const char *name, struct module *module, unsigned int *crc)
+static struct symbol *
+new_symbol(const char *name, struct module *module)
{
unsigned int hash;
struct symbol *new;
@@ -144,10 +163,7 @@ new_symbol(const char *name, struct modu
hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
new = symbolhash[hash] = alloc_symbol(name, symbolhash[hash]);
new->module = module;
- if (crc) {
- new->crc = *crc;
- new->crc_valid = 1;
- }
+ return new;
}
struct symbol *
@@ -168,19 +184,28 @@ find_symbol(const char *name)
/* Add an exported symbol - it may have already been added without a
* CRC, in this case just update the CRC */
-void
-add_exported_symbol(const char *name, struct module *module, unsigned int *crc)
+static struct symbol *
+sym_add_exported(const char *name, struct module *mod)
{
struct symbol *s = find_symbol(name);
if (!s) {
- new_symbol(name, module, crc);
- return;
- }
- if (crc) {
- s->crc = *crc;
- s->crc_valid = 1;
+ s = new_symbol(name, mod);
}
+ s->vmlinux = is_vmlinux(mod->name);
+ s->kernel = 0;
+ return s;
+}
+
+static void
+sym_update_crc(const char *name, struct module *mod, unsigned int crc)
+{
+ struct symbol *s = find_symbol(name);
+
+ if (!s)
+ s = new_symbol(name, mod);
+ s->crc = crc;
+ s->crc_valid = 1;
}
void *
@@ -339,8 +364,7 @@ handle_modversions(struct module *mod, s
/* CRC'd symbol */
if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
crc = (unsigned int) sym->st_value;
- add_exported_symbol(symname + strlen(CRC_PFX),
- mod, &crc);
+ sym_update_crc(symname + strlen(CRC_PFX), mod, crc);
modversions = 1;
}
break;
@@ -372,26 +396,12 @@ handle_modversions(struct module *mod, s
default:
/* All exported symbols */
if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
- add_exported_symbol(symname + strlen(KSYMTAB_PFX),
- mod, NULL);
+ sym_add_exported(symname + strlen(KSYMTAB_PFX), mod);
}
break;
}
}
-int
-is_vmlinux(const char *modname)
-{
- const char *myname;
-
- if ((myname = strrchr(modname, '/')))
- myname++;
- else
- myname = modname;
-
- return strcmp(myname, "vmlinux") == 0;
-}
-
static struct {
void *file;
unsigned long size;
@@ -451,12 +461,7 @@ read_symbols(char *modname)
/* When there's no vmlinux, don't print warnings about
* unresolved symbols (since there'll be too many ;) */
if (is_vmlinux(modname)) {
- unsigned int fake_crc = 0;
have_vmlinux = 1;
- /* May not have this if !CONFIG_MODULE_UNLOAD: fake it.
- If it appears, we'll get the real CRC. */
- add_exported_symbol("cleanup_module", mod, &fake_crc);
- add_exported_symbol("struct_module", mod, &fake_crc);
mod->skip = 1;
}
@@ -499,12 +504,7 @@ buf_printf(struct buffer *buf, const cha
va_start(ap, fmt);
len = vsnprintf(tmp, SZ, fmt, ap);
- if (buf->size - buf->pos < len + 1) {
- buf->size += 128;
- buf->p = realloc(buf->p, buf->size);
- }
- strncpy(buf->p + buf->pos, tmp, len + 1);
- buf->pos += len;
+ buf_write(buf, tmp, len);
va_end(ap);
}
@@ -512,7 +512,7 @@ void
buf_write(struct buffer *buf, const char *s, int len)
{
if (buf->size - buf->pos < len) {
- buf->size += len;
+ buf->size += len + SZ;
buf->p = realloc(buf->p, buf->size);
}
strncpy(buf->p + buf->pos, s, len);
@@ -522,7 +522,7 @@ buf_write(struct buffer *buf, const char
/* Header for the generated file */
void
-add_header(struct buffer *b)
+add_header(struct buffer *b, struct module *mod)
{
buf_printf(b, "#include <linux/module.h>\n");
buf_printf(b, "#include <linux/vermagic.h>\n");
@@ -676,8 +676,11 @@ read_supported(const char *fname)
; /* ignore error */
}
+/* parse Module.symvers file. line format:
+ * 0x12345678<tab>symbol<tab>module[<tab>something]
+ **/
void
-read_dump(const char *fname)
+read_dump(const char *fname, unsigned int kernel)
{
unsigned long size, pos = 0;
void *file = grab_file(fname, &size);
@@ -691,6 +694,7 @@ read_dump(const char *fname)
char *symname, *modname, *d;
unsigned int crc;
struct module *mod;
+ struct symbol *s;
if (!(symname = strchr(line, '\t')))
goto fail;
@@ -712,13 +716,29 @@ read_dump(const char *fname)
mod = new_module(NOFAIL(strdup(modname)));
mod->skip = 1;
}
- add_exported_symbol(symname, mod, &crc);
+ s = sym_add_exported(symname, mod);
+ s->kernel = kernel;
+ sym_update_crc(symname, mod, crc);
}
return;
fail:
fatal("parse error in symbol dump file\n");
}
+/* For normal builds always dump all symbols.
+ * For external modules only dump symbols
+ * that are not read from kernel Module.symvers.
+ **/
+static int
+dump_sym(struct symbol *sym)
+{
+ if (!external_module)
+ return 1;
+ if (sym->vmlinux || sym->kernel)
+ return 0;
+ return 1;
+}
+
void
write_dump(const char *fname)
{
@@ -729,15 +749,10 @@ write_dump(const char *fname)
for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
symbol = symbolhash[n];
while (symbol) {
- symbol = symbol->next;
- }
- }
-
- for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
- symbol = symbolhash[n];
- while (symbol) {
- buf_printf(&buf, "0x%08x\t%s\t%s\n", symbol->crc,
- symbol->name, symbol->module->name);
+ if (dump_sym(symbol))
+ buf_printf(&buf, "0x%08x\t%s\t%s\n",
+ symbol->crc, symbol->name,
+ symbol->module->name);
symbol = symbol->next;
}
}
@@ -750,14 +765,19 @@ main(int argc, char **argv)
struct module *mod;
struct buffer buf = { };
char fname[SZ];
- char *dump_read = NULL, *dump_write = NULL;
+ char *kernel_read = NULL, *module_read = NULL;
+ char *dump_write = NULL;
char *supp = NULL;
int opt;
- while ((opt = getopt(argc, argv, "i:o:s:")) != -1) {
+ while ((opt = getopt(argc, argv, "i:I:o:s:")) != -1) {
switch(opt) {
case 'i':
- dump_read = optarg;
+ kernel_read = optarg;
+ break;
+ case 'I':
+ module_read = optarg;
+ external_module = 1;
break;
case 'o':
dump_write = optarg;
@@ -773,8 +793,10 @@ main(int argc, char **argv)
if (supp)
read_supported(supp);
- if (dump_read)
- read_dump(dump_read);
+ if (kernel_read)
+ read_dump(kernel_read, 1);
+ if (module_read)
+ read_dump(module_read, 0);
while (optind < argc) {
read_symbols(argv[optind++]);
@@ -786,7 +808,7 @@ main(int argc, char **argv)
buf.pos = 0;
- add_header(&buf);
+ add_header(&buf, mod);
add_supported_flag(&buf, mod);
add_versions(&buf, mod);
add_depends(&buf, mod, modules);