aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEric Andersen <andersen@codepoet.org>2004-06-22 11:50:52 +0000
committerEric Andersen <andersen@codepoet.org>2004-06-22 11:50:52 +0000
commitcb3b9b1fed3685198fca2e7070a7179288d2def2 (patch)
tree90ef18eaeff6ffcc02fe101cb6b680517d49111e
parentd943837dab6eb2b2809426c0e81f7b8e8cf82208 (diff)
downloadbusybox-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.in23
-rw-r--r--modutils/insmod.c534
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
14config 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
21config CONFIG_FEATURE_2_4_MODULES 14config 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
28config CONFIG_FEATURE_2_6_MODULES 21config 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
35config CONFIG_FEATURE_INSMOD_VERSION_CHECKING 28config 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
43config CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS 36config 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
54config CONFIG_FEATURE_INSMOD_LOADINKMEM 47config 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
64config CONFIG_FEATURE_INSMOD_LOAD_MAP 57config 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)
98extern int insmod_ng_main( int argc, char **argv); 95extern 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
297static const int MODUTILS_MODULE_H = 1; 291static 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). */
310struct old_kernel_sym
311{
312 unsigned long value;
313 char name[60];
314};
315
316struct old_module_ref
317{
318 unsigned long module; /* kernel addresses */
319 unsigned long next;
320};
321
322struct old_module_symbol
323{
324 unsigned long addr;
325 unsigned long name;
326};
327
328struct 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
337struct old_mod_routines
338{
339 unsigned long init;
340 unsigned long cleanup;
341};
342
343struct 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. */
356static const int OLD_MOD_AUTOCLEAN = 0x40000000; /* big enough, but no sign problems... */
357
358int get_kernel_syms(struct old_kernel_sym *);
359int 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;
461static const int NEW_MOD_VISITED = 8; 392static const int NEW_MOD_VISITED = 8;
462static const int NEW_MOD_USED_ONCE = 16; 393static const int NEW_MOD_USED_ONCE = 16;
463 394
464int new_sys_init_module(const char *name, const struct new_module *); 395int init_module(const char *name, const struct new_module *);
465int query_module(const char *name, int which, void *buf, size_t bufsize, 396int 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
518static const int MODUTILS_OBJ_H = 1; 449static 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);
660static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, 591static 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
664static int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, 594static 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
668static int obj_check_undefineds(struct obj_file *f); 597static 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
696static int obj_gpl_license(struct obj_file *f, const char **license); 625static int obj_gpl_license(struct obj_file *f, const char **license);
697 626
698#ifdef CONFIG_FEATURE_2_4_MODULES
699static 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
1694static 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
2015static int 1933static int
2016add_symbols_from( 1934add_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
2143static int
2144old_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
2256static 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
2262static int
2263old_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
2295static 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
2369static 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
2380static 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
2394static int
2395old_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
2508static int 2060static 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
2791static int new_get_kernel_symbols(void) 2341static int new_get_kernel_symbols(void)
@@ -3015,8 +2565,7 @@ static int new_create_module_ksymtab(struct obj_file *f)
3015 2565
3016 2566
3017static int 2567static int
3018new_init_module(const char *m_name, struct obj_file *f, 2568new_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
3143static int 2678static int
3144obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, 2679obj_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
3160static int obj_check_undefineds(struct obj_file *f) 2694static int obj_check_undefineds(struct obj_file *f)
3161{ 2695{
@@ -3853,10 +3387,7 @@ static int
3853get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) 3387get_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)
4075extern int insmod_main( int argc, char **argv) 3606extern 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;