1 This patch updates the RHEL 4 module build system to properly support
2 dependencies between external modules, similarly to the way they are
3 supported in newer kernels.
5 Index: linux-2.6.9-55.EL/scripts/Makefile.modpost
6 ===================================================================
7 --- linux-2.6.9-55.EL.orig/scripts/Makefile.modpost
8 +++ linux-2.6.9-55.EL/scripts/Makefile.modpost
9 @@ -38,7 +38,8 @@ _modpost: __modpost
11 include scripts/Makefile.lib
13 -symverfile := $(objtree)/Module.symvers
14 +kernelsymfile := $(objtree)/Module.symvers
15 +modulesymfile := $(KBUILD_EXTMOD)/Module.symvers
17 # Step 1), find all modules listed in $(MODVERDIR)/
18 __modules := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))
19 @@ -52,7 +53,9 @@ _modpost: $(modules)
20 quiet_cmd_modpost = MODPOST
21 cmd_modpost = scripts/mod/modpost \
22 $(if $(CONFIG_MODVERSIONS),-m) \
23 - $(if $(KBUILD_EXTMOD),-i,-o) $(symverfile) \
24 + $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \
25 + $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \
26 + $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \
27 $(filter-out FORCE,$^)
30 Index: linux-2.6.9-55.EL/scripts/mod/modpost.c
31 ===================================================================
32 --- linux-2.6.9-55.EL.orig/scripts/mod/modpost.c
33 +++ linux-2.6.9-55.EL/scripts/mod/modpost.c
35 /* Postprocess module symbol versions
37 * Copyright 2003 Kai Germaschewski
38 - * 2002-2003 Rusty Russell, IBM Corporation
39 + * 2002-2004 Rusty Russell, IBM Corporation
40 + * Copyright 2006 Sam Ravnborg
42 * Based in part on module-init-tools/depmod.c,file2alias
46 /* Warn about undefined symbols? (do so if we have vmlinux) */
48 +/* If we are modposting external module set to 1 */
49 +static int external_module = 0;
52 fatal(const char *fmt, ...)
53 @@ -45,6 +48,19 @@ warn(const char *fmt, ...)
58 +is_vmlinux(const char *modname)
62 + if ((myname = strrchr(modname, '/')))
67 + return strcmp(myname, "vmlinux") == 0;
70 void *do_nofail(void *ptr, const char *file, int line, const char *expr)
73 @@ -102,6 +118,10 @@ struct symbol {
74 struct module *module;
77 + unsigned int vmlinux:1; /* 1 if symbol is defined in vmlinux */
78 + unsigned int kernel:1; /* 1 if symbol is from kernel
79 + * (only for external modules) **/
80 + unsigned int preloaded:1; /* 1 if symbol from Module.symvers */
84 @@ -136,8 +156,8 @@ alloc_symbol(const char *name, struct sy
86 /* For the hash of exported symbols */
89 -new_symbol(const char *name, struct module *module, unsigned int *crc)
90 +static struct symbol *
91 +new_symbol(const char *name, struct module *module)
95 @@ -145,10 +165,7 @@ new_symbol(const char *name, struct modu
96 hash = tdb_hash(name) % SYMBOL_HASH_SIZE;
97 new = symbolhash[hash] = alloc_symbol(name, symbolhash[hash]);
101 - new->crc_valid = 1;
107 @@ -169,19 +186,29 @@ find_symbol(const char *name)
109 /* Add an exported symbol - it may have already been added without a
110 * CRC, in this case just update the CRC */
112 -add_exported_symbol(const char *name, struct module *module, unsigned int *crc)
113 +static struct symbol *
114 +sym_add_exported(const char *name, struct module *mod)
116 struct symbol *s = find_symbol(name);
119 - new_symbol(name, module, crc);
125 + s = new_symbol(name, mod);
128 + s->vmlinux = is_vmlinux(mod->name);
134 +sym_update_crc(const char *name, struct module *mod, unsigned int crc)
136 + struct symbol *s = find_symbol(name);
139 + s = new_symbol(name, mod);
145 @@ -341,13 +368,13 @@ handle_modversions(struct module *mod, s
147 if (memcmp(symname, CRC_PFX, strlen(CRC_PFX)) == 0) {
148 crc = (unsigned int) sym->st_value;
149 - add_exported_symbol(symname + strlen(CRC_PFX),
151 + sym_update_crc(symname + strlen(CRC_PFX), mod, crc);
155 /* undefined symbol */
156 - if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL)
157 + if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&
158 + ELF_ST_BIND(sym->st_info) != STB_WEAK)
160 /* ignore global offset table */
161 if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)
162 @@ -373,8 +400,7 @@ handle_modversions(struct module *mod, s
164 /* All exported symbols */
165 if (memcmp(symname, KSYMTAB_PFX, strlen(KSYMTAB_PFX)) == 0) {
166 - add_exported_symbol(symname + strlen(KSYMTAB_PFX),
168 + sym_add_exported(symname + strlen(KSYMTAB_PFX), mod);
170 if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0)
172 @@ -384,19 +410,6 @@ handle_modversions(struct module *mod, s
177 -is_vmlinux(const char *modname)
179 - const char *myname;
181 - if ((myname = strrchr(modname, '/')))
186 - return strcmp(myname, "vmlinux") == 0;
190 read_symbols(char *modname)
192 @@ -412,9 +425,7 @@ read_symbols(char *modname)
193 /* When there's no vmlinux, don't print warnings about
194 * unresolved symbols (since there'll be too many ;) */
195 if (is_vmlinux(modname)) {
196 - unsigned int fake_crc = 0;
198 - add_exported_symbol("struct_module", mod, &fake_crc);
202 @@ -426,6 +437,7 @@ read_symbols(char *modname)
204 maybe_frob_version(modname, info.modinfo, info.modinfo_len,
205 (void *)info.modinfo - (void *)info.hdr);
207 parse_elf_finish(&info);
209 /* Our trick to get versioning for struct_module - it's
210 @@ -451,12 +463,7 @@ buf_printf(struct buffer *buf, const cha
213 len = vsnprintf(tmp, SZ, fmt, ap);
214 - if (buf->size - buf->pos < len + 1) {
216 - buf->p = realloc(buf->p, buf->size);
218 - strncpy(buf->p + buf->pos, tmp, len + 1);
220 + buf_write(buf, tmp, len);
224 @@ -464,7 +471,7 @@ void
225 buf_write(struct buffer *buf, const char *s, int len)
227 if (buf->size - buf->pos < len) {
229 + buf->size += len + SZ;
230 buf->p = realloc(buf->p, buf->size);
232 strncpy(buf->p + buf->pos, s, len);
233 @@ -506,8 +513,8 @@ add_versions(struct buffer *b, struct mo
234 exp = find_symbol(s->name);
235 if (!exp || exp->module == mod) {
237 - fprintf(stderr, "*** Warning: \"%s\" [%s.ko] "
238 - "undefined!\n", s->name, mod->name);
239 + warn("\"%s\" [%s.ko] undefined!\n",
240 + s->name, mod->name);
243 s->module = exp->module;
244 @@ -615,8 +622,11 @@ write_if_changed(struct buffer *b, const
248 +/* parse Module.symvers file. line format:
249 + * 0x12345678<tab>symbol<tab>module[[<tab>export]<tab>something]
252 -read_dump(const char *fname)
253 +read_dump(const char *fname, unsigned int kernel)
255 unsigned long size, pos = 0;
256 void *file = grab_file(fname, &size);
257 @@ -630,6 +640,7 @@ read_dump(const char *fname)
258 char *symname, *modname, *d;
263 if (!(symname = strchr(line, '\t')))
265 @@ -650,13 +661,30 @@ read_dump(const char *fname)
266 mod = new_module(NOFAIL(strdup(modname)));
269 - add_exported_symbol(symname, mod, &crc);
270 + s = sym_add_exported(symname, mod);
271 + s->kernel = kernel;
273 + sym_update_crc(symname, mod, crc);
277 fatal("parse error in symbol dump file\n");
280 +/* For normal builds always dump all symbols.
281 + * For external modules only dump symbols
282 + * that are not read from kernel Module.symvers.
285 +dump_sym(struct symbol *sym)
287 + if (!external_module)
289 + if (sym->vmlinux || sym->kernel)
295 write_dump(const char *fname)
297 @@ -667,15 +695,10 @@ write_dump(const char *fname)
298 for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
299 symbol = symbolhash[n];
301 - symbol = symbol->next;
305 - for (n = 0; n < SYMBOL_HASH_SIZE ; n++) {
306 - symbol = symbolhash[n];
308 - buf_printf(&buf, "0x%08x\t%s\t%s\n", symbol->crc,
309 - symbol->name, symbol->module->name);
310 + if (dump_sym(symbol))
311 + buf_printf(&buf, "0x%08x\t%s\t%s\n",
312 + symbol->crc, symbol->name,
313 + symbol->module->name);
314 symbol = symbol->next;
317 @@ -688,13 +711,18 @@ main(int argc, char **argv)
319 struct buffer buf = { };
321 - char *dump_read = NULL, *dump_write = NULL;
322 + char *kernel_read = NULL, *module_read = NULL;
323 + char *dump_write = NULL;
326 - while ((opt = getopt(argc, argv, "i:mo:")) != -1) {
327 + while ((opt = getopt(argc, argv, "i:I:mo:")) != -1) {
330 - dump_read = optarg;
331 + kernel_read = optarg;
334 + module_read = optarg;
335 + external_module = 1;
339 @@ -707,8 +735,10 @@ main(int argc, char **argv)
344 - read_dump(dump_read);
346 + read_dump(kernel_read, 1);
348 + read_dump(module_read, 0);
350 while (optind < argc) {
351 read_symbols(argv[optind++]);