diff options
author | Eric Andersen <andersen@codepoet.org> | 2004-06-22 11:50:52 +0000 |
---|---|---|
committer | Eric Andersen <andersen@codepoet.org> | 2004-06-22 11:50:52 +0000 |
commit | cb3b9b1fed3685198fca2e7070a7179288d2def2 (patch) | |
tree | 90ef18eaeff6ffcc02fe101cb6b680517d49111e | |
parent | d943837dab6eb2b2809426c0e81f7b8e8cf82208 (diff) | |
download | busybox-w32-cb3b9b1fed3685198fca2e7070a7179288d2def2.tar.gz busybox-w32-cb3b9b1fed3685198fca2e7070a7179288d2def2.tar.bz2 busybox-w32-cb3b9b1fed3685198fca2e7070a7179288d2def2.zip |
kill off insmod support for older pre 2.1 Linux kernels,
which are not supported with the current busybox 1.0 release
-Erik
-rw-r--r-- | modutils/Config.in | 23 | ||||
-rw-r--r-- | modutils/insmod.c | 534 |
2 files changed, 28 insertions, 529 deletions
diff --git a/modutils/Config.in b/modutils/Config.in index 45569cc8c..3b5c1e37a 100644 --- a/modutils/Config.in +++ b/modutils/Config.in | |||
@@ -11,31 +11,24 @@ config CONFIG_INSMOD | |||
11 | help | 11 | help |
12 | insmod is used to load specified modules in the running kernel. | 12 | insmod is used to load specified modules in the running kernel. |
13 | 13 | ||
14 | config CONFIG_FEATURE_2_2_MODULES | ||
15 | bool " Support older (pre 2.1) Linux kernels" | ||
16 | default n | ||
17 | depends on CONFIG_INSMOD | ||
18 | help | ||
19 | Provide insmod support for older (pre 2.1) Linux kernels. | ||
20 | |||
21 | config CONFIG_FEATURE_2_4_MODULES | 14 | config CONFIG_FEATURE_2_4_MODULES |
22 | bool " Support version 2.1.x to 2.4.x Linux kernels" | 15 | bool " Support version 2.2.x to 2.4.x Linux kernels" |
23 | default y | 16 | default y |
24 | depends on CONFIG_INSMOD && !CONFIG_FEATURE_2_6_MODULES | 17 | depends on CONFIG_INSMOD |
25 | help | 18 | help |
26 | Support module loading for 2.2.x and 2.4.x Linux kernels. | 19 | Support module loading for 2.2.x and 2.4.x Linux kernels. |
27 | 20 | ||
28 | config CONFIG_FEATURE_2_6_MODULES | 21 | config CONFIG_FEATURE_2_6_MODULES |
29 | bool " Support version 2.6.x Linux kernels" | 22 | bool " Support version 2.6.x Linux kernels" |
30 | default n | 23 | default n |
31 | depends on CONFIG_INSMOD && !CONFIG_FEATURE_2_4_MODULES | 24 | depends on CONFIG_INSMOD |
32 | help | 25 | help |
33 | Support module loading for 2.6.x Linux kernels. | 26 | Support module loading for newer 2.6.x Linux kernels. |
34 | 27 | ||
35 | config CONFIG_FEATURE_INSMOD_VERSION_CHECKING | 28 | config CONFIG_FEATURE_INSMOD_VERSION_CHECKING |
36 | bool " Module version checking" | 29 | bool " Module version checking" |
37 | default n | 30 | default n |
38 | depends on CONFIG_INSMOD && ( CONFIG_FEATURE_2_2_MODULES || CONFIG_FEATURE_2_4_MODULES ) | 31 | depends on CONFIG_INSMOD && CONFIG_FEATURE_2_4_MODULES |
39 | help | 32 | help |
40 | Support checking of versions for modules. This is used to | 33 | Support checking of versions for modules. This is used to |
41 | ensure that the kernel and module are made for each other. | 34 | ensure that the kernel and module are made for each other. |
@@ -43,7 +36,7 @@ config CONFIG_FEATURE_INSMOD_VERSION_CHECKING | |||
43 | config CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS | 36 | config CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS |
44 | bool " Add module symbols to kernel symbol table" | 37 | bool " Add module symbols to kernel symbol table" |
45 | default n | 38 | default n |
46 | depends on CONFIG_INSMOD && ( CONFIG_FEATURE_2_2_MODULES || CONFIG_FEATURE_2_4_MODULES ) | 39 | depends on CONFIG_INSMOD && CONFIG_FEATURE_2_4_MODULES |
47 | help | 40 | help |
48 | By adding module symbols to the kernel symbol table, Oops messages | 41 | By adding module symbols to the kernel symbol table, Oops messages |
49 | occuring within kernel modules can be properly debugged. By enabling | 42 | occuring within kernel modules can be properly debugged. By enabling |
@@ -54,7 +47,7 @@ config CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS | |||
54 | config CONFIG_FEATURE_INSMOD_LOADINKMEM | 47 | config CONFIG_FEATURE_INSMOD_LOADINKMEM |
55 | bool " In kernel memory optimization (uClinux only)" | 48 | bool " In kernel memory optimization (uClinux only)" |
56 | default n | 49 | default n |
57 | depends on CONFIG_INSMOD && ( CONFIG_FEATURE_2_2_MODULES || CONFIG_FEATURE_2_4_MODULES ) | 50 | depends on CONFIG_INSMOD && CONFIG_FEATURE_2_4_MODULES |
58 | help | 51 | help |
59 | This is a special uClinux only memory optimization that lets insmod | 52 | This is a special uClinux only memory optimization that lets insmod |
60 | load the specified kernel module directly into kernel space, reducing | 53 | load the specified kernel module directly into kernel space, reducing |
@@ -64,7 +57,7 @@ config CONFIG_FEATURE_INSMOD_LOADINKMEM | |||
64 | config CONFIG_FEATURE_INSMOD_LOAD_MAP | 57 | config CONFIG_FEATURE_INSMOD_LOAD_MAP |
65 | bool " Enable load map (-m) option" | 58 | bool " Enable load map (-m) option" |
66 | default n | 59 | default n |
67 | depends on CONFIG_INSMOD && ( CONFIG_FEATURE_2_2_MODULES || CONFIG_FEATURE_2_4_MODULES ) | 60 | depends on CONFIG_INSMOD && CONFIG_FEATURE_2_4_MODULES |
68 | help | 61 | help |
69 | Enabling this, one would be able to get a load map | 62 | Enabling this, one would be able to get a load map |
70 | output on stdout. This makes kernel module debugging | 63 | output on stdout. This makes kernel module debugging |
diff --git a/modutils/insmod.c b/modutils/insmod.c index d98341e7b..1023d0872 100644 --- a/modutils/insmod.c +++ b/modutils/insmod.c | |||
@@ -83,27 +83,21 @@ | |||
83 | #include "busybox.h" | 83 | #include "busybox.h" |
84 | 84 | ||
85 | #if !defined(CONFIG_FEATURE_2_4_MODULES) && \ | 85 | #if !defined(CONFIG_FEATURE_2_4_MODULES) && \ |
86 | !defined(CONFIG_FEATURE_2_2_MODULES) && \ | ||
87 | !defined(CONFIG_FEATURE_2_6_MODULES) | 86 | !defined(CONFIG_FEATURE_2_6_MODULES) |
88 | #define CONFIG_FEATURE_2_4_MODULES | 87 | #define CONFIG_FEATURE_2_4_MODULES |
89 | #endif | 88 | #endif |
90 | 89 | ||
91 | #if !defined(CONFIG_FEATURE_2_4_MODULES) && !defined(CONFIG_FEATURE_2_2_MODULES) | 90 | #if !defined(CONFIG_FEATURE_2_4_MODULES) |
92 | #define insmod_ng_main insmod_main | 91 | #define insmod_ng_main insmod_main |
93 | #endif | 92 | #endif |
94 | 93 | ||
95 | #if defined(CONFIG_FEATURE_2_4_MODULES) || defined(CONFIG_FEATURE_2_2_MODULES) | ||
96 | |||
97 | #if defined(CONFIG_FEATURE_2_6_MODULES) | 94 | #if defined(CONFIG_FEATURE_2_6_MODULES) |
98 | extern int insmod_ng_main( int argc, char **argv); | 95 | extern int insmod_ng_main( int argc, char **argv); |
99 | #endif | 96 | #endif |
100 | 97 | ||
101 | #ifdef CONFIG_FEATURE_2_4_MODULES | 98 | |
102 | # undef CONFIG_FEATURE_2_2_MODULES | 99 | #if defined(CONFIG_FEATURE_2_4_MODULES) |
103 | # define new_sys_init_module init_module | 100 | |
104 | #else | ||
105 | # define old_sys_init_module init_module | ||
106 | #endif | ||
107 | 101 | ||
108 | #ifdef CONFIG_FEATURE_INSMOD_LOADINKMEM | 102 | #ifdef CONFIG_FEATURE_INSMOD_LOADINKMEM |
109 | #define LOADBITS 0 | 103 | #define LOADBITS 0 |
@@ -296,68 +290,7 @@ extern int insmod_ng_main( int argc, char **argv); | |||
296 | #ifndef MODUTILS_MODULE_H | 290 | #ifndef MODUTILS_MODULE_H |
297 | static const int MODUTILS_MODULE_H = 1; | 291 | static const int MODUTILS_MODULE_H = 1; |
298 | 292 | ||
299 | #ident "$Id: insmod.c,v 1.119 2004/05/26 12:06:38 andersen Exp $" | 293 | #ident "$Id: insmod.c,v 1.120 2004/06/22 11:50:52 andersen Exp $" |
300 | |||
301 | /* This file contains the structures used by the 2.0 and 2.1 kernels. | ||
302 | We do not use the kernel headers directly because we do not wish | ||
303 | to be dependent on a particular kernel version to compile insmod. */ | ||
304 | |||
305 | |||
306 | /*======================================================================*/ | ||
307 | /* The structures used by Linux 2.0. */ | ||
308 | |||
309 | /* The symbol format used by get_kernel_syms(2). */ | ||
310 | struct old_kernel_sym | ||
311 | { | ||
312 | unsigned long value; | ||
313 | char name[60]; | ||
314 | }; | ||
315 | |||
316 | struct old_module_ref | ||
317 | { | ||
318 | unsigned long module; /* kernel addresses */ | ||
319 | unsigned long next; | ||
320 | }; | ||
321 | |||
322 | struct old_module_symbol | ||
323 | { | ||
324 | unsigned long addr; | ||
325 | unsigned long name; | ||
326 | }; | ||
327 | |||
328 | struct old_symbol_table | ||
329 | { | ||
330 | int size; /* total, including string table!!! */ | ||
331 | int n_symbols; | ||
332 | int n_refs; | ||
333 | struct old_module_symbol symbol[0]; /* actual size defined by n_symbols */ | ||
334 | struct old_module_ref ref[0]; /* actual size defined by n_refs */ | ||
335 | }; | ||
336 | |||
337 | struct old_mod_routines | ||
338 | { | ||
339 | unsigned long init; | ||
340 | unsigned long cleanup; | ||
341 | }; | ||
342 | |||
343 | struct old_module | ||
344 | { | ||
345 | unsigned long next; | ||
346 | unsigned long ref; /* the list of modules that refer to me */ | ||
347 | unsigned long symtab; | ||
348 | unsigned long name; | ||
349 | int size; /* size of module in pages */ | ||
350 | unsigned long addr; /* address of module */ | ||
351 | int state; | ||
352 | unsigned long cleanup; /* cleanup routine */ | ||
353 | }; | ||
354 | |||
355 | /* Sent to init_module(2) or'ed into the code size parameter. */ | ||
356 | static const int OLD_MOD_AUTOCLEAN = 0x40000000; /* big enough, but no sign problems... */ | ||
357 | |||
358 | int get_kernel_syms(struct old_kernel_sym *); | ||
359 | int old_sys_init_module(const char *name, char *code, unsigned codesize, | ||
360 | struct old_mod_routines *, struct old_symbol_table *); | ||
361 | 294 | ||
362 | /*======================================================================*/ | 295 | /*======================================================================*/ |
363 | /* For sizeof() which are related to the module platform and not to the | 296 | /* For sizeof() which are related to the module platform and not to the |
@@ -429,13 +362,11 @@ struct new_module | |||
429 | unsigned tgt_long persist_end; | 362 | unsigned tgt_long persist_end; |
430 | unsigned tgt_long can_unload; | 363 | unsigned tgt_long can_unload; |
431 | unsigned tgt_long runsize; | 364 | unsigned tgt_long runsize; |
432 | #ifdef CONFIG_FEATURE_2_4_MODULES | ||
433 | const char *kallsyms_start; /* All symbols for kernel debugging */ | 365 | const char *kallsyms_start; /* All symbols for kernel debugging */ |
434 | const char *kallsyms_end; | 366 | const char *kallsyms_end; |
435 | const char *archdata_start; /* arch specific data for module */ | 367 | const char *archdata_start; /* arch specific data for module */ |
436 | const char *archdata_end; | 368 | const char *archdata_end; |
437 | const char *kernel_data; /* Reserved for kernel internal use */ | 369 | const char *kernel_data; /* Reserved for kernel internal use */ |
438 | #endif | ||
439 | }; | 370 | }; |
440 | 371 | ||
441 | #ifdef ARCHDATAM | 372 | #ifdef ARCHDATAM |
@@ -461,9 +392,9 @@ static const int NEW_MOD_AUTOCLEAN = 4; | |||
461 | static const int NEW_MOD_VISITED = 8; | 392 | static const int NEW_MOD_VISITED = 8; |
462 | static const int NEW_MOD_USED_ONCE = 16; | 393 | static const int NEW_MOD_USED_ONCE = 16; |
463 | 394 | ||
464 | int new_sys_init_module(const char *name, const struct new_module *); | 395 | int init_module(const char *name, const struct new_module *); |
465 | int query_module(const char *name, int which, void *buf, size_t bufsize, | 396 | int query_module(const char *name, int which, void *buf, |
466 | size_t *ret); | 397 | size_t bufsize, size_t *ret); |
467 | 398 | ||
468 | /* Values for query_module's which. */ | 399 | /* Values for query_module's which. */ |
469 | 400 | ||
@@ -517,7 +448,7 @@ int delete_module(const char *); | |||
517 | #ifndef MODUTILS_OBJ_H | 448 | #ifndef MODUTILS_OBJ_H |
518 | static const int MODUTILS_OBJ_H = 1; | 449 | static const int MODUTILS_OBJ_H = 1; |
519 | 450 | ||
520 | #ident "$Id: insmod.c,v 1.119 2004/05/26 12:06:38 andersen Exp $" | 451 | #ident "$Id: insmod.c,v 1.120 2004/06/22 11:50:52 andersen Exp $" |
521 | 452 | ||
522 | /* The relocatable object is manipulated using elfin types. */ | 453 | /* The relocatable object is manipulated using elfin types. */ |
523 | 454 | ||
@@ -660,10 +591,8 @@ static void *obj_extend_section (struct obj_section *sec, unsigned long more); | |||
660 | static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, | 591 | static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, |
661 | const char *string); | 592 | const char *string); |
662 | 593 | ||
663 | #ifdef CONFIG_FEATURE_2_4_MODULES | ||
664 | static int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, | 594 | static int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, |
665 | struct obj_symbol *sym); | 595 | struct obj_symbol *sym); |
666 | #endif | ||
667 | 596 | ||
668 | static int obj_check_undefineds(struct obj_file *f); | 597 | static int obj_check_undefineds(struct obj_file *f); |
669 | 598 | ||
@@ -695,10 +624,6 @@ static void arch_create_got (struct obj_file *f); | |||
695 | 624 | ||
696 | static int obj_gpl_license(struct obj_file *f, const char **license); | 625 | static int obj_gpl_license(struct obj_file *f, const char **license); |
697 | 626 | ||
698 | #ifdef CONFIG_FEATURE_2_4_MODULES | ||
699 | static int arch_init_module (struct obj_file *f, struct new_module *); | ||
700 | #endif | ||
701 | |||
702 | #endif /* obj.h */ | 627 | #endif /* obj.h */ |
703 | //---------------------------------------------------------------------------- | 628 | //---------------------------------------------------------------------------- |
704 | //--------end of modutils obj.h | 629 | //--------end of modutils obj.h |
@@ -1690,13 +1615,6 @@ static void arch_create_got(struct obj_file *f) | |||
1690 | #endif /* defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES) */ | 1615 | #endif /* defined(CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES) */ |
1691 | } | 1616 | } |
1692 | 1617 | ||
1693 | #ifdef CONFIG_FEATURE_2_4_MODULES | ||
1694 | static int arch_init_module(struct obj_file *f, struct new_module *mod) | ||
1695 | { | ||
1696 | return 1; | ||
1697 | } | ||
1698 | #endif | ||
1699 | |||
1700 | /*======================================================================*/ | 1618 | /*======================================================================*/ |
1701 | 1619 | ||
1702 | /* Standard ELF hash function. */ | 1620 | /* Standard ELF hash function. */ |
@@ -2013,8 +1931,7 @@ static void *obj_extend_section(struct obj_section *sec, unsigned long more) | |||
2013 | new module. */ | 1931 | new module. */ |
2014 | 1932 | ||
2015 | static int | 1933 | static int |
2016 | add_symbols_from( | 1934 | add_symbols_from( struct obj_file *f, |
2017 | struct obj_file *f, | ||
2018 | int idx, struct new_module_symbol *syms, size_t nsyms) | 1935 | int idx, struct new_module_symbol *syms, size_t nsyms) |
2019 | { | 1936 | { |
2020 | struct new_module_symbol *s; | 1937 | struct new_module_symbol *s; |
@@ -2138,371 +2055,6 @@ static char *get_modinfo_value(struct obj_file *f, const char *key) | |||
2138 | 2055 | ||
2139 | 2056 | ||
2140 | /*======================================================================*/ | 2057 | /*======================================================================*/ |
2141 | /* Functions relating to module loading in pre 2.1 kernels. */ | ||
2142 | |||
2143 | static int | ||
2144 | old_process_module_arguments(struct obj_file *f, int argc, char **argv) | ||
2145 | { | ||
2146 | while (argc > 0) { | ||
2147 | char *p, *q; | ||
2148 | struct obj_symbol *sym; | ||
2149 | int *loc; | ||
2150 | |||
2151 | p = *argv; | ||
2152 | if ((q = strchr(p, '=')) == NULL) { | ||
2153 | argc--; | ||
2154 | continue; | ||
2155 | } | ||
2156 | *q++ = '\0'; | ||
2157 | |||
2158 | sym = obj_find_symbol(f, p); | ||
2159 | |||
2160 | /* Also check that the parameter was not resolved from the kernel. */ | ||
2161 | if (sym == NULL || sym->secidx > SHN_HIRESERVE) { | ||
2162 | bb_error_msg("symbol for parameter %s not found", p); | ||
2163 | return 0; | ||
2164 | } | ||
2165 | |||
2166 | loc = (int *) (f->sections[sym->secidx]->contents + sym->value); | ||
2167 | |||
2168 | /* Do C quoting if we begin with a ". */ | ||
2169 | if (*q == '"') { | ||
2170 | char *r, *str; | ||
2171 | |||
2172 | str = alloca(strlen(q)); | ||
2173 | for (r = str, q++; *q != '"'; ++q, ++r) { | ||
2174 | if (*q == '\0') { | ||
2175 | bb_error_msg("improperly terminated string argument for %s", p); | ||
2176 | return 0; | ||
2177 | } else if (*q == '\\') | ||
2178 | switch (*++q) { | ||
2179 | case 'a': | ||
2180 | *r = '\a'; | ||
2181 | break; | ||
2182 | case 'b': | ||
2183 | *r = '\b'; | ||
2184 | break; | ||
2185 | case 'e': | ||
2186 | *r = '\033'; | ||
2187 | break; | ||
2188 | case 'f': | ||
2189 | *r = '\f'; | ||
2190 | break; | ||
2191 | case 'n': | ||
2192 | *r = '\n'; | ||
2193 | break; | ||
2194 | case 'r': | ||
2195 | *r = '\r'; | ||
2196 | break; | ||
2197 | case 't': | ||
2198 | *r = '\t'; | ||
2199 | break; | ||
2200 | |||
2201 | case '0': | ||
2202 | case '1': | ||
2203 | case '2': | ||
2204 | case '3': | ||
2205 | case '4': | ||
2206 | case '5': | ||
2207 | case '6': | ||
2208 | case '7': | ||
2209 | { | ||
2210 | int c = *q - '0'; | ||
2211 | if (q[1] >= '0' && q[1] <= '7') { | ||
2212 | c = (c * 8) + *++q - '0'; | ||
2213 | if (q[1] >= '0' && q[1] <= '7') | ||
2214 | c = (c * 8) + *++q - '0'; | ||
2215 | } | ||
2216 | *r = c; | ||
2217 | } | ||
2218 | break; | ||
2219 | |||
2220 | default: | ||
2221 | *r = *q; | ||
2222 | break; | ||
2223 | } else | ||
2224 | *r = *q; | ||
2225 | } | ||
2226 | *r = '\0'; | ||
2227 | obj_string_patch(f, sym->secidx, sym->value, str); | ||
2228 | } else if (*q >= '0' && *q <= '9') { | ||
2229 | do | ||
2230 | *loc++ = strtoul(q, &q, 0); | ||
2231 | while (*q++ == ','); | ||
2232 | } else { | ||
2233 | char *contents = f->sections[sym->secidx]->contents; | ||
2234 | char *myloc = contents + sym->value; | ||
2235 | char *r; /* To search for commas */ | ||
2236 | |||
2237 | /* Break the string with comas */ | ||
2238 | while ((r = strchr(q, ',')) != (char *) NULL) { | ||
2239 | *r++ = '\0'; | ||
2240 | obj_string_patch(f, sym->secidx, myloc - contents, q); | ||
2241 | myloc += sizeof(char *); | ||
2242 | q = r; | ||
2243 | } | ||
2244 | |||
2245 | /* last part */ | ||
2246 | obj_string_patch(f, sym->secidx, myloc - contents, q); | ||
2247 | } | ||
2248 | |||
2249 | argc--, argv++; | ||
2250 | } | ||
2251 | |||
2252 | return 1; | ||
2253 | } | ||
2254 | |||
2255 | #ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING | ||
2256 | static int old_is_module_checksummed(struct obj_file *f) | ||
2257 | { | ||
2258 | return obj_find_symbol(f, "Using_Versions") != NULL; | ||
2259 | } | ||
2260 | /* Get the module's kernel version in the canonical integer form. */ | ||
2261 | |||
2262 | static int | ||
2263 | old_get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) | ||
2264 | { | ||
2265 | struct obj_symbol *sym; | ||
2266 | char *p, *q; | ||
2267 | int a, b, c; | ||
2268 | |||
2269 | sym = obj_find_symbol(f, "kernel_version"); | ||
2270 | if (sym == NULL) | ||
2271 | return -1; | ||
2272 | |||
2273 | p = f->sections[sym->secidx]->contents + sym->value; | ||
2274 | safe_strncpy(str, p, STRVERSIONLEN); | ||
2275 | |||
2276 | a = strtoul(p, &p, 10); | ||
2277 | if (*p != '.') | ||
2278 | return -1; | ||
2279 | b = strtoul(p + 1, &p, 10); | ||
2280 | if (*p != '.') | ||
2281 | return -1; | ||
2282 | c = strtoul(p + 1, &q, 10); | ||
2283 | if (p + 1 == q) | ||
2284 | return -1; | ||
2285 | |||
2286 | return a << 16 | b << 8 | c; | ||
2287 | } | ||
2288 | |||
2289 | #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ | ||
2290 | |||
2291 | #ifdef CONFIG_FEATURE_2_2_MODULES | ||
2292 | |||
2293 | /* Fetch all the symbols and divvy them up as appropriate for the modules. */ | ||
2294 | |||
2295 | static int old_get_kernel_symbols(const char *m_name) | ||
2296 | { | ||
2297 | struct old_kernel_sym *ks, *k; | ||
2298 | struct new_module_symbol *s; | ||
2299 | struct external_module *mod; | ||
2300 | int nks, nms, nmod, i; | ||
2301 | |||
2302 | nks = get_kernel_syms(NULL); | ||
2303 | if (nks <= 0) { | ||
2304 | if (nks) | ||
2305 | bb_perror_msg("get_kernel_syms: %s", m_name); | ||
2306 | else | ||
2307 | bb_error_msg("No kernel symbols"); | ||
2308 | return 0; | ||
2309 | } | ||
2310 | |||
2311 | ks = k = xmalloc(nks * sizeof(*ks)); | ||
2312 | |||
2313 | if (get_kernel_syms(ks) != nks) { | ||
2314 | perror("inconsistency with get_kernel_syms -- is someone else " | ||
2315 | "playing with modules?"); | ||
2316 | free(ks); | ||
2317 | return 0; | ||
2318 | } | ||
2319 | |||
2320 | /* Collect the module information. */ | ||
2321 | |||
2322 | mod = NULL; | ||
2323 | nmod = -1; | ||
2324 | |||
2325 | while (k->name[0] == '#' && k->name[1]) { | ||
2326 | struct old_kernel_sym *k2; | ||
2327 | |||
2328 | /* Find out how many symbols this module has. */ | ||
2329 | for (k2 = k + 1; k2->name[0] != '#'; ++k2) | ||
2330 | continue; | ||
2331 | nms = k2 - k - 1; | ||
2332 | |||
2333 | mod = xrealloc(mod, (++nmod + 1) * sizeof(*mod)); | ||
2334 | mod[nmod].name = k->name + 1; | ||
2335 | mod[nmod].addr = k->value; | ||
2336 | mod[nmod].used = 0; | ||
2337 | mod[nmod].nsyms = nms; | ||
2338 | mod[nmod].syms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL); | ||
2339 | |||
2340 | for (i = 0, ++k; i < nms; ++i, ++s, ++k) { | ||
2341 | s->name = (unsigned long) k->name; | ||
2342 | s->value = k->value; | ||
2343 | } | ||
2344 | |||
2345 | k = k2; | ||
2346 | } | ||
2347 | |||
2348 | ext_modules = mod; | ||
2349 | n_ext_modules = nmod + 1; | ||
2350 | |||
2351 | /* Now collect the symbols for the kernel proper. */ | ||
2352 | |||
2353 | if (k->name[0] == '#') | ||
2354 | ++k; | ||
2355 | |||
2356 | nksyms = nms = nks - (k - ks); | ||
2357 | ksyms = s = (nms ? xmalloc(nms * sizeof(*s)) : NULL); | ||
2358 | |||
2359 | for (i = 0; i < nms; ++i, ++s, ++k) { | ||
2360 | s->name = (unsigned long) k->name; | ||
2361 | s->value = k->value; | ||
2362 | } | ||
2363 | |||
2364 | return 1; | ||
2365 | } | ||
2366 | |||
2367 | /* Return the kernel symbol checksum version, or zero if not used. */ | ||
2368 | |||
2369 | static int old_is_kernel_checksummed(void) | ||
2370 | { | ||
2371 | /* Using_Versions is the first symbol. */ | ||
2372 | if (nksyms > 0 | ||
2373 | && strcmp((char *) ksyms[0].name, | ||
2374 | "Using_Versions") == 0) return ksyms[0].value; | ||
2375 | else | ||
2376 | return 0; | ||
2377 | } | ||
2378 | |||
2379 | |||
2380 | static int old_create_mod_use_count(struct obj_file *f) | ||
2381 | { | ||
2382 | struct obj_section *sec; | ||
2383 | |||
2384 | sec = obj_create_alloced_section_first(f, ".moduse", sizeof(long), | ||
2385 | sizeof(long)); | ||
2386 | |||
2387 | obj_add_symbol(f, "mod_use_count_", -1, | ||
2388 | ELFW(ST_INFO) (STB_LOCAL, STT_OBJECT), sec->idx, 0, | ||
2389 | sizeof(long)); | ||
2390 | |||
2391 | return 1; | ||
2392 | } | ||
2393 | |||
2394 | static int | ||
2395 | old_init_module(const char *m_name, struct obj_file *f, | ||
2396 | unsigned long m_size) | ||
2397 | { | ||
2398 | char *image; | ||
2399 | struct old_mod_routines routines; | ||
2400 | struct old_symbol_table *symtab; | ||
2401 | int ret; | ||
2402 | |||
2403 | /* Create the symbol table */ | ||
2404 | { | ||
2405 | int nsyms = 0, strsize = 0, total; | ||
2406 | |||
2407 | /* Size things first... */ | ||
2408 | if (flag_export) { | ||
2409 | int i; | ||
2410 | for (i = 0; i < HASH_BUCKETS; ++i) { | ||
2411 | struct obj_symbol *sym; | ||
2412 | for (sym = f->symtab[i]; sym; sym = sym->next) | ||
2413 | if (ELFW(ST_BIND) (sym->info) != STB_LOCAL | ||
2414 | && sym->secidx <= SHN_HIRESERVE) | ||
2415 | { | ||
2416 | sym->ksymidx = nsyms++; | ||
2417 | strsize += strlen(sym->name) + 1; | ||
2418 | } | ||
2419 | } | ||
2420 | } | ||
2421 | |||
2422 | total = (sizeof(struct old_symbol_table) | ||
2423 | + nsyms * sizeof(struct old_module_symbol) | ||
2424 | + n_ext_modules_used * sizeof(struct old_module_ref) | ||
2425 | + strsize); | ||
2426 | symtab = xmalloc(total); | ||
2427 | symtab->size = total; | ||
2428 | symtab->n_symbols = nsyms; | ||
2429 | symtab->n_refs = n_ext_modules_used; | ||
2430 | |||
2431 | if (flag_export && nsyms) { | ||
2432 | struct old_module_symbol *ksym; | ||
2433 | char *str; | ||
2434 | int i; | ||
2435 | |||
2436 | ksym = symtab->symbol; | ||
2437 | str = ((char *) ksym + nsyms * sizeof(struct old_module_symbol) | ||
2438 | + n_ext_modules_used * sizeof(struct old_module_ref)); | ||
2439 | |||
2440 | for (i = 0; i < HASH_BUCKETS; ++i) { | ||
2441 | struct obj_symbol *sym; | ||
2442 | for (sym = f->symtab[i]; sym; sym = sym->next) | ||
2443 | if (sym->ksymidx >= 0) { | ||
2444 | ksym->addr = obj_symbol_final_value(f, sym); | ||
2445 | ksym->name = | ||
2446 | (unsigned long) str - (unsigned long) symtab; | ||
2447 | |||
2448 | strcpy(str, sym->name); | ||
2449 | str += strlen(sym->name) + 1; | ||
2450 | ksym++; | ||
2451 | } | ||
2452 | } | ||
2453 | } | ||
2454 | |||
2455 | if (n_ext_modules_used) { | ||
2456 | struct old_module_ref *ref; | ||
2457 | int i; | ||
2458 | |||
2459 | ref = (struct old_module_ref *) | ||
2460 | ((char *) symtab->symbol + nsyms * sizeof(struct old_module_symbol)); | ||
2461 | |||
2462 | for (i = 0; i < n_ext_modules; ++i) | ||
2463 | if (ext_modules[i].used) | ||
2464 | ref++->module = ext_modules[i].addr; | ||
2465 | } | ||
2466 | } | ||
2467 | |||
2468 | /* Fill in routines. */ | ||
2469 | |||
2470 | routines.init = | ||
2471 | obj_symbol_final_value(f, obj_find_symbol(f, SPFX "init_module")); | ||
2472 | routines.cleanup = | ||
2473 | obj_symbol_final_value(f, obj_find_symbol(f, SPFX "cleanup_module")); | ||
2474 | |||
2475 | /* Whew! All of the initialization is complete. Collect the final | ||
2476 | module image and give it to the kernel. */ | ||
2477 | |||
2478 | image = xmalloc(m_size); | ||
2479 | obj_create_image(f, image); | ||
2480 | |||
2481 | /* image holds the complete relocated module, accounting correctly for | ||
2482 | mod_use_count. However the old module kernel support assume that | ||
2483 | it is receiving something which does not contain mod_use_count. */ | ||
2484 | ret = old_sys_init_module(m_name, image + sizeof(long), | ||
2485 | m_size | (flag_autoclean ? OLD_MOD_AUTOCLEAN | ||
2486 | : 0), &routines, symtab); | ||
2487 | if (ret) | ||
2488 | bb_perror_msg("init_module: %s", m_name); | ||
2489 | |||
2490 | free(image); | ||
2491 | free(symtab); | ||
2492 | |||
2493 | return ret == 0; | ||
2494 | } | ||
2495 | |||
2496 | #else | ||
2497 | |||
2498 | #define old_create_mod_use_count(x) TRUE | ||
2499 | #define old_init_module(x, y, z) TRUE | ||
2500 | |||
2501 | #endif /* CONFIG_FEATURE_2_2_MODULES */ | ||
2502 | |||
2503 | |||
2504 | |||
2505 | /*======================================================================*/ | ||
2506 | /* Functions relating to module loading after 2.1.18. */ | 2058 | /* Functions relating to module loading after 2.1.18. */ |
2507 | 2059 | ||
2508 | static int | 2060 | static int |
@@ -2784,8 +2336,6 @@ new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) | |||
2784 | #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ | 2336 | #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ |
2785 | 2337 | ||
2786 | 2338 | ||
2787 | #ifdef CONFIG_FEATURE_2_4_MODULES | ||
2788 | |||
2789 | /* Fetch the loaded modules, and all currently exported symbols. */ | 2339 | /* Fetch the loaded modules, and all currently exported symbols. */ |
2790 | 2340 | ||
2791 | static int new_get_kernel_symbols(void) | 2341 | static int new_get_kernel_symbols(void) |
@@ -3015,8 +2565,7 @@ static int new_create_module_ksymtab(struct obj_file *f) | |||
3015 | 2565 | ||
3016 | 2566 | ||
3017 | static int | 2567 | static int |
3018 | new_init_module(const char *m_name, struct obj_file *f, | 2568 | new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size) |
3019 | unsigned long m_size) | ||
3020 | { | 2569 | { |
3021 | struct new_module *module; | 2570 | struct new_module *module; |
3022 | struct obj_section *sec; | 2571 | struct obj_section *sec; |
@@ -3079,16 +2628,13 @@ new_init_module(const char *m_name, struct obj_file *f, | |||
3079 | module->kallsyms_end = module->kallsyms_start + sec->header.sh_size; | 2628 | module->kallsyms_end = module->kallsyms_start + sec->header.sh_size; |
3080 | } | 2629 | } |
3081 | 2630 | ||
3082 | if (!arch_init_module(f, module)) | ||
3083 | return 0; | ||
3084 | |||
3085 | /* Whew! All of the initialization is complete. Collect the final | 2631 | /* Whew! All of the initialization is complete. Collect the final |
3086 | module image and give it to the kernel. */ | 2632 | module image and give it to the kernel. */ |
3087 | 2633 | ||
3088 | image = xmalloc(m_size); | 2634 | image = xmalloc(m_size); |
3089 | obj_create_image(f, image); | 2635 | obj_create_image(f, image); |
3090 | 2636 | ||
3091 | ret = new_sys_init_module(m_name, (struct new_module *) image); | 2637 | ret = init_module(m_name, (struct new_module *) image); |
3092 | if (ret) | 2638 | if (ret) |
3093 | bb_perror_msg("init_module: %s", m_name); | 2639 | bb_perror_msg("init_module: %s", m_name); |
3094 | 2640 | ||
@@ -3097,16 +2643,6 @@ new_init_module(const char *m_name, struct obj_file *f, | |||
3097 | return ret == 0; | 2643 | return ret == 0; |
3098 | } | 2644 | } |
3099 | 2645 | ||
3100 | #else | ||
3101 | |||
3102 | #define new_init_module(x, y, z) TRUE | ||
3103 | #define new_create_this_module(x, y) 0 | ||
3104 | #define new_add_ksymtab(x, y) -1 | ||
3105 | #define new_create_module_ksymtab(x) | ||
3106 | #define query_module(v, w, x, y, z) -1 | ||
3107 | |||
3108 | #endif /* CONFIG_FEATURE_2_4_MODULES */ | ||
3109 | |||
3110 | 2646 | ||
3111 | /*======================================================================*/ | 2647 | /*======================================================================*/ |
3112 | 2648 | ||
@@ -3139,7 +2675,6 @@ obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, | |||
3139 | return 1; | 2675 | return 1; |
3140 | } | 2676 | } |
3141 | 2677 | ||
3142 | #ifdef CONFIG_FEATURE_2_4_MODULES | ||
3143 | static int | 2678 | static int |
3144 | obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, | 2679 | obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, |
3145 | struct obj_symbol *sym) | 2680 | struct obj_symbol *sym) |
@@ -3155,7 +2690,6 @@ obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, | |||
3155 | 2690 | ||
3156 | return 1; | 2691 | return 1; |
3157 | } | 2692 | } |
3158 | #endif | ||
3159 | 2693 | ||
3160 | static int obj_check_undefineds(struct obj_file *f) | 2694 | static int obj_check_undefineds(struct obj_file *f) |
3161 | { | 2695 | { |
@@ -3853,10 +3387,7 @@ static int | |||
3853 | get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) | 3387 | get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) |
3854 | { | 3388 | { |
3855 | #ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING | 3389 | #ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING |
3856 | if (get_modinfo_value(f, "kernel_version") == NULL) | 3390 | return new_get_module_version(f, str); |
3857 | return old_get_module_version(f, str); | ||
3858 | else | ||
3859 | return new_get_module_version(f, str); | ||
3860 | #else /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ | 3391 | #else /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ |
3861 | strncpy(str, "???", sizeof(str)); | 3392 | strncpy(str, "???", sizeof(str)); |
3862 | return -1; | 3393 | return -1; |
@@ -4075,8 +3606,6 @@ static void print_load_map(struct obj_file *f) | |||
4075 | extern int insmod_main( int argc, char **argv) | 3606 | extern int insmod_main( int argc, char **argv) |
4076 | { | 3607 | { |
4077 | int opt; | 3608 | int opt; |
4078 | int k_crcs; | ||
4079 | int k_new_syscalls; | ||
4080 | int len; | 3609 | int len; |
4081 | char *tmp, *tmp1; | 3610 | char *tmp, *tmp1; |
4082 | unsigned long m_size; | 3611 | unsigned long m_size; |
@@ -4090,7 +3619,7 @@ extern int insmod_main( int argc, char **argv) | |||
4090 | struct utsname uts_info; | 3619 | struct utsname uts_info; |
4091 | char m_strversion[STRVERSIONLEN]; | 3620 | char m_strversion[STRVERSIONLEN]; |
4092 | int m_version; | 3621 | int m_version; |
4093 | int m_crcs; | 3622 | int k_crcs, m_crcs; |
4094 | #endif | 3623 | #endif |
4095 | #ifdef CONFIG_FEATURE_CLEAN_UP | 3624 | #ifdef CONFIG_FEATURE_CLEAN_UP |
4096 | FILE *fp = 0; | 3625 | FILE *fp = 0; |
@@ -4273,8 +3802,6 @@ extern int insmod_main( int argc, char **argv) | |||
4273 | uts_info.release[0] = '\0'; | 3802 | uts_info.release[0] = '\0'; |
4274 | if (m_has_modinfo) { | 3803 | if (m_has_modinfo) { |
4275 | m_version = new_get_module_version(f, m_strversion); | 3804 | m_version = new_get_module_version(f, m_strversion); |
4276 | } else { | ||
4277 | m_version = old_get_module_version(f, m_strversion); | ||
4278 | if (m_version == -1) { | 3805 | if (m_version == -1) { |
4279 | bb_error_msg("couldn't find the kernel version the module was " | 3806 | bb_error_msg("couldn't find the kernel version the module was " |
4280 | "compiled for"); | 3807 | "compiled for"); |
@@ -4300,33 +3827,19 @@ extern int insmod_main( int argc, char **argv) | |||
4300 | k_crcs = 0; | 3827 | k_crcs = 0; |
4301 | #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ | 3828 | #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */ |
4302 | 3829 | ||
4303 | k_new_syscalls = !query_module(NULL, 0, NULL, 0, NULL); | 3830 | if (!query_module(NULL, 0, NULL, 0, NULL)) { |
4304 | |||
4305 | if (k_new_syscalls) { | ||
4306 | #ifdef CONFIG_FEATURE_2_4_MODULES | ||
4307 | if (!new_get_kernel_symbols()) | 3831 | if (!new_get_kernel_symbols()) |
4308 | goto out; | 3832 | goto out; |
4309 | k_crcs = new_is_kernel_checksummed(); | 3833 | k_crcs = new_is_kernel_checksummed(); |
4310 | #else | ||
4311 | bb_error_msg("Not configured to support new kernels"); | ||
4312 | goto out; | ||
4313 | #endif | ||
4314 | } else { | 3834 | } else { |
4315 | #ifdef CONFIG_FEATURE_2_2_MODULES | ||
4316 | if (!old_get_kernel_symbols(m_name)) | ||
4317 | goto out; | ||
4318 | k_crcs = old_is_kernel_checksummed(); | ||
4319 | #else | ||
4320 | bb_error_msg("Not configured to support old kernels"); | 3835 | bb_error_msg("Not configured to support old kernels"); |
4321 | goto out; | 3836 | goto out; |
4322 | #endif | ||
4323 | } | 3837 | } |
4324 | 3838 | ||
4325 | #ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING | 3839 | #ifdef CONFIG_FEATURE_INSMOD_VERSION_CHECKING |
3840 | m_crcs = 0; | ||
4326 | if (m_has_modinfo) | 3841 | if (m_has_modinfo) |
4327 | m_crcs = new_is_module_checksummed(f); | 3842 | m_crcs = new_is_module_checksummed(f); |
4328 | else | ||
4329 | m_crcs = old_is_module_checksummed(f); | ||
4330 | 3843 | ||
4331 | if (m_crcs != k_crcs) | 3844 | if (m_crcs != k_crcs) |
4332 | obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash); | 3845 | obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash); |
@@ -4337,9 +3850,7 @@ extern int insmod_main( int argc, char **argv) | |||
4337 | 3850 | ||
4338 | /* Allocate common symbols, symbol tables, and string tables. */ | 3851 | /* Allocate common symbols, symbol tables, and string tables. */ |
4339 | 3852 | ||
4340 | if (k_new_syscalls | 3853 | if (!new_create_this_module(f, m_name)) |
4341 | ? !new_create_this_module(f, m_name) | ||
4342 | : !old_create_mod_use_count(f)) | ||
4343 | { | 3854 | { |
4344 | goto out; | 3855 | goto out; |
4345 | } | 3856 | } |
@@ -4354,9 +3865,7 @@ extern int insmod_main( int argc, char **argv) | |||
4354 | ++optind; | 3865 | ++optind; |
4355 | 3866 | ||
4356 | if (optind < argc) { | 3867 | if (optind < argc) { |
4357 | if (m_has_modinfo | 3868 | if (new_process_module_arguments(f, argc - optind, argv + optind)) |
4358 | ? !new_process_module_arguments(f, argc - optind, argv + optind) | ||
4359 | : !old_process_module_arguments(f, argc - optind, argv + optind)) | ||
4360 | { | 3869 | { |
4361 | goto out; | 3870 | goto out; |
4362 | } | 3871 | } |
@@ -4369,8 +3878,7 @@ extern int insmod_main( int argc, char **argv) | |||
4369 | add_ksymoops_symbols(f, m_filename, m_name); | 3878 | add_ksymoops_symbols(f, m_filename, m_name); |
4370 | #endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */ | 3879 | #endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */ |
4371 | 3880 | ||
4372 | if (k_new_syscalls) | 3881 | new_create_module_ksymtab(f); |
4373 | new_create_module_ksymtab(f); | ||
4374 | 3882 | ||
4375 | /* Find current size of the module */ | 3883 | /* Find current size of the module */ |
4376 | m_size = obj_load_size(f); | 3884 | m_size = obj_load_size(f); |
@@ -4406,9 +3914,7 @@ extern int insmod_main( int argc, char **argv) | |||
4406 | goto out; | 3914 | goto out; |
4407 | } | 3915 | } |
4408 | 3916 | ||
4409 | if (k_new_syscalls | 3917 | if (!new_init_module(m_name, f, m_size)) |
4410 | ? !new_init_module(m_name, f, m_size) | ||
4411 | : !old_init_module(m_name, f, m_size)) | ||
4412 | { | 3918 | { |
4413 | delete_module(m_name); | 3919 | delete_module(m_name); |
4414 | goto out; | 3920 | goto out; |