--- zzzz-none-000/linux-2.6.28.10/kernel/module.c 2009-05-02 18:54:43.000000000 +0000 +++ fusiv-7390-686/linux-2.6.28.10/kernel/module.c 2016-11-17 19:50:27.000000000 +0000 @@ -51,6 +51,7 @@ #include #include #include +#include #if 0 #define DEBUGP printk @@ -295,8 +296,11 @@ return false; if (!fsa->gplok) { - if (syms->licence == GPL_ONLY) + if (syms->licence == GPL_ONLY) { + printk(KERN_ERR "Symbol %s can not be used " + "by a non-GPL module\n", fsa->name); return false; + } if (syms->licence == WILL_BE_GPL_ONLY && fsa->warn) { printk(KERN_WARNING "Symbol %s is being used " "by a non-GPL module, which will not " @@ -568,6 +572,7 @@ MODINFO_ATTR(srcversion); static char last_unloaded_module[MODULE_NAME_LEN+1]; +static unsigned long last_unloaded_module_jiffies; #ifdef CONFIG_MODULE_UNLOAD /* Init the unload section of the module. */ @@ -812,6 +817,7 @@ mutex_lock(&module_mutex); /* Store the name of the last unloaded module for diagnostic purposes */ strlcpy(last_unloaded_module, mod->name, sizeof(last_unloaded_module)); + last_unloaded_module_jiffies = jiffies; unregister_dynamic_debug_module(mod->name); free_module(mod); @@ -995,9 +1001,9 @@ goto bad_version; } - printk(KERN_WARNING "%s: no symbol version for %s\n", - mod->name, symname); - return 0; +/* Not in module's version table. OK, but that taints the kernel. */ + add_taint_module(mod, TAINT_FORCED_MODULE); + return 1; bad_version: printk("%s: disagrees about version of symbol %s\n", @@ -1459,6 +1465,11 @@ /* Free lock-classes: */ lockdep_free_key_range(mod->module_core, mod->core_size); +#if defined(CONFIG_BUG_EXTRA_INFO) + /*--- printk(KERN_INFO"%s -> release_bug_debug_table(%s)\n", __func__, mod->name); ---*/ + release_bug_debug_table(mod->name); +#endif/*--- #if defined(CONFIG_BUG_EXTRA_INFO) ---*/ + /* Finally, free the core (containing the module structure) */ module_free(mod, mod->module_core); } @@ -1559,8 +1570,9 @@ if (ELF_ST_BIND(sym[i].st_info) == STB_WEAK) break; - printk(KERN_WARNING "%s: Unknown symbol %s\n", - mod->name, strtab + sym[i].st_name); + printk(KERN_WARNING "%s: Unknown symbol %s (%ld)\n", + mod->name, strtab + sym[i].st_name, + (long)sym[i].st_value); ret = -ENOENT; break; @@ -1819,9 +1831,9 @@ #endif /* CONFIG_DYNAMIC_PRINTK_DEBUG */ } -static void *module_alloc_update_bounds(unsigned long size) +static void *module_alloc_update_bounds(unsigned long size, char *name, enum _module_alloc_type_ type) { - void *ret = module_alloc(size); + void *ret = module_alloc(size, name, type); if (ret) { /* Update module bounds. */ @@ -1832,6 +1844,23 @@ } return ret; } +#if defined(CONFIG_BUG_EXTRA_INFO) + +/*--------------------------------------------------------------------------------*\ +\*--------------------------------------------------------------------------------*/ +static void __register_module_bugtable(struct module *mod, Elf_Ehdr *hdr, Elf_Shdr *sechdrs, const char *secstrings) { + struct bug_debug_table_entry *bug_info; + unsigned int num_bug_info; + bug_info = section_objs(hdr, sechdrs, secstrings, "__bug_debug_table", + sizeof(struct bug_debug_table_entry), &num_bug_info); + +/*--- printk(KERN_INFO"%s: %s: bug_info_start: %p num=%u\n", __func__, mod->name, bug_info, num_bug_info); ---*/ + if(num_bug_info && bug_info) { + register_bug_debug_table(mod->name, (unsigned long)bug_info, (unsigned long)&bug_info[num_bug_info]); + } +} +#endif/*--- #if defined(CONFIG_BUG_EXTRA_INFO) ---*/ + /* Allocate and load the module: note that size of section 0 is always zero, and we rely on this for optional sections. */ @@ -2010,7 +2039,7 @@ layout_sections(mod, hdr, sechdrs, secstrings); /* Do the allocs. */ - ptr = module_alloc_update_bounds(mod->core_size); + ptr = module_alloc_update_bounds(mod->core_size, mod->name, module_alloc_type_core); if (!ptr) { err = -ENOMEM; goto free_percpu; @@ -2018,7 +2047,7 @@ memset(ptr, 0, mod->core_size); mod->module_core = ptr; - ptr = module_alloc_update_bounds(mod->init_size); + ptr = module_alloc_update_bounds(mod->init_size, mod->name, module_alloc_type_init); if (!ptr && mod->init_size) { err = -ENOMEM; goto free_core; @@ -2254,6 +2283,9 @@ (void *)sechdrs[unwindex].sh_addr, sechdrs[unwindex].sh_size); +#if defined(CONFIG_BUG_EXTRA_INFO) + __register_module_bugtable(mod, hdr, sechdrs, secstrings); +#endif/*--- #if defined(CONFIG_BUG_EXTRA_INFO) ---*/ /* Get rid of temporary copy */ vfree(hdr); @@ -2407,10 +2439,17 @@ && !is_arm_mapping_symbol(mod->strtab + mod->symtab[i].st_name)) nextval = mod->symtab[i].st_value; } - - if (!best) - return NULL; - + if (!best) { + /*--- komplett abgestripptes Modul ---*/ + if (within(addr, mod->module_init, mod->init_size)) { + if(size) *size = mod->init_size; + if (offset) *offset = addr - (unsigned long)mod->module_init; + } else { + if(size) *size = mod->core_text_size; + if (offset) *offset = addr - (unsigned long)mod->module_core; + } + return mod->name; + } if (size) *size = nextval - mod->symtab[best].st_value; if (offset) @@ -2748,8 +2787,11 @@ list_for_each_entry_rcu(mod, &modules, list) printk(" %s%s", mod->name, module_flags(mod, buf)); preempt_enable(); - if (last_unloaded_module[0]) - printk(" [last unloaded: %s]", last_unloaded_module); + if (last_unloaded_module[0]) { + struct timespec sincetime; + jiffies_to_timespec(jiffies - last_unloaded_module_jiffies, &sincetime); + printk(" [last unloaded: %s before %lu.%03lu s]", last_unloaded_module, sincetime.tv_sec, sincetime.tv_nsec / (1000* 1000)); + } printk("\n"); }