diff options
| author | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-02 23:31:10 +0000 |
|---|---|---|
| committer | Denis Vlasenko <vda.linux@googlemail.com> | 2007-11-02 23:31:10 +0000 |
| commit | b68979aefa0efb519e6af02deba082e6b4180043 (patch) | |
| tree | b16d64f31b629e54c70d30abbd98f3b4f46d7cd4 /modutils | |
| parent | 9d1afdb571e0ba3053616d74edc99a68325ef5e9 (diff) | |
| download | busybox-w32-b68979aefa0efb519e6af02deba082e6b4180043.tar.gz busybox-w32-b68979aefa0efb519e6af02deba082e6b4180043.tar.bz2 busybox-w32-b68979aefa0efb519e6af02deba082e6b4180043.zip | |
insmod: code shrink, stop exporting insmod_ng_main.
function old new delta
add_ksymoops_symbols - 421 +421
static.section_names 20 40 +20
lsmod_main 425 424 -1
set_tainted 153 150 -3
main_opts 4 - -4
obj_symbol_patch 47 42 -5
obj_string_patch 144 139 -5
already_loaded 144 138 -6
check_dep 348 341 -7
append_option 75 68 -7
obj_allocate_commons 515 501 -14
new_process_module_arguments 1039 1018 -21
arch_new_symbol 31 9 -22
check_module_name_match 85 61 -24
obj_create_alloced_section 164 136 -28
include_conf 930 902 -28
modprobe_main 1643 1535 -108
obj_load 924 777 -147
insmod_ng_main 245 - -245
insmod_main 4122 3794 -328
------------------------------------------------------------------------------
(add/remove: 1/2 grow/shrink: 1/16 up/down: 441/-1003) Total: -562 bytes
text data bss dec hex filename
776020 974 9420 786414 bffee busybox_old
775384 974 9420 785778 bfd72 busybox_unstripped
Diffstat (limited to 'modutils')
| -rw-r--r-- | modutils/insmod.c | 411 | ||||
| -rw-r--r-- | modutils/lsmod.c | 10 | ||||
| -rw-r--r-- | modutils/modprobe.c | 270 |
3 files changed, 311 insertions, 380 deletions
diff --git a/modutils/insmod.c b/modutils/insmod.c index 6f3b7d0f4..df75abbfa 100644 --- a/modutils/insmod.c +++ b/modutils/insmod.c | |||
| @@ -67,25 +67,21 @@ | |||
| 67 | #define ENABLE_FEATURE_2_4_MODULES 1 | 67 | #define ENABLE_FEATURE_2_4_MODULES 1 |
| 68 | #endif | 68 | #endif |
| 69 | 69 | ||
| 70 | #if !ENABLE_FEATURE_2_4_MODULES | 70 | /* |
| 71 | #define insmod_ng_main insmod_main | 71 | * Big piece of 2.4-specific code |
| 72 | #endif | 72 | */ |
| 73 | #if ENABLE_FEATURE_2_4_MODULES | ||
| 73 | 74 | ||
| 74 | #if ENABLE_FEATURE_2_6_MODULES | 75 | #if ENABLE_FEATURE_2_6_MODULES |
| 75 | extern int insmod_ng_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 76 | static int insmod_ng_main(int argc, char **argv); |
| 76 | #endif | 77 | #endif |
| 77 | 78 | ||
| 78 | |||
| 79 | #if ENABLE_FEATURE_2_4_MODULES | ||
| 80 | |||
| 81 | |||
| 82 | #if ENABLE_FEATURE_INSMOD_LOADINKMEM | 79 | #if ENABLE_FEATURE_INSMOD_LOADINKMEM |
| 83 | #define LOADBITS 0 | 80 | #define LOADBITS 0 |
| 84 | #else | 81 | #else |
| 85 | #define LOADBITS 1 | 82 | #define LOADBITS 1 |
| 86 | #endif | 83 | #endif |
| 87 | 84 | ||
| 88 | |||
| 89 | /* Alpha */ | 85 | /* Alpha */ |
| 90 | #if defined(__alpha__) | 86 | #if defined(__alpha__) |
| 91 | #define MATCH_MACHINE(x) (x == EM_ALPHA) | 87 | #define MATCH_MACHINE(x) (x == EM_ALPHA) |
| @@ -627,13 +623,13 @@ static struct obj_section *obj_create_alloced_section_first(struct obj_file *f, | |||
| 627 | 623 | ||
| 628 | static void *obj_extend_section(struct obj_section *sec, unsigned long more); | 624 | static void *obj_extend_section(struct obj_section *sec, unsigned long more); |
| 629 | 625 | ||
| 630 | static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, | 626 | static void obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, |
| 631 | const char *string); | 627 | const char *string); |
| 632 | 628 | ||
| 633 | static int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, | 629 | static void obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, |
| 634 | struct obj_symbol *sym); | 630 | struct obj_symbol *sym); |
| 635 | 631 | ||
| 636 | static int obj_check_undefineds(struct obj_file *f); | 632 | static void obj_check_undefineds(struct obj_file *f); |
| 637 | 633 | ||
| 638 | static void obj_allocate_commons(struct obj_file *f); | 634 | static void obj_allocate_commons(struct obj_file *f); |
| 639 | 635 | ||
| @@ -788,7 +784,6 @@ static size_t nksyms; | |||
| 788 | static struct external_module *ext_modules; | 784 | static struct external_module *ext_modules; |
| 789 | static int n_ext_modules; | 785 | static int n_ext_modules; |
| 790 | static int n_ext_modules_used; | 786 | static int n_ext_modules_used; |
| 791 | extern int delete_module(const char *); | ||
| 792 | 787 | ||
| 793 | static char *m_filename; | 788 | static char *m_filename; |
| 794 | static char *m_fullName; | 789 | static char *m_fullName; |
| @@ -801,19 +796,16 @@ static int check_module_name_match(const char *filename, struct stat *statbuf, | |||
| 801 | void *userdata, int depth) | 796 | void *userdata, int depth) |
| 802 | { | 797 | { |
| 803 | char *fullname = (char *) userdata; | 798 | char *fullname = (char *) userdata; |
| 799 | char *tmp; | ||
| 804 | 800 | ||
| 805 | if (fullname[0] == '\0') | 801 | if (fullname[0] == '\0') |
| 806 | return FALSE; | 802 | return FALSE; |
| 807 | else { | 803 | |
| 808 | char *tmp, *tmp1 = xstrdup(filename); | 804 | tmp = bb_get_last_path_component_nostrip(filename); |
| 809 | tmp = bb_get_last_path_component_nostrip(tmp1); | 805 | if (strcmp(tmp, fullname) == 0) { |
| 810 | if (strcmp(tmp, fullname) == 0) { | 806 | /* Stop searching if we find a match */ |
| 811 | free(tmp1); | 807 | m_filename = xstrdup(filename); |
| 812 | /* Stop searching if we find a match */ | 808 | return FALSE; |
| 813 | m_filename = xstrdup(filename); | ||
| 814 | return FALSE; | ||
| 815 | } | ||
| 816 | free(tmp1); | ||
| 817 | } | 809 | } |
| 818 | return TRUE; | 810 | return TRUE; |
| 819 | } | 811 | } |
| @@ -824,25 +816,19 @@ static int check_module_name_match(const char *filename, struct stat *statbuf, | |||
| 824 | static struct obj_file *arch_new_file(void) | 816 | static struct obj_file *arch_new_file(void) |
| 825 | { | 817 | { |
| 826 | struct arch_file *f; | 818 | struct arch_file *f; |
| 827 | f = xmalloc(sizeof(*f)); | 819 | f = xzalloc(sizeof(*f)); |
| 828 | 820 | return &f->root; /* it's a first member */ | |
| 829 | memset(f, 0, sizeof(*f)); | ||
| 830 | |||
| 831 | return &f->root; | ||
| 832 | } | 821 | } |
| 833 | 822 | ||
| 834 | static struct obj_section *arch_new_section(void) | 823 | static struct obj_section *arch_new_section(void) |
| 835 | { | 824 | { |
| 836 | return xmalloc(sizeof(struct obj_section)); | 825 | return xzalloc(sizeof(struct obj_section)); |
| 837 | } | 826 | } |
| 838 | 827 | ||
| 839 | static struct obj_symbol *arch_new_symbol(void) | 828 | static struct obj_symbol *arch_new_symbol(void) |
| 840 | { | 829 | { |
| 841 | struct arch_symbol *sym; | 830 | struct arch_symbol *sym; |
| 842 | sym = xmalloc(sizeof(*sym)); | 831 | sym = xzalloc(sizeof(*sym)); |
| 843 | |||
| 844 | memset(sym, 0, sizeof(*sym)); | ||
| 845 | |||
| 846 | return &sym->root; | 832 | return &sym->root; |
| 847 | } | 833 | } |
| 848 | 834 | ||
| @@ -2210,7 +2196,6 @@ static struct obj_section *obj_create_alloced_section(struct obj_file *f, | |||
| 2210 | f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec)); | 2196 | f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec)); |
| 2211 | f->sections[newidx] = sec = arch_new_section(); | 2197 | f->sections[newidx] = sec = arch_new_section(); |
| 2212 | 2198 | ||
| 2213 | memset(sec, 0, sizeof(*sec)); | ||
| 2214 | sec->header.sh_type = SHT_PROGBITS; | 2199 | sec->header.sh_type = SHT_PROGBITS; |
| 2215 | sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; | 2200 | sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; |
| 2216 | sec->header.sh_size = size; | 2201 | sec->header.sh_size = size; |
| @@ -2236,7 +2221,6 @@ static struct obj_section *obj_create_alloced_section_first(struct obj_file *f, | |||
| 2236 | f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec)); | 2221 | f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec)); |
| 2237 | f->sections[newidx] = sec = arch_new_section(); | 2222 | f->sections[newidx] = sec = arch_new_section(); |
| 2238 | 2223 | ||
| 2239 | memset(sec, 0, sizeof(*sec)); | ||
| 2240 | sec->header.sh_type = SHT_PROGBITS; | 2224 | sec->header.sh_type = SHT_PROGBITS; |
| 2241 | sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; | 2225 | sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; |
| 2242 | sec->header.sh_size = size; | 2226 | sec->header.sh_size = size; |
| @@ -2398,7 +2382,7 @@ static char *get_modinfo_value(struct obj_file *f, const char *key) | |||
| 2398 | /*======================================================================*/ | 2382 | /*======================================================================*/ |
| 2399 | /* Functions relating to module loading after 2.1.18. */ | 2383 | /* Functions relating to module loading after 2.1.18. */ |
| 2400 | 2384 | ||
| 2401 | static int | 2385 | static void |
| 2402 | new_process_module_arguments(struct obj_file *f, int argc, char **argv) | 2386 | new_process_module_arguments(struct obj_file *f, int argc, char **argv) |
| 2403 | { | 2387 | { |
| 2404 | while (argc > 0) { | 2388 | while (argc > 0) { |
| @@ -2408,7 +2392,8 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) | |||
| 2408 | int min, max, n; | 2392 | int min, max, n; |
| 2409 | 2393 | ||
| 2410 | p = *argv; | 2394 | p = *argv; |
| 2411 | if ((q = strchr(p, '=')) == NULL) { | 2395 | q = strchr(p, '='); |
| 2396 | if (q == NULL) { | ||
| 2412 | argc--; | 2397 | argc--; |
| 2413 | continue; | 2398 | continue; |
| 2414 | } | 2399 | } |
| @@ -2421,8 +2406,7 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) | |||
| 2421 | p = get_modinfo_value(f, key); | 2406 | p = get_modinfo_value(f, key); |
| 2422 | key += 5; | 2407 | key += 5; |
| 2423 | if (p == NULL) { | 2408 | if (p == NULL) { |
| 2424 | bb_error_msg("invalid parameter %s", key); | 2409 | bb_error_msg_and_die("invalid parameter %s", key); |
| 2425 | return 0; | ||
| 2426 | } | 2410 | } |
| 2427 | 2411 | ||
| 2428 | #ifdef SYMBOL_PREFIX | 2412 | #ifdef SYMBOL_PREFIX |
| @@ -2436,8 +2420,7 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) | |||
| 2436 | 2420 | ||
| 2437 | /* Also check that the parameter was not resolved from the kernel. */ | 2421 | /* Also check that the parameter was not resolved from the kernel. */ |
| 2438 | if (sym == NULL || sym->secidx > SHN_HIRESERVE) { | 2422 | if (sym == NULL || sym->secidx > SHN_HIRESERVE) { |
| 2439 | bb_error_msg("symbol for parameter %s not found", key); | 2423 | bb_error_msg_and_die("symbol for parameter %s not found", key); |
| 2440 | return 0; | ||
| 2441 | } | 2424 | } |
| 2442 | 2425 | ||
| 2443 | if (isdigit(*p)) { | 2426 | if (isdigit(*p)) { |
| @@ -2463,11 +2446,10 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) | |||
| 2463 | 2446 | ||
| 2464 | str = alloca(strlen(q)); | 2447 | str = alloca(strlen(q)); |
| 2465 | for (r = str, q++; *q != '"'; ++q, ++r) { | 2448 | for (r = str, q++; *q != '"'; ++q, ++r) { |
| 2466 | if (*q == '\0') { | 2449 | if (*q == '\0') |
| 2467 | bb_error_msg("improperly terminated string argument for %s", | 2450 | bb_error_msg_and_die("improperly terminated string argument for %s", |
| 2468 | key); | 2451 | key); |
| 2469 | return 0; | 2452 | if (*q == '\\') |
| 2470 | } else if (*q == '\\') | ||
| 2471 | switch (*++q) { | 2453 | switch (*++q) { |
| 2472 | case 'a': | 2454 | case 'a': |
| 2473 | *r = '\a'; | 2455 | *r = '\a'; |
| @@ -2513,8 +2495,9 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) | |||
| 2513 | default: | 2495 | default: |
| 2514 | *r = *q; | 2496 | *r = *q; |
| 2515 | break; | 2497 | break; |
| 2516 | } else | 2498 | } |
| 2517 | *r = *q; | 2499 | else |
| 2500 | *r = *q; | ||
| 2518 | } | 2501 | } |
| 2519 | *r = '\0'; | 2502 | *r = '\0'; |
| 2520 | ++q; | 2503 | ++q; |
| @@ -2558,17 +2541,15 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) | |||
| 2558 | /* Get the size of each member */ | 2541 | /* Get the size of each member */ |
| 2559 | /* Probably we should do that outside the loop ? */ | 2542 | /* Probably we should do that outside the loop ? */ |
| 2560 | if (!isdigit(*(p + 1))) { | 2543 | if (!isdigit(*(p + 1))) { |
| 2561 | bb_error_msg("parameter type 'c' for %s must be followed by" | 2544 | bb_error_msg_and_die("parameter type 'c' for %s must be followed by" |
| 2562 | " the maximum size", key); | 2545 | " the maximum size", key); |
| 2563 | return 0; | ||
| 2564 | } | 2546 | } |
| 2565 | charssize = strtoul(p + 1, (char **) NULL, 10); | 2547 | charssize = strtoul(p + 1, (char **) NULL, 10); |
| 2566 | 2548 | ||
| 2567 | /* Check length */ | 2549 | /* Check length */ |
| 2568 | if (strlen(str) >= charssize) { | 2550 | if (strlen(str) >= charssize) { |
| 2569 | bb_error_msg("string too long for %s (max %ld)", key, | 2551 | bb_error_msg_and_die("string too long for %s (max %ld)", key, |
| 2570 | charssize - 1); | 2552 | charssize - 1); |
| 2571 | return 0; | ||
| 2572 | } | 2553 | } |
| 2573 | 2554 | ||
| 2574 | /* Copy to location */ | 2555 | /* Copy to location */ |
| @@ -2595,12 +2576,10 @@ new_process_module_arguments(struct obj_file *f, int argc, char **argv) | |||
| 2595 | break; | 2576 | break; |
| 2596 | 2577 | ||
| 2597 | default: | 2578 | default: |
| 2598 | bb_error_msg("unknown parameter type '%c' for %s", *p, key); | 2579 | bb_error_msg_and_die("unknown parameter type '%c' for %s", *p, key); |
| 2599 | return 0; | ||
| 2600 | } | 2580 | } |
| 2601 | } | 2581 | } |
| 2602 | 2582 | retry_end_of_value: | |
| 2603 | retry_end_of_value: | ||
| 2604 | switch (*q) { | 2583 | switch (*q) { |
| 2605 | case '\0': | 2584 | case '\0': |
| 2606 | goto end_of_arg; | 2585 | goto end_of_arg; |
| @@ -2614,28 +2593,23 @@ retry_end_of_value: | |||
| 2614 | 2593 | ||
| 2615 | case ',': | 2594 | case ',': |
| 2616 | if (++n > max) { | 2595 | if (++n > max) { |
| 2617 | bb_error_msg("too many values for %s (max %d)", key, max); | 2596 | bb_error_msg_and_die("too many values for %s (max %d)", key, max); |
| 2618 | return 0; | ||
| 2619 | } | 2597 | } |
| 2620 | ++q; | 2598 | ++q; |
| 2621 | break; | 2599 | break; |
| 2622 | 2600 | ||
| 2623 | default: | 2601 | default: |
| 2624 | bb_error_msg("invalid argument syntax for %s", key); | 2602 | bb_error_msg_and_die("invalid argument syntax for %s", key); |
| 2625 | return 0; | ||
| 2626 | } | 2603 | } |
| 2627 | } | 2604 | } |
| 2628 | 2605 | end_of_arg: | |
| 2629 | end_of_arg: | ||
| 2630 | if (n < min) { | 2606 | if (n < min) { |
| 2631 | bb_error_msg("too few values for %s (min %d)", key, min); | 2607 | bb_error_msg_and_die("too few values for %s (min %d)", key, min); |
| 2632 | return 0; | ||
| 2633 | } | 2608 | } |
| 2634 | 2609 | ||
| 2635 | argc--, argv++; | 2610 | argc--; |
| 2611 | argv++; | ||
| 2636 | } | 2612 | } |
| 2637 | |||
| 2638 | return 1; | ||
| 2639 | } | 2613 | } |
| 2640 | 2614 | ||
| 2641 | #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING | 2615 | #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING |
| @@ -2644,8 +2618,7 @@ static int new_is_module_checksummed(struct obj_file *f) | |||
| 2644 | const char *p = get_modinfo_value(f, "using_checksums"); | 2618 | const char *p = get_modinfo_value(f, "using_checksums"); |
| 2645 | if (p) | 2619 | if (p) |
| 2646 | return xatoi(p); | 2620 | return xatoi(p); |
| 2647 | else | 2621 | return 0; |
| 2648 | return 0; | ||
| 2649 | } | 2622 | } |
| 2650 | 2623 | ||
| 2651 | /* Get the module's kernel version in the canonical integer form. */ | 2624 | /* Get the module's kernel version in the canonical integer form. */ |
| @@ -2679,7 +2652,7 @@ new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) | |||
| 2679 | 2652 | ||
| 2680 | /* Fetch the loaded modules, and all currently exported symbols. */ | 2653 | /* Fetch the loaded modules, and all currently exported symbols. */ |
| 2681 | 2654 | ||
| 2682 | static int new_get_kernel_symbols(void) | 2655 | static void new_get_kernel_symbols(void) |
| 2683 | { | 2656 | { |
| 2684 | char *module_names, *mn; | 2657 | char *module_names, *mn; |
| 2685 | struct external_module *modules, *m; | 2658 | struct external_module *modules, *m; |
| @@ -2688,15 +2661,17 @@ static int new_get_kernel_symbols(void) | |||
| 2688 | 2661 | ||
| 2689 | /* Collect the loaded modules. */ | 2662 | /* Collect the loaded modules. */ |
| 2690 | 2663 | ||
| 2691 | module_names = xmalloc(bufsize = 256); | 2664 | bufsize = 256; |
| 2692 | retry_modules_load: | 2665 | module_names = xmalloc(bufsize); |
| 2666 | |||
| 2667 | retry_modules_load: | ||
| 2693 | if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) { | 2668 | if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) { |
| 2694 | if (errno == ENOSPC && bufsize < ret) { | 2669 | if (errno == ENOSPC && bufsize < ret) { |
| 2695 | module_names = xrealloc(module_names, bufsize = ret); | 2670 | bufsize = ret; |
| 2671 | module_names = xrealloc(module_names, bufsize); | ||
| 2696 | goto retry_modules_load; | 2672 | goto retry_modules_load; |
| 2697 | } | 2673 | } |
| 2698 | bb_perror_msg("QM_MODULES"); | 2674 | bb_perror_msg_and_die("QM_MODULES"); |
| 2699 | return 0; | ||
| 2700 | } | 2675 | } |
| 2701 | 2676 | ||
| 2702 | n_ext_modules = nmod = ret; | 2677 | n_ext_modules = nmod = ret; |
| @@ -2715,23 +2690,23 @@ retry_modules_load: | |||
| 2715 | /* The module was removed out from underneath us. */ | 2690 | /* The module was removed out from underneath us. */ |
| 2716 | continue; | 2691 | continue; |
| 2717 | } | 2692 | } |
| 2718 | bb_perror_msg("query_module: QM_INFO: %s", mn); | 2693 | bb_perror_msg_and_die("query_module: QM_INFO: %s", mn); |
| 2719 | return 0; | ||
| 2720 | } | 2694 | } |
| 2721 | 2695 | ||
| 2722 | syms = xmalloc(bufsize = 1024); | 2696 | bufsize = 1024; |
| 2723 | retry_mod_sym_load: | 2697 | syms = xmalloc(bufsize); |
| 2698 | retry_mod_sym_load: | ||
| 2724 | if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) { | 2699 | if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) { |
| 2725 | switch (errno) { | 2700 | switch (errno) { |
| 2726 | case ENOSPC: | 2701 | case ENOSPC: |
| 2727 | syms = xrealloc(syms, bufsize = ret); | 2702 | bufsize = ret; |
| 2703 | syms = xrealloc(syms, bufsize); | ||
| 2728 | goto retry_mod_sym_load; | 2704 | goto retry_mod_sym_load; |
| 2729 | case ENOENT: | 2705 | case ENOENT: |
| 2730 | /* The module was removed out from underneath us. */ | 2706 | /* The module was removed out from underneath us. */ |
| 2731 | continue; | 2707 | continue; |
| 2732 | default: | 2708 | default: |
| 2733 | bb_perror_msg("query_module: QM_SYMBOLS: %s", mn); | 2709 | bb_perror_msg_and_die("query_module: QM_SYMBOLS: %s", mn); |
| 2734 | return 0; | ||
| 2735 | } | 2710 | } |
| 2736 | } | 2711 | } |
| 2737 | nsyms = ret; | 2712 | nsyms = ret; |
| @@ -2750,14 +2725,13 @@ retry_mod_sym_load: | |||
| 2750 | /* Collect the kernel's symbols. */ | 2725 | /* Collect the kernel's symbols. */ |
| 2751 | 2726 | ||
| 2752 | syms = xmalloc(bufsize = 16 * 1024); | 2727 | syms = xmalloc(bufsize = 16 * 1024); |
| 2753 | retry_kern_sym_load: | 2728 | retry_kern_sym_load: |
| 2754 | if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) { | 2729 | if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) { |
| 2755 | if (errno == ENOSPC && bufsize < ret) { | 2730 | if (errno == ENOSPC && bufsize < ret) { |
| 2756 | syms = xrealloc(syms, bufsize = ret); | 2731 | syms = xrealloc(syms, bufsize = ret); |
| 2757 | goto retry_kern_sym_load; | 2732 | goto retry_kern_sym_load; |
| 2758 | } | 2733 | } |
| 2759 | bb_perror_msg("kernel: QM_SYMBOLS"); | 2734 | bb_perror_msg_and_die("kernel: QM_SYMBOLS"); |
| 2760 | return 0; | ||
| 2761 | } | 2735 | } |
| 2762 | nksyms = nsyms = ret; | 2736 | nksyms = nsyms = ret; |
| 2763 | ksyms = syms; | 2737 | ksyms = syms; |
| @@ -2765,7 +2739,6 @@ retry_kern_sym_load: | |||
| 2765 | for (j = 0, s = syms; j < nsyms; ++j, ++s) { | 2739 | for (j = 0, s = syms; j < nsyms; ++j, ++s) { |
| 2766 | s->name += (unsigned long) syms; | 2740 | s->name += (unsigned long) syms; |
| 2767 | } | 2741 | } |
| 2768 | return 1; | ||
| 2769 | } | 2742 | } |
| 2770 | 2743 | ||
| 2771 | 2744 | ||
| @@ -2786,7 +2759,7 @@ static int new_is_kernel_checksummed(void) | |||
| 2786 | } | 2759 | } |
| 2787 | 2760 | ||
| 2788 | 2761 | ||
| 2789 | static int new_create_this_module(struct obj_file *f, const char *m_name) | 2762 | static void new_create_this_module(struct obj_file *f, const char *m_name) |
| 2790 | { | 2763 | { |
| 2791 | struct obj_section *sec; | 2764 | struct obj_section *sec; |
| 2792 | 2765 | ||
| @@ -2800,8 +2773,6 @@ static int new_create_this_module(struct obj_file *f, const char *m_name) | |||
| 2800 | 2773 | ||
| 2801 | obj_string_patch(f, sec->idx, offsetof(struct new_module, name), | 2774 | obj_string_patch(f, sec->idx, offsetof(struct new_module, name), |
| 2802 | m_name); | 2775 | m_name); |
| 2803 | |||
| 2804 | return 1; | ||
| 2805 | } | 2776 | } |
| 2806 | 2777 | ||
| 2807 | #if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS | 2778 | #if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS |
| @@ -2985,7 +2956,7 @@ new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size) | |||
| 2985 | 2956 | ||
| 2986 | /*======================================================================*/ | 2957 | /*======================================================================*/ |
| 2987 | 2958 | ||
| 2988 | static int | 2959 | static void |
| 2989 | obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, | 2960 | obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, |
| 2990 | const char *string) | 2961 | const char *string) |
| 2991 | { | 2962 | { |
| @@ -3010,11 +2981,9 @@ obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, | |||
| 3010 | loc = obj_extend_section(strsec, len); | 2981 | loc = obj_extend_section(strsec, len); |
| 3011 | } | 2982 | } |
| 3012 | memcpy(loc, string, len); | 2983 | memcpy(loc, string, len); |
| 3013 | |||
| 3014 | return 1; | ||
| 3015 | } | 2984 | } |
| 3016 | 2985 | ||
| 3017 | static int | 2986 | static void |
| 3018 | obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, | 2987 | obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, |
| 3019 | struct obj_symbol *sym) | 2988 | struct obj_symbol *sym) |
| 3020 | { | 2989 | { |
| @@ -3026,14 +2995,11 @@ obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, | |||
| 3026 | p->reloc_offset = offset; | 2995 | p->reloc_offset = offset; |
| 3027 | p->sym = sym; | 2996 | p->sym = sym; |
| 3028 | f->symbol_patches = p; | 2997 | f->symbol_patches = p; |
| 3029 | |||
| 3030 | return 1; | ||
| 3031 | } | 2998 | } |
| 3032 | 2999 | ||
| 3033 | static int obj_check_undefineds(struct obj_file *f) | 3000 | static void obj_check_undefineds(struct obj_file *f) |
| 3034 | { | 3001 | { |
| 3035 | unsigned long i; | 3002 | unsigned i; |
| 3036 | int ret = 1; | ||
| 3037 | 3003 | ||
| 3038 | for (i = 0; i < HASH_BUCKETS; ++i) { | 3004 | for (i = 0; i < HASH_BUCKETS; ++i) { |
| 3039 | struct obj_symbol *sym; | 3005 | struct obj_symbol *sym; |
| @@ -3043,15 +3009,11 @@ static int obj_check_undefineds(struct obj_file *f) | |||
| 3043 | sym->secidx = SHN_ABS; | 3009 | sym->secidx = SHN_ABS; |
| 3044 | sym->value = 0; | 3010 | sym->value = 0; |
| 3045 | } else { | 3011 | } else { |
| 3046 | if (!flag_quiet) { | 3012 | if (!flag_quiet) |
| 3047 | bb_error_msg("unresolved symbol %s", sym->name); | 3013 | bb_error_msg_and_die("unresolved symbol %s", sym->name); |
| 3048 | } | ||
| 3049 | ret = 0; | ||
| 3050 | } | 3014 | } |
| 3051 | } | 3015 | } |
| 3052 | } | 3016 | } |
| 3053 | |||
| 3054 | return ret; | ||
| 3055 | } | 3017 | } |
| 3056 | 3018 | ||
| 3057 | static void obj_allocate_commons(struct obj_file *f) | 3019 | static void obj_allocate_commons(struct obj_file *f) |
| @@ -3114,7 +3076,6 @@ static void obj_allocate_commons(struct obj_file *f) | |||
| 3114 | f->sections[i] = sec = arch_new_section(); | 3076 | f->sections[i] = sec = arch_new_section(); |
| 3115 | f->header.e_shnum = i + 1; | 3077 | f->header.e_shnum = i + 1; |
| 3116 | 3078 | ||
| 3117 | memset(sec, 0, sizeof(*sec)); | ||
| 3118 | sec->header.sh_type = SHT_PROGBITS; | 3079 | sec->header.sh_type = SHT_PROGBITS; |
| 3119 | sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; | 3080 | sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; |
| 3120 | sec->name = ".bss"; | 3081 | sec->name = ".bss"; |
| @@ -3347,44 +3308,38 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) | |||
| 3347 | /* Read the file header. */ | 3308 | /* Read the file header. */ |
| 3348 | 3309 | ||
| 3349 | f = arch_new_file(); | 3310 | f = arch_new_file(); |
| 3350 | memset(f, 0, sizeof(*f)); | ||
| 3351 | f->symbol_cmp = strcmp; | 3311 | f->symbol_cmp = strcmp; |
| 3352 | f->symbol_hash = obj_elf_hash; | 3312 | f->symbol_hash = obj_elf_hash; |
| 3353 | f->load_order_search_start = &f->load_order; | 3313 | f->load_order_search_start = &f->load_order; |
| 3354 | 3314 | ||
| 3355 | fseek(fp, 0, SEEK_SET); | 3315 | fseek(fp, 0, SEEK_SET); |
| 3356 | if (fread(&f->header, sizeof(f->header), 1, fp) != 1) { | 3316 | if (fread(&f->header, sizeof(f->header), 1, fp) != 1) { |
| 3357 | bb_perror_msg("error reading ELF header"); | 3317 | bb_perror_msg_and_die("error reading ELF header"); |
| 3358 | return NULL; | ||
| 3359 | } | 3318 | } |
| 3360 | 3319 | ||
| 3361 | if (f->header.e_ident[EI_MAG0] != ELFMAG0 | 3320 | if (f->header.e_ident[EI_MAG0] != ELFMAG0 |
| 3362 | || f->header.e_ident[EI_MAG1] != ELFMAG1 | 3321 | || f->header.e_ident[EI_MAG1] != ELFMAG1 |
| 3363 | || f->header.e_ident[EI_MAG2] != ELFMAG2 | 3322 | || f->header.e_ident[EI_MAG2] != ELFMAG2 |
| 3364 | || f->header.e_ident[EI_MAG3] != ELFMAG3) { | 3323 | || f->header.e_ident[EI_MAG3] != ELFMAG3) { |
| 3365 | bb_error_msg("not an ELF file"); | 3324 | bb_error_msg_and_die("not an ELF file"); |
| 3366 | return NULL; | ||
| 3367 | } | 3325 | } |
| 3368 | if (f->header.e_ident[EI_CLASS] != ELFCLASSM | 3326 | if (f->header.e_ident[EI_CLASS] != ELFCLASSM |
| 3369 | || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN | 3327 | || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN |
| 3370 | ? ELFDATA2MSB : ELFDATA2LSB) | 3328 | ? ELFDATA2MSB : ELFDATA2LSB) |
| 3371 | || f->header.e_ident[EI_VERSION] != EV_CURRENT | 3329 | || f->header.e_ident[EI_VERSION] != EV_CURRENT |
| 3372 | || !MATCH_MACHINE(f->header.e_machine)) { | 3330 | || !MATCH_MACHINE(f->header.e_machine)) { |
| 3373 | bb_error_msg("ELF file not for this architecture"); | 3331 | bb_error_msg_and_die("ELF file not for this architecture"); |
| 3374 | return NULL; | ||
| 3375 | } | 3332 | } |
| 3376 | if (f->header.e_type != ET_REL) { | 3333 | if (f->header.e_type != ET_REL) { |
| 3377 | bb_error_msg("ELF file not a relocatable object"); | 3334 | bb_error_msg_and_die("ELF file not a relocatable object"); |
| 3378 | return NULL; | ||
| 3379 | } | 3335 | } |
| 3380 | 3336 | ||
| 3381 | /* Read the section headers. */ | 3337 | /* Read the section headers. */ |
| 3382 | 3338 | ||
| 3383 | if (f->header.e_shentsize != sizeof(ElfW(Shdr))) { | 3339 | if (f->header.e_shentsize != sizeof(ElfW(Shdr))) { |
| 3384 | bb_error_msg("section header size mismatch: %lu != %lu", | 3340 | bb_error_msg_and_die("section header size mismatch: %lu != %lu", |
| 3385 | (unsigned long) f->header.e_shentsize, | 3341 | (unsigned long) f->header.e_shentsize, |
| 3386 | (unsigned long) sizeof(ElfW(Shdr))); | 3342 | (unsigned long) sizeof(ElfW(Shdr))); |
| 3387 | return NULL; | ||
| 3388 | } | 3343 | } |
| 3389 | 3344 | ||
| 3390 | shnum = f->header.e_shnum; | 3345 | shnum = f->header.e_shnum; |
| @@ -3394,8 +3349,7 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) | |||
| 3394 | section_headers = alloca(sizeof(ElfW(Shdr)) * shnum); | 3349 | section_headers = alloca(sizeof(ElfW(Shdr)) * shnum); |
| 3395 | fseek(fp, f->header.e_shoff, SEEK_SET); | 3350 | fseek(fp, f->header.e_shoff, SEEK_SET); |
| 3396 | if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) { | 3351 | if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) { |
| 3397 | bb_perror_msg("error reading ELF section headers"); | 3352 | bb_perror_msg_and_die("error reading ELF section headers"); |
| 3398 | return NULL; | ||
| 3399 | } | 3353 | } |
| 3400 | 3354 | ||
| 3401 | /* Read the section data. */ | 3355 | /* Read the section data. */ |
| @@ -3404,7 +3358,6 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) | |||
| 3404 | struct obj_section *sec; | 3358 | struct obj_section *sec; |
| 3405 | 3359 | ||
| 3406 | f->sections[i] = sec = arch_new_section(); | 3360 | f->sections[i] = sec = arch_new_section(); |
| 3407 | memset(sec, 0, sizeof(*sec)); | ||
| 3408 | 3361 | ||
| 3409 | sec->header = section_headers[i]; | 3362 | sec->header = section_headers[i]; |
| 3410 | sec->idx = i; | 3363 | sec->idx = i; |
| @@ -3431,8 +3384,7 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) | |||
| 3431 | sec->contents = xmalloc(sec->header.sh_size); | 3384 | sec->contents = xmalloc(sec->header.sh_size); |
| 3432 | fseek(fp, sec->header.sh_offset, SEEK_SET); | 3385 | fseek(fp, sec->header.sh_offset, SEEK_SET); |
| 3433 | if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) { | 3386 | if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) { |
| 3434 | bb_perror_msg("error reading ELF section data"); | 3387 | bb_perror_msg_and_die("error reading ELF section data"); |
| 3435 | return NULL; | ||
| 3436 | } | 3388 | } |
| 3437 | } else { | 3389 | } else { |
| 3438 | sec->contents = NULL; | 3390 | sec->contents = NULL; |
| @@ -3441,14 +3393,11 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) | |||
| 3441 | 3393 | ||
| 3442 | #if SHT_RELM == SHT_REL | 3394 | #if SHT_RELM == SHT_REL |
| 3443 | case SHT_RELA: | 3395 | case SHT_RELA: |
| 3444 | bb_error_msg("RELA relocations not supported on this architecture"); | 3396 | bb_error_msg_and_die("RELA relocations not supported on this architecture"); |
| 3445 | return NULL; | ||
| 3446 | #else | 3397 | #else |
| 3447 | case SHT_REL: | 3398 | case SHT_REL: |
| 3448 | bb_error_msg("REL relocations not supported on this architecture"); | 3399 | bb_error_msg_and_die("REL relocations not supported on this architecture"); |
| 3449 | return NULL; | ||
| 3450 | #endif | 3400 | #endif |
| 3451 | |||
| 3452 | default: | 3401 | default: |
| 3453 | if (sec->header.sh_type >= SHT_LOPROC) { | 3402 | if (sec->header.sh_type >= SHT_LOPROC) { |
| 3454 | /* Assume processor specific section types are debug | 3403 | /* Assume processor specific section types are debug |
| @@ -3458,9 +3407,8 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) | |||
| 3458 | break; | 3407 | break; |
| 3459 | } | 3408 | } |
| 3460 | 3409 | ||
| 3461 | bb_error_msg("can't handle sections of type %ld", | 3410 | bb_error_msg_and_die("can't handle sections of type %ld", |
| 3462 | (long) sec->header.sh_type); | 3411 | (long) sec->header.sh_type); |
| 3463 | return NULL; | ||
| 3464 | } | 3412 | } |
| 3465 | } | 3413 | } |
| 3466 | } | 3414 | } |
| @@ -3494,10 +3442,9 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) | |||
| 3494 | ElfW(Sym) * sym; | 3442 | ElfW(Sym) * sym; |
| 3495 | 3443 | ||
| 3496 | if (sec->header.sh_entsize != sizeof(ElfW(Sym))) { | 3444 | if (sec->header.sh_entsize != sizeof(ElfW(Sym))) { |
| 3497 | bb_error_msg("symbol size mismatch: %lu != %lu", | 3445 | bb_error_msg_and_die("symbol size mismatch: %lu != %lu", |
| 3498 | (unsigned long) sec->header.sh_entsize, | 3446 | (unsigned long) sec->header.sh_entsize, |
| 3499 | (unsigned long) sizeof(ElfW(Sym))); | 3447 | (unsigned long) sizeof(ElfW(Sym))); |
| 3500 | return NULL; | ||
| 3501 | } | 3448 | } |
| 3502 | 3449 | ||
| 3503 | nsym = sec->header.sh_size / sizeof(ElfW(Sym)); | 3450 | nsym = sec->header.sh_size / sizeof(ElfW(Sym)); |
| @@ -3528,7 +3475,6 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) | |||
| 3528 | */ | 3475 | */ |
| 3529 | val |= sym->st_other & 4; | 3476 | val |= sym->st_other & 4; |
| 3530 | #endif | 3477 | #endif |
| 3531 | |||
| 3532 | obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx, | 3478 | obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx, |
| 3533 | val, sym->st_size); | 3479 | val, sym->st_size); |
| 3534 | } | 3480 | } |
| @@ -3537,10 +3483,9 @@ static struct obj_file *obj_load(FILE * fp, int loadprogbits) | |||
| 3537 | 3483 | ||
| 3538 | case SHT_RELM: | 3484 | case SHT_RELM: |
| 3539 | if (sec->header.sh_entsize != sizeof(ElfW(RelM))) { | 3485 | if (sec->header.sh_entsize != sizeof(ElfW(RelM))) { |
| 3540 | bb_error_msg("relocation entry size mismatch: %lu != %lu", | 3486 | bb_error_msg_and_die("relocation entry size mismatch: %lu != %lu", |
| 3541 | (unsigned long) sec->header.sh_entsize, | 3487 | (unsigned long) sec->header.sh_entsize, |
| 3542 | (unsigned long) sizeof(ElfW(RelM))); | 3488 | (unsigned long) sizeof(ElfW(RelM))); |
| 3543 | return NULL; | ||
| 3544 | } | 3489 | } |
| 3545 | break; | 3490 | break; |
| 3546 | /* XXX Relocation code from modutils-2.3.19 is not here. | 3491 | /* XXX Relocation code from modutils-2.3.19 is not here. |
| @@ -3638,8 +3583,9 @@ static int obj_gpl_license(struct obj_file *f, const char **license) | |||
| 3638 | } | 3583 | } |
| 3639 | return 2; | 3584 | return 2; |
| 3640 | } | 3585 | } |
| 3641 | if (strchr(ptr, '\0')) | 3586 | ptr = strchr(ptr, '\0'); |
| 3642 | ptr = strchr(ptr, '\0') + 1; | 3587 | if (ptr) |
| 3588 | ptr++; | ||
| 3643 | else | 3589 | else |
| 3644 | ptr = endptr; | 3590 | ptr = endptr; |
| 3645 | } | 3591 | } |
| @@ -3648,12 +3594,12 @@ static int obj_gpl_license(struct obj_file *f, const char **license) | |||
| 3648 | } | 3594 | } |
| 3649 | 3595 | ||
| 3650 | #define TAINT_FILENAME "/proc/sys/kernel/tainted" | 3596 | #define TAINT_FILENAME "/proc/sys/kernel/tainted" |
| 3651 | #define TAINT_PROPRIETORY_MODULE (1<<0) | 3597 | #define TAINT_PROPRIETORY_MODULE (1 << 0) |
| 3652 | #define TAINT_FORCED_MODULE (1<<1) | 3598 | #define TAINT_FORCED_MODULE (1 << 1) |
| 3653 | #define TAINT_UNSAFE_SMP (1<<2) | 3599 | #define TAINT_UNSAFE_SMP (1 << 2) |
| 3654 | #define TAINT_URL "http://www.tux.org/lkml/#export-tainted" | 3600 | #define TAINT_URL "http://www.tux.org/lkml/#export-tainted" |
| 3655 | 3601 | ||
| 3656 | static void set_tainted(struct obj_file *f, int fd, char *m_name, | 3602 | static void set_tainted(int fd, char *m_name, |
| 3657 | int kernel_has_tainted, int taint, const char *text1, const char *text2) | 3603 | int kernel_has_tainted, int taint, const char *text1, const char *text2) |
| 3658 | { | 3604 | { |
| 3659 | static smallint printed_info; | 3605 | static smallint printed_info; |
| @@ -3703,22 +3649,22 @@ static void check_tainted_module(struct obj_file *f, char *m_name) | |||
| 3703 | case 0: | 3649 | case 0: |
| 3704 | break; | 3650 | break; |
| 3705 | case 1: | 3651 | case 1: |
| 3706 | set_tainted(f, fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", ""); | 3652 | set_tainted(fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", ""); |
| 3707 | break; | 3653 | break; |
| 3708 | case 2: | 3654 | case 2: |
| 3709 | /* The module has a non-GPL license so we pretend that the | 3655 | /* The module has a non-GPL license so we pretend that the |
| 3710 | * kernel always has a taint flag to get a warning even on | 3656 | * kernel always has a taint flag to get a warning even on |
| 3711 | * kernels without the proc flag. | 3657 | * kernels without the proc flag. |
| 3712 | */ | 3658 | */ |
| 3713 | set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr); | 3659 | set_tainted(fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr); |
| 3714 | break; | 3660 | break; |
| 3715 | default: | 3661 | default: |
| 3716 | set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "Unexpected return from obj_gpl_license", ""); | 3662 | set_tainted(fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "Unexpected return from obj_gpl_license", ""); |
| 3717 | break; | 3663 | break; |
| 3718 | } | 3664 | } |
| 3719 | 3665 | ||
| 3720 | if (flag_force_load) | 3666 | if (flag_force_load) |
| 3721 | set_tainted(f, fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", ""); | 3667 | set_tainted(fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", ""); |
| 3722 | 3668 | ||
| 3723 | if (fd >= 0) | 3669 | if (fd >= 0) |
| 3724 | close(fd); | 3670 | close(fd); |
| @@ -3752,15 +3698,7 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename, | |||
| 3752 | const char *m_name) | 3698 | const char *m_name) |
| 3753 | { | 3699 | { |
| 3754 | static const char symprefix[] ALIGN1 = "__insmod_"; | 3700 | static const char symprefix[] ALIGN1 = "__insmod_"; |
| 3755 | 3701 | static const char section_names[][8] = { | |
| 3756 | struct obj_section *sec; | ||
| 3757 | struct obj_symbol *sym; | ||
| 3758 | char *name, *absolute_filename; | ||
| 3759 | char str[STRVERSIONLEN], real[PATH_MAX]; | ||
| 3760 | int i, l, lm_name, lfilename, use_ksymtab, version; | ||
| 3761 | struct stat statbuf; | ||
| 3762 | |||
| 3763 | static const char *section_names[] = { | ||
| 3764 | ".text", | 3702 | ".text", |
| 3765 | ".rodata", | 3703 | ".rodata", |
| 3766 | ".data", | 3704 | ".data", |
| @@ -3768,12 +3706,18 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename, | |||
| 3768 | ".sbss" | 3706 | ".sbss" |
| 3769 | }; | 3707 | }; |
| 3770 | 3708 | ||
| 3771 | if (realpath(filename, real)) { | 3709 | struct obj_section *sec; |
| 3772 | absolute_filename = xstrdup(real); | 3710 | struct obj_symbol *sym; |
| 3773 | } else { | 3711 | char *name, *absolute_filename; |
| 3774 | bb_perror_msg("cannot get realpath for %s", filename); | 3712 | char str[STRVERSIONLEN]; |
| 3713 | int i, l, lm_name, lfilename, use_ksymtab, version; | ||
| 3714 | struct stat statbuf; | ||
| 3715 | |||
| 3716 | /* WARNING: was using realpath, but replaced by readlink to stop using | ||
| 3717 | * lots of stack. But here it seems to be able to cause problems? */ | ||
| 3718 | absolute_filename = xmalloc_readlink(filename); | ||
| 3719 | if (!absolute_filename) | ||
| 3775 | absolute_filename = xstrdup(filename); | 3720 | absolute_filename = xstrdup(filename); |
| 3776 | } | ||
| 3777 | 3721 | ||
| 3778 | lm_name = strlen(m_name); | 3722 | lm_name = strlen(m_name); |
| 3779 | lfilename = strlen(absolute_filename); | 3723 | lfilename = strlen(absolute_filename); |
| @@ -3791,22 +3735,22 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename, | |||
| 3791 | * is 0xffffff, decimal 16777215. putting all three fields in | 3735 | * is 0xffffff, decimal 16777215. putting all three fields in |
| 3792 | * one symbol is less readable but saves kernel space. | 3736 | * one symbol is less readable but saves kernel space. |
| 3793 | */ | 3737 | */ |
| 3794 | l = sizeof(symprefix)+ /* "__insmod_" */ | 3738 | l = sizeof(symprefix) + /* "__insmod_" */ |
| 3795 | lm_name+ /* module name */ | 3739 | lm_name + /* module name */ |
| 3796 | 2+ /* "_O" */ | 3740 | 2 + /* "_O" */ |
| 3797 | lfilename+ /* object filename */ | 3741 | lfilename + /* object filename */ |
| 3798 | 2+ /* "_M" */ | 3742 | 2 + /* "_M" */ |
| 3799 | 2*sizeof(statbuf.st_mtime)+ /* mtime in hex */ | 3743 | 2 * sizeof(statbuf.st_mtime) + /* mtime in hex */ |
| 3800 | 2+ /* "_V" */ | 3744 | 2 + /* "_V" */ |
| 3801 | 8+ /* version in dec */ | 3745 | 8 + /* version in dec */ |
| 3802 | 1; /* nul */ | 3746 | 1; /* nul */ |
| 3803 | name = xmalloc(l); | 3747 | name = xmalloc(l); |
| 3804 | if (stat(absolute_filename, &statbuf) != 0) | 3748 | if (stat(absolute_filename, &statbuf) != 0) |
| 3805 | statbuf.st_mtime = 0; | 3749 | statbuf.st_mtime = 0; |
| 3806 | version = get_module_version(f, str); /* -1 if not found */ | 3750 | version = get_module_version(f, str); /* -1 if not found */ |
| 3807 | snprintf(name, l, "%s%s_O%s_M%0*lX_V%d", | 3751 | snprintf(name, l, "%s%s_O%s_M%0*lX_V%d", |
| 3808 | symprefix, m_name, absolute_filename, | 3752 | symprefix, m_name, absolute_filename, |
| 3809 | (int)(2*sizeof(statbuf.st_mtime)), statbuf.st_mtime, | 3753 | (int)(2 * sizeof(statbuf.st_mtime)), statbuf.st_mtime, |
| 3810 | version); | 3754 | version); |
| 3811 | sym = obj_add_symbol(f, name, -1, | 3755 | sym = obj_add_symbol(f, name, -1, |
| 3812 | ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE), | 3756 | ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE), |
| @@ -3819,11 +3763,11 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename, | |||
| 3819 | /* record where the persistent data is going, same address as previous symbol */ | 3763 | /* record where the persistent data is going, same address as previous symbol */ |
| 3820 | 3764 | ||
| 3821 | if (f->persist) { | 3765 | if (f->persist) { |
| 3822 | l = sizeof(symprefix)+ /* "__insmod_" */ | 3766 | l = sizeof(symprefix) + /* "__insmod_" */ |
| 3823 | lm_name+ /* module name */ | 3767 | lm_name + /* module name */ |
| 3824 | 2+ /* "_P" */ | 3768 | 2 + /* "_P" */ |
| 3825 | strlen(f->persist)+ /* data store */ | 3769 | strlen(f->persist) + /* data store */ |
| 3826 | 1; /* nul */ | 3770 | 1; /* nul */ |
| 3827 | name = xmalloc(l); | 3771 | name = xmalloc(l); |
| 3828 | snprintf(name, l, "%s%s_P%s", | 3772 | snprintf(name, l, "%s%s_P%s", |
| 3829 | symprefix, m_name, f->persist); | 3773 | symprefix, m_name, f->persist); |
| @@ -3838,13 +3782,13 @@ add_ksymoops_symbols(struct obj_file *f, const char *filename, | |||
| 3838 | for (i = 0; i < ARRAY_SIZE(section_names); ++i) { | 3782 | for (i = 0; i < ARRAY_SIZE(section_names); ++i) { |
| 3839 | sec = obj_find_section(f, section_names[i]); | 3783 | sec = obj_find_section(f, section_names[i]); |
| 3840 | if (sec && sec->header.sh_size) { | 3784 | if (sec && sec->header.sh_size) { |
| 3841 | l = sizeof(symprefix)+ /* "__insmod_" */ | 3785 | l = sizeof(symprefix) + /* "__insmod_" */ |
| 3842 | lm_name+ /* module name */ | 3786 | lm_name + /* module name */ |
| 3843 | 2+ /* "_S" */ | 3787 | 2 + /* "_S" */ |
| 3844 | strlen(sec->name)+ /* section name */ | 3788 | strlen(sec->name) + /* section name */ |
| 3845 | 2+ /* "_L" */ | 3789 | 2 + /* "_L" */ |
| 3846 | 8+ /* length in dec */ | 3790 | 8 + /* length in dec */ |
| 3847 | 1; /* nul */ | 3791 | 1; /* nul */ |
| 3848 | name = xmalloc(l); | 3792 | name = xmalloc(l); |
| 3849 | snprintf(name, l, "%s%s_S%s_L%ld", | 3793 | snprintf(name, l, "%s%s_S%s_L%ld", |
| 3850 | symprefix, m_name, sec->name, | 3794 | symprefix, m_name, sec->name, |
| @@ -3891,9 +3835,10 @@ static void print_load_map(struct obj_file *f) | |||
| 3891 | #if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL | 3835 | #if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL |
| 3892 | /* Quick reference which section indicies are loaded. */ | 3836 | /* Quick reference which section indicies are loaded. */ |
| 3893 | 3837 | ||
| 3894 | loaded = alloca(sizeof(int) * (i = f->header.e_shnum)); | 3838 | i = f->header.e_shnum; |
| 3839 | loaded = alloca(sizeof(int) * i); | ||
| 3895 | while (--i >= 0) | 3840 | while (--i >= 0) |
| 3896 | loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0; | 3841 | loaded[i] = ((f->sections[i]->header.sh_flags & SHF_ALLOC) != 0); |
| 3897 | 3842 | ||
| 3898 | /* Collect the symbols we'll be listing. */ | 3843 | /* Collect the symbols we'll be listing. */ |
| 3899 | 3844 | ||
| @@ -3963,7 +3908,7 @@ int insmod_main(int argc, char **argv) | |||
| 3963 | ElfW(Addr) m_addr; | 3908 | ElfW(Addr) m_addr; |
| 3964 | struct obj_file *f; | 3909 | struct obj_file *f; |
| 3965 | struct stat st; | 3910 | struct stat st; |
| 3966 | char *m_name = 0; | 3911 | char *m_name = NULL; |
| 3967 | int exit_status = EXIT_FAILURE; | 3912 | int exit_status = EXIT_FAILURE; |
| 3968 | int m_has_modinfo; | 3913 | int m_has_modinfo; |
| 3969 | #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING | 3914 | #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING |
| @@ -4027,7 +3972,7 @@ int insmod_main(int argc, char **argv) | |||
| 4027 | m_name = tmp; | 3972 | m_name = tmp; |
| 4028 | } else { | 3973 | } else { |
| 4029 | free(tmp1); | 3974 | free(tmp1); |
| 4030 | tmp1 = 0; /* flag for free(m_name) before exit() */ | 3975 | tmp1 = NULL; /* flag for free(m_name) before exit() */ |
| 4031 | } | 3976 | } |
| 4032 | 3977 | ||
| 4033 | /* Get a filedesc for the module. Check that we have a complete path */ | 3978 | /* Get a filedesc for the module. Check that we have a complete path */ |
| @@ -4039,7 +3984,6 @@ int insmod_main(int argc, char **argv) | |||
| 4039 | if (k_version) { /* uname succeedd */ | 3984 | if (k_version) { /* uname succeedd */ |
| 4040 | char *module_dir; | 3985 | char *module_dir; |
| 4041 | char *tmdn; | 3986 | char *tmdn; |
| 4042 | char real_module_dir[FILENAME_MAX]; | ||
| 4043 | 3987 | ||
| 4044 | tmdn = concat_path_file(_PATH_MODULES, myuname.release); | 3988 | tmdn = concat_path_file(_PATH_MODULES, myuname.release); |
| 4045 | /* Jump through hoops in case /lib/modules/`uname -r` | 3989 | /* Jump through hoops in case /lib/modules/`uname -r` |
| @@ -4047,36 +3991,37 @@ int insmod_main(int argc, char **argv) | |||
| 4047 | * follow symlinks, but we do want to follow the | 3991 | * follow symlinks, but we do want to follow the |
| 4048 | * /lib/modules/`uname -r` dir, So resolve it ourselves | 3992 | * /lib/modules/`uname -r` dir, So resolve it ourselves |
| 4049 | * if it is a link... */ | 3993 | * if it is a link... */ |
| 4050 | if (realpath(tmdn, real_module_dir) == NULL) | 3994 | module_dir = xmalloc_readlink(tmdn); |
| 4051 | module_dir = tmdn; | 3995 | if (!module_dir) |
| 4052 | else | 3996 | module_dir = xstrdup(tmdn); |
| 4053 | module_dir = real_module_dir; | ||
| 4054 | recursive_action(module_dir, ACTION_RECURSE, | 3997 | recursive_action(module_dir, ACTION_RECURSE, |
| 4055 | check_module_name_match, 0, m_fullName, 0); | 3998 | check_module_name_match, NULL, m_fullName, 0); |
| 3999 | free(module_dir); | ||
| 4056 | free(tmdn); | 4000 | free(tmdn); |
| 4057 | } | 4001 | } |
| 4058 | 4002 | ||
| 4059 | /* Check if we have found anything yet */ | 4003 | /* Check if we have found anything yet */ |
| 4060 | if (!m_filename || ((fp = fopen(m_filename, "r")) == NULL)) { | 4004 | if (!m_filename || ((fp = fopen(m_filename, "r")) == NULL)) { |
| 4061 | char module_dir[FILENAME_MAX]; | 4005 | int r; |
| 4006 | char *module_dir; | ||
| 4062 | 4007 | ||
| 4063 | free(m_filename); | 4008 | free(m_filename); |
| 4064 | m_filename = NULL; | 4009 | m_filename = NULL; |
| 4065 | if (realpath(_PATH_MODULES, module_dir) == NULL) | 4010 | module_dir = xmalloc_readlink(_PATH_MODULES); |
| 4066 | strcpy(module_dir, _PATH_MODULES); | 4011 | if (!module_dir) |
| 4012 | module_dir = xstrdup(_PATH_MODULES); | ||
| 4067 | /* No module found under /lib/modules/`uname -r`, this | 4013 | /* No module found under /lib/modules/`uname -r`, this |
| 4068 | * time cast the net a bit wider. Search /lib/modules/ */ | 4014 | * time cast the net a bit wider. Search /lib/modules/ */ |
| 4069 | if (!recursive_action(module_dir, ACTION_RECURSE, | 4015 | r = recursive_action(module_dir, ACTION_RECURSE, |
| 4070 | check_module_name_match, 0, m_fullName, 0) | 4016 | check_module_name_match, NULL, m_fullName, 0); |
| 4017 | if (r) | ||
| 4018 | bb_error_msg_and_die("%s: module not found", m_fullName); | ||
| 4019 | free(module_dir); | ||
| 4020 | if (m_filename == NULL | ||
| 4021 | || ((fp = fopen(m_filename, "r")) == NULL) | ||
| 4071 | ) { | 4022 | ) { |
| 4072 | if (m_filename == 0 | ||
| 4073 | || ((fp = fopen(m_filename, "r")) == NULL) | ||
| 4074 | ) { | ||
| 4075 | bb_error_msg("%s: module not found", m_fullName); | ||
| 4076 | goto out; | ||
| 4077 | } | ||
| 4078 | } else | ||
| 4079 | bb_error_msg_and_die("%s: module not found", m_fullName); | 4023 | bb_error_msg_and_die("%s: module not found", m_fullName); |
| 4024 | } | ||
| 4080 | } | 4025 | } |
| 4081 | } else | 4026 | } else |
| 4082 | m_filename = xstrdup(arg1); | 4027 | m_filename = xstrdup(arg1); |
| @@ -4093,8 +4038,6 @@ int insmod_main(int argc, char **argv) | |||
| 4093 | #endif | 4038 | #endif |
| 4094 | 4039 | ||
| 4095 | f = obj_load(fp, LOADBITS); | 4040 | f = obj_load(fp, LOADBITS); |
| 4096 | if (f == NULL) | ||
| 4097 | bb_perror_msg_and_die("cannot load the module"); | ||
| 4098 | 4041 | ||
| 4099 | if (get_modinfo_value(f, "kernel_version") == NULL) | 4042 | if (get_modinfo_value(f, "kernel_version") == NULL) |
| 4100 | m_has_modinfo = 0; | 4043 | m_has_modinfo = 0; |
| @@ -4109,9 +4052,8 @@ int insmod_main(int argc, char **argv) | |||
| 4109 | if (m_has_modinfo) { | 4052 | if (m_has_modinfo) { |
| 4110 | m_version = new_get_module_version(f, m_strversion); | 4053 | m_version = new_get_module_version(f, m_strversion); |
| 4111 | if (m_version == -1) { | 4054 | if (m_version == -1) { |
| 4112 | bb_error_msg("cannot find the kernel version the module was " | 4055 | bb_error_msg_and_die("cannot find the kernel version the module was " |
| 4113 | "compiled for"); | 4056 | "compiled for"); |
| 4114 | goto out; | ||
| 4115 | } | 4057 | } |
| 4116 | } | 4058 | } |
| 4117 | 4059 | ||
| @@ -4128,14 +4070,10 @@ int insmod_main(int argc, char **argv) | |||
| 4128 | k_crcs = 0; | 4070 | k_crcs = 0; |
| 4129 | #endif /* FEATURE_INSMOD_VERSION_CHECKING */ | 4071 | #endif /* FEATURE_INSMOD_VERSION_CHECKING */ |
| 4130 | 4072 | ||
| 4131 | if (!query_module(NULL, 0, NULL, 0, NULL)) { | 4073 | if (query_module(NULL, 0, NULL, 0, NULL)) |
| 4132 | if (!new_get_kernel_symbols()) | 4074 | bb_error_msg_and_die("not configured to support old kernels"); |
| 4133 | goto out; | 4075 | new_get_kernel_symbols(); |
| 4134 | k_crcs = new_is_kernel_checksummed(); | 4076 | k_crcs = new_is_kernel_checksummed(); |
| 4135 | } else { | ||
| 4136 | bb_error_msg("not configured to support old kernels"); | ||
| 4137 | goto out; | ||
| 4138 | } | ||
| 4139 | 4077 | ||
| 4140 | #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING | 4078 | #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING |
| 4141 | m_crcs = 0; | 4079 | m_crcs = 0; |
| @@ -4151,22 +4089,15 @@ int insmod_main(int argc, char **argv) | |||
| 4151 | 4089 | ||
| 4152 | /* Allocate common symbols, symbol tables, and string tables. */ | 4090 | /* Allocate common symbols, symbol tables, and string tables. */ |
| 4153 | 4091 | ||
| 4154 | if (!new_create_this_module(f, m_name)) { | 4092 | new_create_this_module(f, m_name); |
| 4155 | goto out; | 4093 | obj_check_undefineds(f); |
| 4156 | } | ||
| 4157 | |||
| 4158 | if (!obj_check_undefineds(f)) { | ||
| 4159 | goto out; | ||
| 4160 | } | ||
| 4161 | obj_allocate_commons(f); | 4094 | obj_allocate_commons(f); |
| 4162 | check_tainted_module(f, m_name); | 4095 | check_tainted_module(f, m_name); |
| 4163 | 4096 | ||
| 4164 | /* done with the module name, on to the optional var=value arguments */ | 4097 | /* done with the module name, on to the optional var=value arguments */ |
| 4165 | ++optind; | 4098 | ++optind; |
| 4166 | if (optind < argc) { | 4099 | if (optind < argc) { |
| 4167 | if (!new_process_module_arguments(f, argc - optind, argv + optind)) { | 4100 | new_process_module_arguments(f, argc - optind, argv + optind); |
| 4168 | goto out; | ||
| 4169 | } | ||
| 4170 | } | 4101 | } |
| 4171 | 4102 | ||
| 4172 | arch_create_got(f); | 4103 | arch_create_got(f); |
| @@ -4181,22 +4112,18 @@ int insmod_main(int argc, char **argv) | |||
| 4181 | /* Find current size of the module */ | 4112 | /* Find current size of the module */ |
| 4182 | m_size = obj_load_size(f); | 4113 | m_size = obj_load_size(f); |
| 4183 | 4114 | ||
| 4184 | |||
| 4185 | m_addr = create_module(m_name, m_size); | 4115 | m_addr = create_module(m_name, m_size); |
| 4186 | if (m_addr == -1) switch (errno) { | 4116 | if (m_addr == -1) switch (errno) { |
| 4187 | case EEXIST: | 4117 | case EEXIST: |
| 4188 | bb_error_msg("a module named %s already exists", m_name); | 4118 | bb_error_msg_and_die("a module named %s already exists", m_name); |
| 4189 | goto out; | ||
| 4190 | case ENOMEM: | 4119 | case ENOMEM: |
| 4191 | bb_error_msg("can't allocate kernel memory for module; needed %lu bytes", | 4120 | bb_error_msg_and_die("can't allocate kernel memory for module; needed %lu bytes", |
| 4192 | m_size); | 4121 | m_size); |
| 4193 | goto out; | ||
| 4194 | default: | 4122 | default: |
| 4195 | bb_perror_msg("create_module: %s", m_name); | 4123 | bb_perror_msg_and_die("create_module: %s", m_name); |
| 4196 | goto out; | ||
| 4197 | } | 4124 | } |
| 4198 | 4125 | ||
| 4199 | #if !LOADBITS | 4126 | #if !LOADBITS |
| 4200 | /* | 4127 | /* |
| 4201 | * the PROGBITS section was not loaded by the obj_load | 4128 | * the PROGBITS section was not loaded by the obj_load |
| 4202 | * now we can load them directly into the kernel memory | 4129 | * now we can load them directly into the kernel memory |
| @@ -4222,7 +4149,7 @@ int insmod_main(int argc, char **argv) | |||
| 4222 | 4149 | ||
| 4223 | exit_status = EXIT_SUCCESS; | 4150 | exit_status = EXIT_SUCCESS; |
| 4224 | 4151 | ||
| 4225 | out: | 4152 | out: |
| 4226 | #if ENABLE_FEATURE_CLEAN_UP | 4153 | #if ENABLE_FEATURE_CLEAN_UP |
| 4227 | if (fp) | 4154 | if (fp) |
| 4228 | fclose(fp); | 4155 | fclose(fp); |
| @@ -4234,8 +4161,10 @@ out: | |||
| 4234 | return exit_status; | 4161 | return exit_status; |
| 4235 | } | 4162 | } |
| 4236 | 4163 | ||
| 4237 | 4164 | #endif /* ENABLE_FEATURE_2_4_MODULES */ | |
| 4238 | #endif | 4165 | /* |
| 4166 | * End of big piece of 2.4-specific code | ||
| 4167 | */ | ||
| 4239 | 4168 | ||
| 4240 | 4169 | ||
| 4241 | #if ENABLE_FEATURE_2_6_MODULES | 4170 | #if ENABLE_FEATURE_2_6_MODULES |
| @@ -4249,20 +4178,24 @@ static const char *moderror(int err) | |||
| 4249 | { | 4178 | { |
| 4250 | switch (err) { | 4179 | switch (err) { |
| 4251 | case ENOEXEC: | 4180 | case ENOEXEC: |
| 4252 | return "Invalid module format"; | 4181 | return "invalid module format"; |
| 4253 | case ENOENT: | 4182 | case ENOENT: |
| 4254 | return "Unknown symbol in module"; | 4183 | return "unknown symbol in module"; |
| 4255 | case ESRCH: | 4184 | case ESRCH: |
| 4256 | return "Module has wrong symbol version"; | 4185 | return "module has wrong symbol version"; |
| 4257 | case EINVAL: | 4186 | case EINVAL: |
| 4258 | return "Invalid parameters"; | 4187 | return "invalid parameters"; |
| 4259 | default: | 4188 | default: |
| 4260 | return strerror(err); | 4189 | return strerror(err); |
| 4261 | } | 4190 | } |
| 4262 | } | 4191 | } |
| 4263 | 4192 | ||
| 4264 | int insmod_ng_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; | 4193 | #if !ENABLE_FEATURE_2_4_MODULES |
| 4265 | int insmod_ng_main(int argc, char **argv) | 4194 | int insmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
| 4195 | int insmod_main(int argc, char **argv) | ||
| 4196 | #else | ||
| 4197 | static int insmod_ng_main(int argc, char **argv) | ||
| 4198 | #endif | ||
| 4266 | { | 4199 | { |
| 4267 | long ret; | 4200 | long ret; |
| 4268 | size_t len; | 4201 | size_t len; |
diff --git a/modutils/lsmod.c b/modutils/lsmod.c index 70146814c..f1f78ff9f 100644 --- a/modutils/lsmod.c +++ b/modutils/lsmod.c | |||
| @@ -28,17 +28,17 @@ static void check_tainted(void) | |||
| 28 | FILE *f; | 28 | FILE *f; |
| 29 | 29 | ||
| 30 | tainted = 0; | 30 | tainted = 0; |
| 31 | if ((f = fopen(TAINT_FILENAME, "r"))) { | 31 | f = fopen(TAINT_FILENAME, "r"); |
| 32 | if (f) { | ||
| 32 | fscanf(f, "%d", &tainted); | 33 | fscanf(f, "%d", &tainted); |
| 33 | fclose(f); | 34 | fclose(f); |
| 34 | } | 35 | } |
| 35 | if (f && tainted) { | 36 | if (tainted) { |
| 36 | printf(" Tainted: %c%c%c\n", | 37 | printf(" Tainted: %c%c%c\n", |
| 37 | tainted & TAINT_PROPRIETORY_MODULE ? 'P' : 'G', | 38 | tainted & TAINT_PROPRIETORY_MODULE ? 'P' : 'G', |
| 38 | tainted & TAINT_FORCED_MODULE ? 'F' : ' ', | 39 | tainted & TAINT_FORCED_MODULE ? 'F' : ' ', |
| 39 | tainted & TAINT_UNSAFE_SMP ? 'S' : ' '); | 40 | tainted & TAINT_UNSAFE_SMP ? 'S' : ' '); |
| 40 | } | 41 | } else { |
| 41 | else { | ||
| 42 | printf(" Not tainted\n"); | 42 | printf(" Not tainted\n"); |
| 43 | } | 43 | } |
| 44 | } | 44 | } |
| @@ -147,7 +147,7 @@ int lsmod_main(int argc, char **argv) | |||
| 147 | 147 | ||
| 148 | printf("Module Size Used by"); | 148 | printf("Module Size Used by"); |
| 149 | check_tainted(); | 149 | check_tainted(); |
| 150 | #if defined(CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT) | 150 | #if ENABLE_FEATURE_LSMOD_PRETTY_2_6_OUTPUT |
| 151 | { | 151 | { |
| 152 | char *line; | 152 | char *line; |
| 153 | while ((line = xmalloc_fgets(file)) != NULL) { | 153 | while ((line = xmalloc_fgets(file)) != NULL) { |
diff --git a/modutils/modprobe.c b/modutils/modprobe.c index a67ddea9b..f7d193a05 100644 --- a/modutils/modprobe.c +++ b/modutils/modprobe.c | |||
| @@ -15,6 +15,8 @@ | |||
| 15 | #include <sys/utsname.h> | 15 | #include <sys/utsname.h> |
| 16 | #include <fnmatch.h> | 16 | #include <fnmatch.h> |
| 17 | 17 | ||
| 18 | #define line_buffer bb_common_bufsiz1 | ||
| 19 | |||
| 18 | struct mod_opt_t { /* one-way list of options to pass to a module */ | 20 | struct mod_opt_t { /* one-way list of options to pass to a module */ |
| 19 | char * m_opt_val; | 21 | char * m_opt_val; |
| 20 | struct mod_opt_t * m_next; | 22 | struct mod_opt_t * m_next; |
| @@ -48,7 +50,7 @@ struct mod_list_t { /* two-way list of modules to process */ | |||
| 48 | 50 | ||
| 49 | static struct dep_t *depend; | 51 | static struct dep_t *depend; |
| 50 | 52 | ||
| 51 | #define main_options "acdklnqrst:vVC:" | 53 | #define MAIN_OPT_STR "acdklnqrst:vVC:" |
| 52 | #define INSERT_ALL 1 /* a */ | 54 | #define INSERT_ALL 1 /* a */ |
| 53 | #define DUMP_CONF_EXIT 2 /* c */ | 55 | #define DUMP_CONF_EXIT 2 /* c */ |
| 54 | #define D_OPT_IGNORED 4 /* d */ | 56 | #define D_OPT_IGNORED 4 /* d */ |
| @@ -63,14 +65,12 @@ static struct dep_t *depend; | |||
| 63 | #define VERSION_ONLY 2048 /* V */ | 65 | #define VERSION_ONLY 2048 /* V */ |
| 64 | #define CONFIG_FILE 4096 /* C */ | 66 | #define CONFIG_FILE 4096 /* C */ |
| 65 | 67 | ||
| 66 | #define autoclean (main_opts & AUTOCLEAN_FLG) | 68 | #define autoclean (option_mask32 & AUTOCLEAN_FLG) |
| 67 | #define show_only (main_opts & SHOW_ONLY) | 69 | #define show_only (option_mask32 & SHOW_ONLY) |
| 68 | #define quiet (main_opts & QUIET) | 70 | #define quiet (option_mask32 & QUIET) |
| 69 | #define remove_opt (main_opts & REMOVE_OPT) | 71 | #define remove_opt (option_mask32 & REMOVE_OPT) |
| 70 | #define do_syslog (main_opts & DO_SYSLOG) | 72 | #define do_syslog (option_mask32 & DO_SYSLOG) |
| 71 | #define verbose (main_opts & VERBOSE) | 73 | #define verbose (option_mask32 & VERBOSE) |
| 72 | |||
| 73 | static int main_opts; | ||
| 74 | 74 | ||
| 75 | static int parse_tag_value(char *buffer, char **ptag, char **pvalue) | 75 | static int parse_tag_value(char *buffer, char **ptag, char **pvalue) |
| 76 | { | 76 | { |
| @@ -78,12 +78,15 @@ static int parse_tag_value(char *buffer, char **ptag, char **pvalue) | |||
| 78 | 78 | ||
| 79 | buffer = skip_whitespace(buffer); | 79 | buffer = skip_whitespace(buffer); |
| 80 | tag = value = buffer; | 80 | tag = value = buffer; |
| 81 | while (!isspace(*value)) | 81 | while (!isspace(*value)) { |
| 82 | if (!*value) return 0; | 82 | if (!*value) |
| 83 | else value++; | 83 | return 0; |
| 84 | *value++ = 0; | 84 | value++; |
| 85 | } | ||
| 86 | *value++ = '\0'; | ||
| 85 | value = skip_whitespace(value); | 87 | value = skip_whitespace(value); |
| 86 | if (!*value) return 0; | 88 | if (!*value) |
| 89 | return 0; | ||
| 87 | 90 | ||
| 88 | *ptag = tag; | 91 | *ptag = tag; |
| 89 | *pvalue = value; | 92 | *pvalue = value; |
| @@ -102,14 +105,14 @@ static struct mod_opt_t *append_option(struct mod_opt_t *opt_list, char *opt) | |||
| 102 | while (ol->m_next) { | 105 | while (ol->m_next) { |
| 103 | ol = ol->m_next; | 106 | ol = ol->m_next; |
| 104 | } | 107 | } |
| 105 | ol->m_next = xmalloc(sizeof(struct mod_opt_t)); | 108 | ol->m_next = xzalloc(sizeof(struct mod_opt_t)); |
| 106 | ol = ol->m_next; | 109 | ol = ol->m_next; |
| 107 | } else { | 110 | } else { |
| 108 | ol = opt_list = xmalloc(sizeof(struct mod_opt_t)); | 111 | ol = opt_list = xzalloc(sizeof(struct mod_opt_t)); |
| 109 | } | 112 | } |
| 110 | 113 | ||
| 111 | ol->m_opt_val = xstrdup(opt); | 114 | ol->m_opt_val = xstrdup(opt); |
| 112 | ol->m_next = NULL; | 115 | /*ol->m_next = NULL; - done by xzalloc*/ |
| 113 | 116 | ||
| 114 | return opt_list; | 117 | return opt_list; |
| 115 | } | 118 | } |
| @@ -190,7 +193,8 @@ static char *parse_command_string(char *src, char **dst) | |||
| 190 | case '0': | 193 | case '0': |
| 191 | /* We escaped a special character. For now, keep | 194 | /* We escaped a special character. For now, keep |
| 192 | * both the back-slash and the following char. */ | 195 | * both the back-slash and the following char. */ |
| 193 | tmp_str++; src++; | 196 | tmp_str++; |
| 197 | src++; | ||
| 194 | break; | 198 | break; |
| 195 | default: | 199 | default: |
| 196 | /* We escaped a space or a single or double quote, | 200 | /* We escaped a space or a single or double quote, |
| @@ -242,12 +246,12 @@ static void include_conf(struct dep_t **first, struct dep_t **current, char *buf | |||
| 242 | 246 | ||
| 243 | p = strchr(buffer, '#'); | 247 | p = strchr(buffer, '#'); |
| 244 | if (p) | 248 | if (p) |
| 245 | *p = 0; | 249 | *p = '\0'; |
| 246 | 250 | ||
| 247 | l = strlen(buffer); | 251 | l = strlen(buffer); |
| 248 | 252 | ||
| 249 | while (l && isspace(buffer[l-1])) { | 253 | while (l && isspace(buffer[l-1])) { |
| 250 | buffer[l-1] = 0; | 254 | buffer[l-1] = '\0'; |
| 251 | l--; | 255 | l--; |
| 252 | } | 256 | } |
| 253 | 257 | ||
| @@ -256,66 +260,68 @@ static void include_conf(struct dep_t **first, struct dep_t **current, char *buf | |||
| 256 | continue; | 260 | continue; |
| 257 | } | 261 | } |
| 258 | 262 | ||
| 259 | if (!continuation_line) { | 263 | if (continuation_line) |
| 260 | if ((strncmp(buffer, "alias", 5) == 0) && isspace(buffer[5])) { | 264 | continue; |
| 261 | char *alias, *mod; | ||
| 262 | 265 | ||
| 263 | if (parse_tag_value(buffer + 6, &alias, &mod)) { | 266 | if ((strncmp(buffer, "alias", 5) == 0) && isspace(buffer[5])) { |
| 264 | /* handle alias as a module dependent on the aliased module */ | 267 | char *alias, *mod; |
| 265 | if (!*current) { | ||
| 266 | (*first) = (*current) = xzalloc(sizeof(struct dep_t)); | ||
| 267 | } else { | ||
| 268 | (*current)->m_next = xzalloc(sizeof(struct dep_t)); | ||
| 269 | (*current) = (*current)->m_next; | ||
| 270 | } | ||
| 271 | (*current)->m_name = xstrdup(alias); | ||
| 272 | (*current)->m_isalias = 1; | ||
| 273 | 268 | ||
| 274 | if ((strcmp(mod, "off") == 0) || (strcmp(mod, "null") == 0)) { | 269 | if (parse_tag_value(buffer + 6, &alias, &mod)) { |
| 275 | (*current)->m_depcnt = 0; | 270 | /* handle alias as a module dependent on the aliased module */ |
| 276 | (*current)->m_deparr = 0; | 271 | if (!*current) { |
| 277 | } else { | 272 | (*first) = (*current) = xzalloc(sizeof(struct dep_t)); |
| 278 | (*current)->m_depcnt = 1; | 273 | } else { |
| 279 | (*current)->m_deparr = xmalloc(1 * sizeof(char *)); | 274 | (*current)->m_next = xzalloc(sizeof(struct dep_t)); |
| 280 | (*current)->m_deparr[0] = xstrdup(mod); | 275 | (*current) = (*current)->m_next; |
| 281 | } | ||
| 282 | (*current)->m_next = 0; | ||
| 283 | } | 276 | } |
| 284 | } else if ((strncmp(buffer, "options", 7) == 0) && isspace(buffer[7])) { | 277 | (*current)->m_name = xstrdup(alias); |
| 285 | char *mod, *opt; | 278 | (*current)->m_isalias = 1; |
| 286 | |||
| 287 | /* split the line in the module/alias name, and options */ | ||
| 288 | if (parse_tag_value(buffer + 8, &mod, &opt)) { | ||
| 289 | struct dep_t *dt; | ||
| 290 | 279 | ||
| 291 | /* find the corresponding module */ | 280 | if ((strcmp(mod, "off") == 0) || (strcmp(mod, "null") == 0)) { |
| 292 | for (dt = *first; dt; dt = dt->m_next) { | 281 | /*(*current)->m_depcnt = 0; - done by xzalloc */ |
| 293 | if (strcmp(dt->m_name, mod) == 0) | 282 | /*(*current)->m_deparr = 0;*/ |
| 294 | break; | 283 | } else { |
| 295 | } | 284 | (*current)->m_depcnt = 1; |
| 296 | if (dt) { | 285 | (*current)->m_deparr = xmalloc(sizeof(char *)); |
| 297 | if (ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS) { | 286 | (*current)->m_deparr[0] = xstrdup(mod); |
| 298 | char* new_opt = NULL; | ||
| 299 | while ((opt = parse_command_string(opt, &new_opt))) { | ||
| 300 | dt->m_options = append_option(dt->m_options, new_opt); | ||
| 301 | } | ||
| 302 | } else { | ||
| 303 | dt->m_options = append_option(dt->m_options, opt); | ||
| 304 | } | ||
| 305 | } | ||
| 306 | } | 287 | } |
| 307 | } else if ((strncmp(buffer, "include", 7) == 0) && isspace(buffer[7])) { | 288 | /*(*current)->m_next = NULL; - done by xzalloc */ |
| 308 | int fdi; char *filename; | 289 | } |
| 290 | } else if ((strncmp(buffer, "options", 7) == 0) && isspace(buffer[7])) { | ||
| 291 | char *mod, *opt; | ||
| 309 | 292 | ||
| 310 | filename = skip_whitespace(buffer + 8); | 293 | /* split the line in the module/alias name, and options */ |
| 294 | if (parse_tag_value(buffer + 8, &mod, &opt)) { | ||
| 295 | struct dep_t *dt; | ||
| 311 | 296 | ||
| 312 | if ((fdi = open(filename, O_RDONLY)) >= 0) { | 297 | /* find the corresponding module */ |
| 313 | include_conf(first, current, buffer, buflen, fdi); | 298 | for (dt = *first; dt; dt = dt->m_next) { |
| 314 | close(fdi); | 299 | if (strcmp(dt->m_name, mod) == 0) |
| 300 | break; | ||
| 315 | } | 301 | } |
| 302 | if (dt) { | ||
| 303 | if (ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS) { | ||
| 304 | char* new_opt = NULL; | ||
| 305 | while ((opt = parse_command_string(opt, &new_opt))) { | ||
| 306 | dt->m_options = append_option(dt->m_options, new_opt); | ||
| 307 | } | ||
| 308 | } else { | ||
| 309 | dt->m_options = append_option(dt->m_options, opt); | ||
| 310 | } | ||
| 311 | } | ||
| 312 | } | ||
| 313 | } else if ((strncmp(buffer, "include", 7) == 0) && isspace(buffer[7])) { | ||
| 314 | int fdi; | ||
| 315 | char *filename; | ||
| 316 | |||
| 317 | filename = skip_whitespace(buffer + 8); | ||
| 318 | fdi = open(filename, O_RDONLY); | ||
| 319 | if (fdi >= 0) { | ||
| 320 | include_conf(first, current, buffer, buflen, fdi); | ||
| 321 | close(fdi); | ||
| 316 | } | 322 | } |
| 317 | } | 323 | } |
| 318 | } | 324 | } /* while (reads(...)) */ |
| 319 | } | 325 | } |
| 320 | 326 | ||
| 321 | /* | 327 | /* |
| @@ -327,9 +333,8 @@ static struct dep_t *build_dep(void) | |||
| 327 | { | 333 | { |
| 328 | int fd; | 334 | int fd; |
| 329 | struct utsname un; | 335 | struct utsname un; |
| 330 | struct dep_t *first = 0; | 336 | struct dep_t *first = NULL; |
| 331 | struct dep_t *current = 0; | 337 | struct dep_t *current = NULL; |
| 332 | char buffer[2048]; | ||
| 333 | char *filename; | 338 | char *filename; |
| 334 | int continuation_line = 0; | 339 | int continuation_line = 0; |
| 335 | int k_version; | 340 | int k_version; |
| @@ -350,16 +355,16 @@ static struct dep_t *build_dep(void) | |||
| 350 | /* Ok, that didn't work. Fall back to looking in /lib/modules */ | 355 | /* Ok, that didn't work. Fall back to looking in /lib/modules */ |
| 351 | fd = open("/lib/modules/modules.dep", O_RDONLY); | 356 | fd = open("/lib/modules/modules.dep", O_RDONLY); |
| 352 | if (fd < 0) { | 357 | if (fd < 0) { |
| 353 | return 0; | 358 | bb_error_msg_and_die("cannot parse modules.dep"); |
| 354 | } | 359 | } |
| 355 | } | 360 | } |
| 356 | 361 | ||
| 357 | while (reads(fd, buffer, sizeof(buffer))) { | 362 | while (reads(fd, line_buffer, sizeof(line_buffer))) { |
| 358 | int l = strlen(buffer); | 363 | int l = strlen(line_buffer); |
| 359 | char *p = 0; | 364 | char *p = 0; |
| 360 | 365 | ||
| 361 | while (l > 0 && isspace(buffer[l-1])) { | 366 | while (l > 0 && isspace(line_buffer[l-1])) { |
| 362 | buffer[l-1] = 0; | 367 | line_buffer[l-1] = '\0'; |
| 363 | l--; | 368 | l--; |
| 364 | } | 369 | } |
| 365 | 370 | ||
| @@ -371,7 +376,7 @@ static struct dep_t *build_dep(void) | |||
| 371 | /* Is this a new module dep description? */ | 376 | /* Is this a new module dep description? */ |
| 372 | if (!continuation_line) { | 377 | if (!continuation_line) { |
| 373 | /* find the dep beginning */ | 378 | /* find the dep beginning */ |
| 374 | char *col = strchr(buffer, ':'); | 379 | char *col = strchr(line_buffer, ':'); |
| 375 | char *dot = col; | 380 | char *dot = col; |
| 376 | 381 | ||
| 377 | if (col) { | 382 | if (col) { |
| @@ -381,53 +386,52 @@ static struct dep_t *build_dep(void) | |||
| 381 | char *mod; | 386 | char *mod; |
| 382 | 387 | ||
| 383 | /* Find the beginning of the module file name */ | 388 | /* Find the beginning of the module file name */ |
| 384 | *col = 0; | 389 | *col = '\0'; |
| 385 | mods = bb_basename(buffer); | 390 | mods = bb_basename(line_buffer); |
| 386 | 391 | ||
| 387 | /* find the path of the module */ | 392 | /* find the path of the module */ |
| 388 | modpath = strchr(buffer, '/'); /* ... and this is the path */ | 393 | modpath = strchr(line_buffer, '/'); /* ... and this is the path */ |
| 389 | if (!modpath) | 394 | if (!modpath) |
| 390 | modpath = buffer; /* module with no path */ | 395 | modpath = line_buffer; /* module with no path */ |
| 391 | /* find the end of the module name in the file name */ | 396 | /* find the end of the module name in the file name */ |
| 392 | if (ENABLE_FEATURE_2_6_MODULES && | 397 | if (ENABLE_FEATURE_2_6_MODULES && |
| 393 | (k_version > 4) && (*(col-3) == '.') && | 398 | (k_version > 4) && (col[-3] == '.') && |
| 394 | (*(col-2) == 'k') && (*(col-1) == 'o')) | 399 | (col[-2] == 'k') && (col[-1] == 'o')) |
| 395 | dot = col - 3; | 400 | dot = col - 3; |
| 396 | else | 401 | else if ((col[-2] == '.') && (col[-1] == 'o')) |
| 397 | if ((*(col-2) == '.') && (*(col-1) == 'o')) | 402 | dot = col - 2; |
| 398 | dot = col - 2; | ||
| 399 | 403 | ||
| 400 | mod = xstrndup(mods, dot - mods); | 404 | mod = xstrndup(mods, dot - mods); |
| 401 | 405 | ||
| 402 | /* enqueue new module */ | 406 | /* enqueue new module */ |
| 403 | if (!current) { | 407 | if (!current) { |
| 404 | first = current = xmalloc(sizeof(struct dep_t)); | 408 | first = current = xzalloc(sizeof(struct dep_t)); |
| 405 | } else { | 409 | } else { |
| 406 | current->m_next = xmalloc(sizeof(struct dep_t)); | 410 | current->m_next = xzalloc(sizeof(struct dep_t)); |
| 407 | current = current->m_next; | 411 | current = current->m_next; |
| 408 | } | 412 | } |
| 409 | current->m_name = mod; | 413 | current->m_name = mod; |
| 410 | current->m_path = xstrdup(modpath); | 414 | current->m_path = xstrdup(modpath); |
| 411 | current->m_options = NULL; | 415 | /*current->m_options = NULL; - xzalloc did it*/ |
| 412 | current->m_isalias = 0; | 416 | /*current->m_isalias = 0;*/ |
| 413 | current->m_depcnt = 0; | 417 | /*current->m_depcnt = 0;*/ |
| 414 | current->m_deparr = 0; | 418 | /*current->m_deparr = 0;*/ |
| 415 | current->m_next = 0; | 419 | /*current->m_next = 0;*/ |
| 416 | 420 | ||
| 417 | p = col + 1; | 421 | p = col + 1; |
| 418 | } else | 422 | } else |
| 419 | /* this line is not a dep description */ | 423 | /* this line is not a dep description */ |
| 420 | p = 0; | 424 | p = NULL; |
| 421 | } else | 425 | } else |
| 422 | /* It's a dep description continuation */ | 426 | /* It's a dep description continuation */ |
| 423 | p = buffer; | 427 | p = line_buffer; |
| 424 | 428 | ||
| 425 | while (p && *p && isblank(*p)) | 429 | while (p && *p && isblank(*p)) |
| 426 | p++; | 430 | p++; |
| 427 | 431 | ||
| 428 | /* p points to the first dependable module; if NULL, no dependable module */ | 432 | /* p points to the first dependable module; if NULL, no dependable module */ |
| 429 | if (p && *p) { | 433 | if (p && *p) { |
| 430 | char *end = &buffer[l-1]; | 434 | char *end = &line_buffer[l-1]; |
| 431 | const char *deps; | 435 | const char *deps; |
| 432 | char *dep; | 436 | char *dep; |
| 433 | char *next; | 437 | char *next; |
| @@ -440,7 +444,7 @@ static struct dep_t *build_dep(void) | |||
| 440 | /* search the end of the dependency */ | 444 | /* search the end of the dependency */ |
| 441 | next = strchr(p, ' '); | 445 | next = strchr(p, ' '); |
| 442 | if (next) { | 446 | if (next) { |
| 443 | *next = 0; | 447 | *next = '\0'; |
| 444 | next--; | 448 | next--; |
| 445 | } else | 449 | } else |
| 446 | next = end; | 450 | next = end; |
| @@ -454,12 +458,11 @@ static struct dep_t *build_dep(void) | |||
| 454 | 458 | ||
| 455 | /* find the end of the module name in the file name */ | 459 | /* find the end of the module name in the file name */ |
| 456 | if (ENABLE_FEATURE_2_6_MODULES | 460 | if (ENABLE_FEATURE_2_6_MODULES |
| 457 | && (k_version > 4) && (*(next-2) == '.') | 461 | && (k_version > 4) && (next[-2] == '.') |
| 458 | && (*(next-1) == 'k') && (*next == 'o')) | 462 | && (next[-1] == 'k') && (next[0] == 'o')) |
| 459 | ext = 3; | 463 | ext = 3; |
| 460 | else | 464 | else if ((next[-1] == '.') && (next[0] == 'o')) |
| 461 | if ((*(next-1) == '.') && (*next == 'o')) | 465 | ext = 2; |
| 462 | ext = 2; | ||
| 463 | 466 | ||
| 464 | /* Cope with blank lines */ | 467 | /* Cope with blank lines */ |
| 465 | if ((next-deps-ext+1) <= 0) | 468 | if ((next-deps-ext+1) <= 0) |
| @@ -477,11 +480,8 @@ static struct dep_t *build_dep(void) | |||
| 477 | } | 480 | } |
| 478 | 481 | ||
| 479 | /* is there other dependable module(s) ? */ | 482 | /* is there other dependable module(s) ? */ |
| 480 | if (buffer[l-1] == '\\') | 483 | continuation_line = (line_buffer[l-1] == '\\'); |
| 481 | continuation_line = 1; | 484 | } /* while (reads(...)) */ |
| 482 | else | ||
| 483 | continuation_line = 0; | ||
| 484 | } | ||
| 485 | close(fd); | 485 | close(fd); |
| 486 | 486 | ||
| 487 | /* | 487 | /* |
| @@ -498,7 +498,7 @@ static struct dep_t *build_dep(void) | |||
| 498 | fd = open("/etc/conf.modules", O_RDONLY); | 498 | fd = open("/etc/conf.modules", O_RDONLY); |
| 499 | 499 | ||
| 500 | if (fd >= 0) { | 500 | if (fd >= 0) { |
| 501 | include_conf(&first, ¤t, buffer, sizeof(buffer), fd); | 501 | include_conf(&first, ¤t, line_buffer, sizeof(line_buffer), fd); |
| 502 | close(fd); | 502 | close(fd); |
| 503 | } | 503 | } |
| 504 | 504 | ||
| @@ -515,7 +515,7 @@ static struct dep_t *build_dep(void) | |||
| 515 | free(filename); | 515 | free(filename); |
| 516 | 516 | ||
| 517 | if (fd >= 0) { | 517 | if (fd >= 0) { |
| 518 | include_conf(&first, ¤t, buffer, sizeof(buffer), fd); | 518 | include_conf(&first, ¤t, line_buffer, sizeof(line_buffer), fd); |
| 519 | close(fd); | 519 | close(fd); |
| 520 | } | 520 | } |
| 521 | 521 | ||
| @@ -530,7 +530,7 @@ static struct dep_t *build_dep(void) | |||
| 530 | free(filename); | 530 | free(filename); |
| 531 | 531 | ||
| 532 | if (fd >= 0) { | 532 | if (fd >= 0) { |
| 533 | include_conf(&first, ¤t, buffer, sizeof(buffer), fd); | 533 | include_conf(&first, ¤t, line_buffer, sizeof(line_buffer), fd); |
| 534 | close(fd); | 534 | close(fd); |
| 535 | } | 535 | } |
| 536 | } | 536 | } |
| @@ -542,16 +542,15 @@ static struct dep_t *build_dep(void) | |||
| 542 | static int already_loaded(const char *name) | 542 | static int already_loaded(const char *name) |
| 543 | { | 543 | { |
| 544 | int fd, ret = 0; | 544 | int fd, ret = 0; |
| 545 | char buffer[4096]; | ||
| 546 | 545 | ||
| 547 | fd = open("/proc/modules", O_RDONLY); | 546 | fd = open("/proc/modules", O_RDONLY); |
| 548 | if (fd < 0) | 547 | if (fd < 0) |
| 549 | return -1; | 548 | return -1; |
| 550 | 549 | ||
| 551 | while (reads(fd, buffer, sizeof(buffer))) { | 550 | while (reads(fd, line_buffer, sizeof(line_buffer))) { |
| 552 | char *p; | 551 | char *p; |
| 553 | 552 | ||
| 554 | p = strchr (buffer, ' '); | 553 | p = strchr(line_buffer, ' '); |
| 555 | if (p) { | 554 | if (p) { |
| 556 | const char *n; | 555 | const char *n; |
| 557 | 556 | ||
| @@ -559,8 +558,8 @@ static int already_loaded(const char *name) | |||
| 559 | // the idiosyncrasy that _ and - are interchangeable because the | 558 | // the idiosyncrasy that _ and - are interchangeable because the |
| 560 | // 2.6 kernel does weird things. | 559 | // 2.6 kernel does weird things. |
| 561 | 560 | ||
| 562 | *p = 0; | 561 | *p = '\0'; |
| 563 | for (p = buffer, n = name; ; p++, n++) { | 562 | for (p = line_buffer, n = name; ; p++, n++) { |
| 564 | if (*p != *n) { | 563 | if (*p != *n) { |
| 565 | if ((*p == '_' || *p == '-') && (*n == '_' || *n == '-')) | 564 | if ((*p == '_' || *p == '-') && (*n == '_' || *n == '-')) |
| 566 | continue; | 565 | continue; |
| @@ -574,8 +573,8 @@ static int already_loaded(const char *name) | |||
| 574 | } | 573 | } |
| 575 | } | 574 | } |
| 576 | } | 575 | } |
| 577 | done: | 576 | done: |
| 578 | close (fd); | 577 | close(fd); |
| 579 | return ret; | 578 | return ret; |
| 580 | } | 579 | } |
| 581 | 580 | ||
| @@ -623,7 +622,7 @@ static int mod_process(const struct mod_list_t *list, int do_insert) | |||
| 623 | while (opts) { | 622 | while (opts) { |
| 624 | /* Add one more option */ | 623 | /* Add one more option */ |
| 625 | argc++; | 624 | argc++; |
| 626 | argv = xrealloc(argv,(argc + 1)* sizeof(char*)); | 625 | argv = xrealloc(argv, (argc + 1) * sizeof(char*)); |
| 627 | argv[argc-1] = opts->m_opt_val; | 626 | argv[argc-1] = opts->m_opt_val; |
| 628 | opts = opts->m_next; | 627 | opts = opts->m_next; |
| 629 | } | 628 | } |
| @@ -698,9 +697,8 @@ static int check_pattern(const char* pat_src, const char* mod_src) | |||
| 698 | } | 697 | } |
| 699 | 698 | ||
| 700 | return ret; | 699 | return ret; |
| 701 | } else { | ||
| 702 | return fnmatch(pat_src, mod_src, 0); | ||
| 703 | } | 700 | } |
| 701 | return fnmatch(pat_src, mod_src, 0); | ||
| 704 | } | 702 | } |
| 705 | 703 | ||
| 706 | /* | 704 | /* |
| @@ -712,8 +710,8 @@ static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **t | |||
| 712 | { | 710 | { |
| 713 | struct mod_list_t *find; | 711 | struct mod_list_t *find; |
| 714 | struct dep_t *dt; | 712 | struct dep_t *dt; |
| 715 | struct mod_opt_t *opt = 0; | 713 | struct mod_opt_t *opt = NULL; |
| 716 | char *path = 0; | 714 | char *path = NULL; |
| 717 | 715 | ||
| 718 | /* Search for the given module name amongst all dependency rules. | 716 | /* Search for the given module name amongst all dependency rules. |
| 719 | * The module name in a dependency rule can be a shell pattern, | 717 | * The module name in a dependency rule can be a shell pattern, |
| @@ -765,8 +763,8 @@ static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **t | |||
| 765 | 763 | ||
| 766 | // search for duplicates | 764 | // search for duplicates |
| 767 | for (find = *head; find; find = find->m_next) { | 765 | for (find = *head; find; find = find->m_next) { |
| 768 | if (!strcmp(mod, find->m_name)) { | 766 | if (strcmp(mod, find->m_name) == 0) { |
| 769 | // found ->dequeue it | 767 | // found -> dequeue it |
| 770 | 768 | ||
| 771 | if (find->m_prev) | 769 | if (find->m_prev) |
| 772 | find->m_prev->m_next = find->m_next; | 770 | find->m_prev->m_next = find->m_next; |
| @@ -783,7 +781,7 @@ static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **t | |||
| 783 | } | 781 | } |
| 784 | 782 | ||
| 785 | if (!find) { // did not find a duplicate | 783 | if (!find) { // did not find a duplicate |
| 786 | find = xmalloc(sizeof(struct mod_list_t)); | 784 | find = xzalloc(sizeof(struct mod_list_t)); |
| 787 | find->m_name = mod; | 785 | find->m_name = mod; |
| 788 | find->m_path = path; | 786 | find->m_path = path; |
| 789 | find->m_options = opt; | 787 | find->m_options = opt; |
| @@ -793,7 +791,7 @@ static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **t | |||
| 793 | if (*tail) | 791 | if (*tail) |
| 794 | (*tail)->m_next = find; | 792 | (*tail)->m_next = find; |
| 795 | find->m_prev = *tail; | 793 | find->m_prev = *tail; |
| 796 | find->m_next = 0; | 794 | /*find->m_next = NULL; - xzalloc did it */ |
| 797 | 795 | ||
| 798 | if (!*head) | 796 | if (!*head) |
| 799 | *head = find; | 797 | *head = find; |
| @@ -868,11 +866,11 @@ int modprobe_main(int argc, char **argv) | |||
| 868 | char *unused; | 866 | char *unused; |
| 869 | 867 | ||
| 870 | opt_complementary = "?V-:q-v:v-q"; | 868 | opt_complementary = "?V-:q-v:v-q"; |
| 871 | main_opts = getopt32(argv, "acdklnqrst:vVC:", | 869 | getopt32(argv, MAIN_OPT_STR, &unused, &unused); |
| 872 | &unused, &unused); | 870 | |
| 873 | if (main_opts & (DUMP_CONF_EXIT | LIST_ALL)) | 871 | if (option_mask32 & (DUMP_CONF_EXIT | LIST_ALL)) |
| 874 | return EXIT_SUCCESS; | 872 | return EXIT_SUCCESS; |
| 875 | if (main_opts & (RESTRICT_DIR | CONFIG_FILE)) | 873 | if (option_mask32 & (RESTRICT_DIR | CONFIG_FILE)) |
| 876 | bb_error_msg_and_die("-t and -C not supported"); | 874 | bb_error_msg_and_die("-t and -C not supported"); |
| 877 | 875 | ||
| 878 | depend = build_dep(); | 876 | depend = build_dep(); |
| @@ -882,8 +880,8 @@ int modprobe_main(int argc, char **argv) | |||
| 882 | 880 | ||
| 883 | if (remove_opt) { | 881 | if (remove_opt) { |
| 884 | do { | 882 | do { |
| 885 | if (mod_remove(optind < argc ? | 883 | /* argv[optind] can be NULL here */ |
| 886 | argv[optind] : NULL)) { | 884 | if (mod_remove(argv[optind])) { |
| 887 | bb_error_msg("failed to remove module %s", | 885 | bb_error_msg("failed to remove module %s", |
| 888 | argv[optind]); | 886 | argv[optind]); |
| 889 | rc = EXIT_FAILURE; | 887 | rc = EXIT_FAILURE; |
