Name: Remove pointer from module symbols Author: Rusty Russell Depends: Status: Tested lightly on 2.5.59 D: This reverts to Kai's original code, which didn't use a pointer, but D: relied on link ordering to keep the strings and structures in sync. D: I misunderstood: Richard Henderson says that way was fine. diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .15242-linux-2.5-bk/include/asm-generic/vmlinux.lds.h .15242-linux-2.5-bk.updated/include/asm-generic/vmlinux.lds.h --- .15242-linux-2.5-bk/include/asm-generic/vmlinux.lds.h 2003-02-04 15:04:39.000000000 +1100 +++ .15242-linux-2.5-bk.updated/include/asm-generic/vmlinux.lds.h 2003-02-04 17:34:56.000000000 +1100 @@ -12,20 +12,33 @@ *(.rodata1) \ } \ \ - /* Kernel symbol table: Normal symbols */ \ + /* Kernel symbol values: Normal symbols */ \ __ksymtab : AT(ADDR(__ksymtab) - LOAD_OFFSET) { \ __start___ksymtab = .; \ *(__ksymtab) \ __stop___ksymtab = .; \ } \ \ - /* Kernel symbol table: GPL-only symbols */ \ + /* Kernel symbol names: Normal symbols */ \ + __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ + __start___ksymtab_strings = .; \ + *(__ksymtab_strings) \ + } \ + \ + /* Kernel symbol values: GPL-only symbols */ \ __ksymtab_gpl : AT(ADDR(__ksymtab_gpl) - LOAD_OFFSET) { \ __start___ksymtab_gpl = .; \ *(__ksymtab_gpl) \ __stop___ksymtab_gpl = .; \ } \ \ + /* Kernel symbol names: GPL-only symbols */ \ + __ksymtab_strings_gpl \ + : AT(ADDR(__ksymtab_strings_gpl) - LOAD_OFFSET) { \ + __start___ksymtab_strings_gpl = .; \ + *(__ksymtab_strings_gpl) \ + } \ + \ /* Kernel symbol table: Normal symbols */ \ __kcrctab : AT(ADDR(__kcrctab) - LOAD_OFFSET) { \ __start___kcrctab = .; \ @@ -38,10 +51,5 @@ __start___kcrctab_gpl = .; \ *(__kcrctab_gpl) \ __stop___kcrctab_gpl = .; \ - } \ - \ - /* Kernel symbol table: strings */ \ - __ksymtab_strings : AT(ADDR(__ksymtab_strings) - LOAD_OFFSET) { \ - *(__ksymtab_strings) \ } diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .15242-linux-2.5-bk/include/linux/module.h .15242-linux-2.5-bk.updated/include/linux/module.h --- .15242-linux-2.5-bk/include/linux/module.h 2003-02-04 15:04:44.000000000 +1100 +++ .15242-linux-2.5-bk.updated/include/linux/module.h 2003-02-04 17:36:53.000000000 +1100 @@ -34,12 +34,6 @@ #define MODULE_NAME_LEN (64 - sizeof(unsigned long)) -struct kernel_symbol -{ - unsigned long value; - const char *name; -}; - struct modversion_info { unsigned long crc; @@ -125,7 +119,8 @@ struct kernel_symbol_group int gplonly; unsigned int num_syms; - const struct kernel_symbol *syms; + const unsigned long *sym_values; + const char *sym_names; const unsigned long *crcs; }; @@ -171,11 +166,11 @@ void *__symbol_get_gpl(const char *symbo #define __EXPORT_SYMBOL(sym, sec) \ __CRC_SYMBOL(sym, sec) \ static const char __kstrtab_##sym[] \ - __attribute__((section("__ksymtab_strings"))) \ + __attribute__((section("__ksymtab_strings" sec))) \ = MODULE_SYMBOL_PREFIX #sym; \ - static const struct kernel_symbol __ksymtab_##sym \ + static const unsigned long __ksymtab_##sym \ __attribute__((section("__ksymtab" sec), unused)) \ - = { (unsigned long)&sym, __kstrtab_##sym } + = (unsigned long)&sym #define EXPORT_SYMBOL(sym) \ __EXPORT_SYMBOL(sym, "") diff -urpN --exclude TAGS -X /home/rusty/devel/kernel/kernel-patches/current-dontdiff --minimal .15242-linux-2.5-bk/kernel/module.c .15242-linux-2.5-bk.updated/kernel/module.c --- .15242-linux-2.5-bk/kernel/module.c 2003-02-04 15:05:22.000000000 +1100 +++ .15242-linux-2.5-bk.updated/kernel/module.c 2003-02-04 17:38:06.000000000 +1100 @@ -85,16 +85,21 @@ static unsigned long __find_symbol(const list_for_each_entry(ks, &symbols, list) { unsigned int i; + const char *names; if (ks->gplonly && !gplok) continue; - for (i = 0; i < ks->num_syms; i++) { - if (strcmp(ks->syms[i].name, name) == 0) { + for (i = 0, names = ks->sym_names; i < ks->num_syms; i++) { + /* Can have extra zero padding */ + while (!names[0]) + names++; + if (strcmp(names, name) == 0) { *group = ks; if (symidx) *symidx = i; - return ks->syms[i].value; + return ks->sym_values[i]; } + names += strlen(names) + 1; } } DEBUGP("Failed to find symbol %s\n", name); @@ -540,7 +545,7 @@ void symbol_put_addr(void *addr) unsigned int i; for (i = 0; i < ks->num_syms; i++) { - if (ks->syms[i].value == (unsigned long)addr) { + if (ks->sym_values[i] == (unsigned long)addr) { module_put(ks->owner); spin_unlock_irqrestore(&modlist_lock, flags); return; @@ -1050,7 +1055,7 @@ static struct module *load_module(void * char *secstrings, *args; unsigned int i, symindex, exportindex, strindex, setupindex, exindex, modindex, obsparmindex, licenseindex, gplindex, vmagindex, - crcindex, gplcrcindex, versindex; + crcindex, gplcrcindex, versindex, exstrindex, gplstrindex; long arglen; struct module *mod; long err = 0; @@ -1087,7 +1092,8 @@ static struct module *load_module(void * /* May not export symbols, or have setup params, so these may not exist */ exportindex = setupindex = obsparmindex = gplindex = licenseindex - = crcindex = gplcrcindex = versindex = 0; + = crcindex = gplcrcindex = versindex = exstrindex = gplstrindex + = 0; /* And these should exist, but gcc whinges if we don't init them */ symindex = strindex = exindex = modindex = vmagindex = 0; @@ -1130,6 +1136,16 @@ static struct module *load_module(void * /* Exported symbols CRCs. (GPL)*/ DEBUGP("CRC table in section %u\n", i); gplcrcindex = i; + } else if (strcmp(secstrings+sechdrs[i].sh_name, + "__ksymtab_strings") == 0) { + /* Names of exported symbols. */ + DEBUGP("Symbol names found in section %u\n", i); + exstrindex = i; + } else if (strcmp(secstrings+sechdrs[i].sh_name, + "__ksymtab_strings_gpl") == 0) { + /* Names of exported symbols. (GPL) */ + DEBUGP("GPL symbol names found in section %u\n", i); + gplstrindex = i; } else if (strcmp(secstrings+sechdrs[i].sh_name, "__param") == 0) { /* Setup parameter info */ @@ -1282,14 +1298,16 @@ static struct module *load_module(void * /* Set up EXPORTed & EXPORT_GPLed symbols (section 0 is 0 length) */ mod->symbols.num_syms = (sechdrs[exportindex].sh_size - / sizeof(*mod->symbols.syms)); - mod->symbols.syms = (void *)sechdrs[exportindex].sh_addr; + / sizeof(*mod->symbols.sym_values)); + mod->symbols.sym_values = (void *)sechdrs[exportindex].sh_addr; + mod->symbols.sym_names = (void *)sechdrs[exstrindex].sh_addr; if (crcindex) mod->symbols.crcs = (void *)sechdrs[crcindex].sh_addr; mod->gpl_symbols.num_syms = (sechdrs[gplindex].sh_size - / sizeof(*mod->symbols.syms)); - mod->gpl_symbols.syms = (void *)sechdrs[gplindex].sh_addr; + / sizeof(*mod->symbols.sym_values)); + mod->gpl_symbols.sym_values = (void *)sechdrs[gplindex].sh_addr; + mod->gpl_symbols.sym_names = (void *)sechdrs[gplstrindex].sh_addr; if (gplcrcindex) mod->gpl_symbols.crcs = (void *)sechdrs[gplcrcindex].sh_addr; @@ -1599,10 +1617,12 @@ int module_text_address(unsigned long ad } /* Provided by the linker */ -extern const struct kernel_symbol __start___ksymtab[]; -extern const struct kernel_symbol __stop___ksymtab[]; -extern const struct kernel_symbol __start___ksymtab_gpl[]; -extern const struct kernel_symbol __stop___ksymtab_gpl[]; +extern const unsigned long __start___ksymtab[]; +extern const unsigned long __stop___ksymtab[]; +extern const char __start___ksymtab_strings[]; +extern const unsigned long __start___ksymtab_gpl[]; +extern const unsigned long __stop___ksymtab_gpl[]; +extern const char __start___ksymtab_strings_gpl[]; extern const unsigned long __start___kcrctab[]; extern const unsigned long __stop___kcrctab[]; extern const unsigned long __start___kcrctab_gpl[]; @@ -1614,14 +1634,16 @@ static int __init symbols_init(void) { /* Add kernel symbols to symbol table */ kernel_symbols.num_syms = (__stop___ksymtab - __start___ksymtab); - kernel_symbols.syms = __start___ksymtab; + kernel_symbols.sym_values = __start___ksymtab; + kernel_symbols.sym_names = __start___ksymtab_strings; kernel_symbols.crcs = __start___kcrctab; kernel_symbols.gplonly = 0; list_add(&kernel_symbols.list, &symbols); kernel_gpl_symbols.num_syms = (__stop___ksymtab_gpl - __start___ksymtab_gpl); - kernel_gpl_symbols.syms = __start___ksymtab_gpl; + kernel_gpl_symbols.sym_values = __start___ksymtab_gpl; + kernel_gpl_symbols.sym_names = __start___ksymtab_strings_gpl; kernel_gpl_symbols.crcs = __start___kcrctab_gpl; kernel_gpl_symbols.gplonly = 1; list_add(&kernel_gpl_symbols.list, &symbols);