📄 modpost_external_module_updates_rhel4.patch
字号:
This patch updates the RHEL 4 module build system to properly supportdependencies between external modules, similarly to the way they aresupported in newer kernels.Index: linux-2.6.9-55.EL/scripts/Makefile.modpost===================================================================--- linux-2.6.9-55.EL.orig/scripts/Makefile.modpost+++ linux-2.6.9-55.EL/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 := $(sort $(shell grep -h '\.ko' /dev/null $(wildcard $(MODVERDIR)/*.mod)))@@ -52,7 +53,9 @@ _modpost: $(modules) quiet_cmd_modpost = MODPOST cmd_modpost = scripts/mod/modpost \ $(if $(CONFIG_MODVERSIONS),-m) \- $(if $(KBUILD_EXTMOD),-i,-o) $(symverfile) \+ $(if $(KBUILD_EXTMOD),-i,-o) $(kernelsymfile) \+ $(if $(KBUILD_EXTMOD),-I $(modulesymfile)) \+ $(if $(KBUILD_EXTMOD),-o $(modulesymfile)) \ $(filter-out FORCE,$^) .PHONY: __modpostIndex: linux-2.6.9-55.EL/scripts/mod/modpost.c===================================================================--- linux-2.6.9-55.EL.orig/scripts/mod/modpost.c+++ linux-2.6.9-55.EL/scripts/mod/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 *file, int line, const char *expr) { if (!ptr) {@@ -102,6 +118,10 @@ 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) **/+ unsigned int preloaded:1; /* 1 if symbol from Module.symvers */ char name[0]; }; @@ -136,8 +156,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;@@ -145,10 +165,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 *@@ -169,19 +186,29 @@ 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->preloaded = 0;+ 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 *@@ -341,13 +368,13 @@ 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); } break; case SHN_UNDEF: /* undefined symbol */- if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL)+ if (ELF_ST_BIND(sym->st_info) != STB_GLOBAL &&+ ELF_ST_BIND(sym->st_info) != STB_WEAK) break; /* ignore global offset table */ if (strcmp(symname, "_GLOBAL_OFFSET_TABLE_") == 0)@@ -373,8 +400,7 @@ 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); } if (strcmp(symname, MODULE_SYMBOL_PREFIX "init_module") == 0) mod->has_init = 1;@@ -384,19 +410,6 @@ handle_modversions(struct module *mod, s } } -int-is_vmlinux(const char *modname)-{- const char *myname;-- if ((myname = strrchr(modname, '/')))- myname++;- else- myname = modname;-- return strcmp(myname, "vmlinux") == 0;-}- void read_symbols(char *modname) {@@ -412,9 +425,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;- add_exported_symbol("struct_module", mod, &fake_crc); mod->skip = 1; } @@ -426,6 +437,7 @@ read_symbols(char *modname) } maybe_frob_version(modname, info.modinfo, info.modinfo_len, (void *)info.modinfo - (void *)info.hdr);+ parse_elf_finish(&info); /* Our trick to get versioning for struct_module - it's@@ -451,12 +463,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); } @@ -464,7 +471,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);@@ -506,8 +513,8 @@ add_versions(struct buffer *b, struct mo exp = find_symbol(s->name); if (!exp || exp->module == mod) { if (have_vmlinux)- fprintf(stderr, "*** Warning: \"%s\" [%s.ko] "- "undefined!\n", s->name, mod->name);+ warn("\"%s\" [%s.ko] undefined!\n",+ s->name, mod->name); continue; } s->module = exp->module;@@ -615,8 +622,11 @@ write_if_changed(struct buffer *b, const fclose(file); } +/* parse Module.symvers file. line format:+ * 0x12345678<tab>symbol<tab>module[[<tab>export]<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);@@ -630,6 +640,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;@@ -650,13 +661,30 @@ 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;+ s->preloaded = 1;+ 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) {@@ -667,15 +695,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; } }@@ -688,13 +711,18 @@ 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; int opt; - while ((opt = getopt(argc, argv, "i:mo:")) != -1) {+ while ((opt = getopt(argc, argv, "i:I:mo:")) != -1) { switch(opt) { case 'i':- dump_read = optarg;+ kernel_read = optarg;+ break;+ case 'I':+ module_read = optarg;+ external_module = 1; break; case 'm': modversions = 1;@@ -707,8 +735,10 @@ main(int argc, char **argv) } } - 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++]);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -