Changeset 1770 in MondoRescue for branches/stable/mindi-busybox/modutils/insmod.c
- Timestamp:
- Nov 6, 2007, 11:01:53 AM (16 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/stable/mindi-busybox/modutils/insmod.c
r821 r1770 41 41 * written by Paul Mackerras, Copyright 1996, 1997 Linux International. 42 42 * I've only tested the code on mpc8xx platforms in big-endian mode. 43 * Did some cleanup and added CONFIG_USE_xxx_ENTRIES...43 * Did some cleanup and added USE_xxx_ENTRIES... 44 44 * 45 45 * Quinn Jensen <jensenq@lineo.com> added MIPS support 23-Feb-2001. … … 59 59 */ 60 60 61 #include "busybox.h" 62 #include <stdlib.h> 63 #include <stdio.h> 64 #include <stddef.h> 65 #include <errno.h> 66 #include <unistd.h> 67 #include <dirent.h> 68 #include <ctype.h> 69 #include <assert.h> 70 #include <string.h> 71 #include <getopt.h> 72 #include <fcntl.h> 61 #include "libbb.h" 62 #include <libgen.h> 73 63 #include <sys/utsname.h> 74 64 75 #if ! defined(CONFIG_FEATURE_2_4_MODULES) && \76 !defined(CONFIG_FEATURE_2_6_MODULES) 77 #define CONFIG_FEATURE_2_4_MODULES78 #endif 79 80 #if ! defined(CONFIG_FEATURE_2_4_MODULES)65 #if !ENABLE_FEATURE_2_4_MODULES && !ENABLE_FEATURE_2_6_MODULES 66 #undef ENABLE_FEATURE_2_4_MODULES 67 #define ENABLE_FEATURE_2_4_MODULES 1 68 #endif 69 70 #if !ENABLE_FEATURE_2_4_MODULES 81 71 #define insmod_ng_main insmod_main 82 72 #endif 83 73 84 #if defined(CONFIG_FEATURE_2_6_MODULES)74 #if ENABLE_FEATURE_2_6_MODULES 85 75 extern int insmod_ng_main( int argc, char **argv); 86 76 #endif 87 77 88 78 89 #if defined(CONFIG_FEATURE_2_4_MODULES)90 91 92 #if def CONFIG_FEATURE_INSMOD_LOADINKMEM79 #if ENABLE_FEATURE_2_4_MODULES 80 81 82 #if ENABLE_FEATURE_INSMOD_LOADINKMEM 93 83 #define LOADBITS 0 94 84 #else … … 111 101 #define Elf32_RelM Elf32_Rel 112 102 #define ELFCLASSM ELFCLASS32 113 #define CONFIG_USE_PLT_ENTRIES114 #define CONFIG_PLT_ENTRY_SIZE 8115 #define CONFIG_USE_GOT_ENTRIES116 #define CONFIG_GOT_ENTRY_SIZE 8117 #define CONFIG_USE_SINGLE103 #define USE_PLT_ENTRIES 104 #define PLT_ENTRY_SIZE 8 105 #define USE_GOT_ENTRIES 106 #define GOT_ENTRY_SIZE 8 107 #define USE_SINGLE 118 108 #endif 119 109 … … 145 135 #define Elf32_RelM Elf32_Rela 146 136 #define ELFCLASSM ELFCLASS32 147 #define CONFIG_USE_SINGLE137 #define USE_SINGLE 148 138 #define SYMBOL_PREFIX "_" 149 139 #endif … … 172 162 #define Elf32_RelM Elf32_Rel 173 163 #define ELFCLASSM ELFCLASS32 174 #define CONFIG_USE_GOT_ENTRIES175 #define CONFIG_GOT_ENTRY_SIZE 4176 #define CONFIG_USE_SINGLE164 #define USE_GOT_ENTRIES 165 #define GOT_ENTRY_SIZE 4 166 #define USE_SINGLE 177 167 #endif 178 168 … … 191 181 #define Elf32_RelM Elf32_Rela 192 182 #define ELFCLASSM ELFCLASS32 193 #define CONFIG_USE_GOT_ENTRIES194 #define CONFIG_GOT_ENTRY_SIZE 4195 #define CONFIG_USE_SINGLE183 #define USE_GOT_ENTRIES 184 #define GOT_ENTRY_SIZE 4 185 #define USE_SINGLE 196 186 #endif 197 187 198 188 /* Microblaze */ 199 189 #if defined(__microblaze__) 200 #define CONFIG_USE_SINGLE190 #define USE_SINGLE 201 191 #define MATCH_MACHINE(x) (x == EM_XILINX_MICROBLAZE) 202 192 #define SHT_RELM SHT_RELA … … 241 231 #define Elf32_RelM Elf32_Rela 242 232 #define ELFCLASSM ELFCLASS32 243 #define CONFIG_USE_PLT_ENTRIES244 #define CONFIG_PLT_ENTRY_SIZE 16245 #define CONFIG_USE_PLT_LIST246 #define CONFIG_LIST_ARCHTYPE ElfW(Addr)247 #define CONFIG_USE_LIST233 #define USE_PLT_ENTRIES 234 #define PLT_ENTRY_SIZE 16 235 #define USE_PLT_LIST 236 #define LIST_ARCHTYPE ElfW(Addr) 237 #define USE_LIST 248 238 #define ARCHDATAM "__ftr_fixup" 249 239 #endif … … 255 245 #define Elf32_RelM Elf32_Rela 256 246 #define ELFCLASSM ELFCLASS32 257 #define CONFIG_USE_PLT_ENTRIES258 #define CONFIG_PLT_ENTRY_SIZE 8259 #define CONFIG_USE_GOT_ENTRIES260 #define CONFIG_GOT_ENTRY_SIZE 8261 #define CONFIG_USE_SINGLE247 #define USE_PLT_ENTRIES 248 #define PLT_ENTRY_SIZE 8 249 #define USE_GOT_ENTRIES 250 #define GOT_ENTRY_SIZE 8 251 #define USE_SINGLE 262 252 #endif 263 253 … … 268 258 #define Elf32_RelM Elf32_Rela 269 259 #define ELFCLASSM ELFCLASS32 270 #define CONFIG_USE_GOT_ENTRIES271 #define CONFIG_GOT_ENTRY_SIZE 4272 #define CONFIG_USE_SINGLE260 #define USE_GOT_ENTRIES 261 #define GOT_ENTRY_SIZE 4 262 #define USE_SINGLE 273 263 /* the SH changes have only been tested in =little endian= mode */ 274 264 /* I'm not sure about big endian, so let's warn: */ … … 291 281 292 282 /* v850e */ 293 #if defined 283 #if defined(__v850e__) 294 284 #define MATCH_MACHINE(x) ((x) == EM_V850 || (x) == EM_CYGNUS_V850) 295 285 #define SHT_RELM SHT_RELA 296 286 #define Elf32_RelM Elf32_Rela 297 287 #define ELFCLASSM ELFCLASS32 298 #define CONFIG_USE_PLT_ENTRIES299 #define CONFIG_PLT_ENTRY_SIZE 8300 #define CONFIG_USE_SINGLE288 #define USE_PLT_ENTRIES 289 #define PLT_ENTRY_SIZE 8 290 #define USE_SINGLE 301 291 #ifndef EM_CYGNUS_V850 /* grumble */ 302 292 #define EM_CYGNUS_V850 0x9080 … … 309 299 #define MATCH_MACHINE(x) (x == EM_X86_64) 310 300 #define SHT_RELM SHT_RELA 311 #define CONFIG_USE_GOT_ENTRIES312 #define CONFIG_GOT_ENTRY_SIZE 8313 #define CONFIG_USE_SINGLE301 #define USE_GOT_ENTRIES 302 #define GOT_ENTRY_SIZE 8 303 #define USE_SINGLE 314 304 #define Elf64_RelM Elf64_Rela 315 305 #define ELFCLASSM ELFCLASS64 … … 348 338 349 339 #ifndef MODUTILS_MODULE_H 350 /* Why? static const int MODUTILS_MODULE_H = 1;*/351 352 #ident "$Id: insmod.c,v 1.126 2004/12/26 09:13:32 vapier Exp $"353 340 354 341 /*======================================================================*/ … … 381 368 382 369 /* Note: new_module_symbol does not use tgt_long intentionally */ 383 struct new_module_symbol 384 { 370 struct new_module_symbol { 385 371 unsigned long value; 386 372 unsigned long name; … … 389 375 struct new_module_persist; 390 376 391 struct new_module_ref 392 { 377 struct new_module_ref { 393 378 unsigned tgt_long dep; /* kernel addresses */ 394 379 unsigned tgt_long ref; … … 396 381 }; 397 382 398 struct new_module 399 { 383 struct new_module { 400 384 unsigned tgt_long size_of_struct; /* == sizeof(module) */ 401 385 unsigned tgt_long next; … … 439 423 440 424 441 struct new_module_info 442 { 425 struct new_module_info { 443 426 unsigned long addr; 444 427 unsigned long size; … … 511 494 512 495 #ifndef MODUTILS_OBJ_H 513 /* Why? static const int MODUTILS_OBJ_H = 1; */514 515 #ident "$Id: insmod.c,v 1.126 2004/12/26 09:13:32 vapier Exp $"516 496 517 497 /* The relocatable object is manipulated using elfin types. */ 518 498 519 #include <stdio.h>520 499 #include <elf.h> 521 500 #include <endian.h> … … 576 555 #define HASH_BUCKETS 521 577 556 578 struct obj_file 579 { 557 struct obj_file { 580 558 ElfW(Ehdr) header; 581 559 ElfW(Addr) baseaddr; … … 592 570 }; 593 571 594 enum obj_reloc 595 { 572 enum obj_reloc { 596 573 obj_reloc_ok, 597 574 obj_reloc_overflow, … … 600 577 }; 601 578 602 struct obj_string_patch 603 { 579 struct obj_string_patch { 604 580 struct obj_string_patch *next; 605 581 int reloc_secidx; … … 608 584 }; 609 585 610 struct obj_symbol_patch 611 { 586 struct obj_symbol_patch { 612 587 struct obj_symbol_patch *next; 613 588 int reloc_secidx; … … 623 598 static unsigned long obj_elf_hash_n(const char *, unsigned long len); 624 599 625 static struct obj_symbol *obj_find_symbol 600 static struct obj_symbol *obj_find_symbol(struct obj_file *f, 626 601 const char *name); 627 602 … … 629 604 struct obj_symbol *sym); 630 605 631 #if def CONFIG_FEATURE_INSMOD_VERSION_CHECKING606 #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 632 607 static void obj_set_symbol_compare(struct obj_file *f, 633 608 int (*cmp)(const char *, const char *), … … 635 610 #endif 636 611 637 static struct obj_section *obj_find_section 612 static struct obj_section *obj_find_section(struct obj_file *f, 638 613 const char *name); 639 614 640 static void obj_insert_section_load_order 615 static void obj_insert_section_load_order(struct obj_file *f, 641 616 struct obj_section *sec); 642 617 643 static struct obj_section *obj_create_alloced_section 618 static struct obj_section *obj_create_alloced_section(struct obj_file *f, 644 619 const char *name, 645 620 unsigned long align, 646 621 unsigned long size); 647 622 648 static struct obj_section *obj_create_alloced_section_first 623 static struct obj_section *obj_create_alloced_section_first(struct obj_file *f, 649 624 const char *name, 650 625 unsigned long align, 651 626 unsigned long size); 652 627 653 static void *obj_extend_section 628 static void *obj_extend_section(struct obj_section *sec, unsigned long more); 654 629 655 630 static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, … … 663 638 static void obj_allocate_commons(struct obj_file *f); 664 639 665 static unsigned long obj_load_size 666 667 static int obj_relocate 640 static unsigned long obj_load_size(struct obj_file *f); 641 642 static int obj_relocate(struct obj_file *f, ElfW(Addr) base); 668 643 669 644 static struct obj_file *obj_load(FILE *f, int loadprogbits); 670 645 671 static int obj_create_image 646 static int obj_create_image(struct obj_file *f, char *image); 672 647 673 648 /* Architecture specific manipulation routines. */ 674 649 675 static struct obj_file *arch_new_file 676 677 static struct obj_section *arch_new_section 678 679 static struct obj_symbol *arch_new_symbol 680 681 static enum obj_reloc arch_apply_relocation 650 static struct obj_file *arch_new_file(void); 651 652 static struct obj_section *arch_new_section(void); 653 654 static struct obj_symbol *arch_new_symbol(void); 655 656 static enum obj_reloc arch_apply_relocation(struct obj_file *f, 682 657 struct obj_section *targsec, 683 658 struct obj_section *symsec, … … 685 660 ElfW(RelM) *rel, ElfW(Addr) value); 686 661 687 static void arch_create_got 662 static void arch_create_got(struct obj_file *f); 688 663 #if ENABLE_FEATURE_CHECK_TAINTED_MODULE 689 664 static int obj_gpl_license(struct obj_file *f, const char **license); 690 #endif /* ENABLE_FEATURE_CHECK_TAINTED_MODULE */665 #endif /* FEATURE_CHECK_TAINTED_MODULE */ 691 666 #endif /* obj.h */ 692 667 //---------------------------------------------------------------------------- … … 704 679 705 680 #define _PATH_MODULES "/lib/modules" 706 enum { STRVERSIONLEN = 32};681 enum { STRVERSIONLEN = 64 }; 707 682 708 683 /*======================================================================*/ 709 684 710 static int flag_force_load = 0; 711 static int flag_autoclean = 0; 712 static int flag_verbose = 0; 713 static int flag_quiet = 0; 714 static int flag_export = 1; 715 685 #define OPTION_STR "sLo:fkvqx" USE_FEATURE_INSMOD_LOAD_MAP("m") 686 enum { 687 OPT_s = 0x1, // -s /* log to syslog */ 688 /* Not supported but kernel needs this for request_module(), 689 as this calls: modprobe -k -s -- <module> 690 so silently ignore this flag */ 691 OPT_L = 0x2, // -L /* Stub warning */ 692 /* Compatibility with modprobe. 693 In theory, this does locking, but we don't do 694 that. So be careful and plan your life around not 695 loading the same module 50 times concurrently. */ 696 OPT_o = 0x4, // -o /* name the output module */ 697 OPT_f = 0x8, // -f /* force loading */ 698 OPT_k = 0x10, // -k /* module loaded by kerneld, auto-cleanable */ 699 OPT_v = 0x20, // -v /* verbose output */ 700 OPT_q = 0x40, // -q /* silent */ 701 OPT_x = 0x80, // -x /* do not export externs */ 702 OPT_m = 0x100, // -m /* print module load map */ 703 }; 704 #define flag_force_load (option_mask32 & OPT_f) 705 #define flag_autoclean (option_mask32 & OPT_k) 706 #define flag_verbose (option_mask32 & OPT_v) 707 #define flag_quiet (option_mask32 & OPT_q) 708 #define flag_noexport (option_mask32 & OPT_x) 709 #if ENABLE_FEATURE_INSMOD_LOAD_MAP 710 #define flag_print_load_map (option_mask32 & OPT_m) 711 #else 712 #define flag_print_load_map 0 713 #endif 716 714 717 715 /*======================================================================*/ 718 716 719 #if defined( CONFIG_USE_LIST)717 #if defined(USE_LIST) 720 718 721 719 struct arch_list_entry 722 720 { 723 721 struct arch_list_entry *next; 724 CONFIG_LIST_ARCHTYPE addend;722 LIST_ARCHTYPE addend; 725 723 int offset; 726 724 int inited : 1; … … 729 727 #endif 730 728 731 #if defined( CONFIG_USE_SINGLE)729 #if defined(USE_SINGLE) 732 730 733 731 struct arch_single_entry … … 751 749 struct arch_file { 752 750 struct obj_file root; 753 #if defined( CONFIG_USE_PLT_ENTRIES)751 #if defined(USE_PLT_ENTRIES) 754 752 struct obj_section *plt; 755 753 #endif 756 #if defined( CONFIG_USE_GOT_ENTRIES)754 #if defined(USE_GOT_ENTRIES) 757 755 struct obj_section *got; 758 756 #endif … … 764 762 struct arch_symbol { 765 763 struct obj_symbol root; 766 #if defined( CONFIG_USE_PLT_ENTRIES)767 #if defined( CONFIG_USE_PLT_LIST)764 #if defined(USE_PLT_ENTRIES) 765 #if defined(USE_PLT_LIST) 768 766 struct arch_list_entry *pltent; 769 767 #else … … 771 769 #endif 772 770 #endif 773 #if defined( CONFIG_USE_GOT_ENTRIES)771 #if defined(USE_GOT_ENTRIES) 774 772 struct arch_single_entry gotent; 775 773 #endif … … 797 795 798 796 799 800 797 /*======================================================================*/ 801 798 802 799 803 800 static int check_module_name_match(const char *filename, struct stat *statbuf, 804 void *userdata)801 void *userdata, int depth) 805 802 { 806 803 char *fullname = (char *) userdata; 807 804 808 805 if (fullname[0] == '\0') 809 return (FALSE);806 return FALSE; 810 807 else { 811 char *tmp, *tmp1 = bb_xstrdup(filename);808 char *tmp, *tmp1 = xstrdup(filename); 812 809 tmp = bb_get_last_path_component(tmp1); 813 810 if (strcmp(tmp, fullname) == 0) { 814 811 free(tmp1); 815 812 /* Stop searching if we find a match */ 816 m_filename = bb_xstrdup(filename);817 return (FALSE);813 m_filename = xstrdup(filename); 814 return FALSE; 818 815 } 819 816 free(tmp1); 820 817 } 821 return (TRUE);818 return TRUE; 822 819 } 823 820 … … 852 849 static enum obj_reloc 853 850 arch_apply_relocation(struct obj_file *f, 854 855 856 857 851 struct obj_section *targsec, 852 struct obj_section *symsec, 853 struct obj_symbol *sym, 854 ElfW(RelM) *rel, ElfW(Addr) v) 858 855 { 859 856 struct arch_file *ifile = (struct arch_file *) f; … … 861 858 ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset); 862 859 ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset; 863 #if defined( CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES)860 #if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES) 864 861 struct arch_symbol *isym = (struct arch_symbol *) sym; 865 862 #endif 866 863 #if defined(__arm__) || defined(__i386__) || defined(__mc68000__) || defined(__sh__) || defined(__s390__) 867 #if defined( CONFIG_USE_GOT_ENTRIES)864 #if defined(USE_GOT_ENTRIES) 868 865 ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0; 869 866 #endif 870 867 #endif 871 #if defined( CONFIG_USE_PLT_ENTRIES)868 #if defined(USE_PLT_ENTRIES) 872 869 ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0; 873 870 unsigned long *ip; 874 # if defined( CONFIG_USE_PLT_LIST)871 # if defined(USE_PLT_LIST) 875 872 struct arch_list_entry *pe; 876 873 # else … … 898 895 * but is full 32 bits relative */ 899 896 900 assert(got != 0);901 897 *loc += got - dot; 902 898 break; … … 907 903 908 904 case R_ARM_GOTOFF: /* address relative to the got */ 909 assert(got != 0);910 905 *loc += v - got; 911 906 break; … … 977 972 978 973 case R_386_GOTPC: 979 assert(got != 0);980 974 *loc += got - dot; 981 975 break; … … 985 979 986 980 case R_386_GOTOFF: 987 assert(got != 0);988 981 *loc += v - got; 989 982 break; 990 983 991 #elif defined 984 #elif defined(__microblaze__) 992 985 case R_MICROBLAZE_NONE: 993 986 case R_MICROBLAZE_64_NONE: … … 1000 993 * v is the target symbol address. 1001 994 * So we need to extract the offset in the code, 1002 * adding v, then subtrating the current address 995 * adding v, then subtrating the current address 1003 996 * of this instruction. 1004 997 * Ex: "IMM 0xFFFE bralid 0x0000" = "bralid 0xFFFE0000" … … 1009 1002 (loc[1] & 0xFFFF); 1010 1003 1011 /* Adjust relative offset. -4 adjustment required 1004 /* Adjust relative offset. -4 adjustment required 1012 1005 * because dot points to the IMM insn, but branch 1013 1006 * is computed relative to the branch instruction itself. … … 1107 1100 # ifdef R_68K_GOTOFF 1108 1101 case R_68K_GOTOFF: 1109 assert(got != 0);1110 1102 *loc += v - got; 1111 1103 break; … … 1138 1130 of the carry we need to add. Save the information, and let LO16 1139 1131 do the actual relocation. */ 1140 n = (struct mips_hi16 *)xmalloc(sizeof *n);1132 n = xmalloc(sizeof *n); 1141 1133 n->addr = loc; 1142 1134 n->value = v; … … 1161 1153 struct mips_hi16 *next; 1162 1154 unsigned long insn; 1163 1164 /* The value for the HI16 had best be the same. */1165 assert(v == l->value);1166 1155 1167 1156 /* Do the HI16 relocation. Note that we actually don't … … 1413 1402 case R_390_PLT16DBL: 1414 1403 /* find the plt entry and initialize it. */ 1415 assert(isym != NULL);1416 1404 pe = (struct arch_single_entry *) &isym->pltent; 1417 assert(pe->allocated);1418 1405 if (pe->inited == 0) { 1419 1406 ip = (unsigned long *)(ifile->plt->contents + pe->offset); … … 1445 1432 1446 1433 case R_390_GOTPC: 1447 assert(got != 0);1448 1434 *(unsigned long *) loc += got - dot; 1449 1435 break; … … 1452 1438 case R_390_GOT16: 1453 1439 case R_390_GOT32: 1454 assert(isym != NULL);1455 assert(got != 0);1456 1440 if (!isym->gotent.inited) 1457 1441 { … … 1471 1455 # endif 1472 1456 case R_390_GOTOFF32: 1473 assert(got != 0);1474 1457 *loc += v - got; 1475 1458 break; … … 1502 1485 1503 1486 case R_SH_GOTPC: 1504 assert(got != 0);1505 1487 *loc = got - dot + rel->r_addend; 1506 1488 break; … … 1510 1492 1511 1493 case R_SH_GOTOFF: 1512 assert(got != 0);1513 1494 *loc = v - got; 1514 1495 break; … … 1559 1540 # endif /* __SH5__ */ 1560 1541 1561 #elif defined 1542 #elif defined(__v850e__) 1562 1543 1563 1544 case R_V850_NONE: … … 1632 1613 goto bb_use_got; 1633 1614 # if 0 1634 assert(isym != NULL);1635 1615 if (!isym->gotent.reloc_done) 1636 1616 { … … 1655 1635 break; 1656 1636 1657 #if defined( CONFIG_USE_PLT_ENTRIES)1637 #if defined(USE_PLT_ENTRIES) 1658 1638 1659 1639 bb_use_plt: 1660 1640 1661 1641 /* find the plt entry and initialize it if necessary */ 1662 assert(isym != NULL); 1663 1664 #if defined(CONFIG_USE_PLT_LIST) 1642 1643 #if defined(USE_PLT_LIST) 1665 1644 for (pe = isym->pltent; pe != NULL && pe->addend != rel->r_addend;) 1666 1645 pe = pe->next; 1667 assert(pe != NULL);1668 1646 #else 1669 1647 pe = &isym->pltent; … … 1685 1663 ip[3] = 0x4e800420; /* bctr */ 1686 1664 #endif 1687 #if defined 1665 #if defined(__v850e__) 1688 1666 /* We have to trash a register, so we assume that any control 1689 1667 transfer more than 21-bits away must be a function call … … 1698 1676 v -= dot; 1699 1677 /* if the target is too far away.... */ 1700 #if defined (__arm__) || defined(__powerpc__)1678 #if defined(__arm__) || defined(__powerpc__) 1701 1679 if ((int)v < -0x02000000 || (int)v >= 0x02000000) 1702 #elif defined 1680 #elif defined(__v850e__) 1703 1681 if ((ElfW(Sword))v > 0x1fffff || (ElfW(Sword))v < (ElfW(Sword))-0x200000) 1704 1682 #endif … … 1706 1684 v = plt + pe->offset - dot; 1707 1685 1708 #if defined 1686 #if defined(__v850e__) 1709 1687 if (v & 1) 1710 1688 #else … … 1723 1701 *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc); 1724 1702 #endif 1725 #if defined 1703 #if defined(__v850e__) 1726 1704 /* We write two shorts instead of a long because even 32-bit insns 1727 1705 only need half-word alignment, but the 32-bit data write needs … … 1734 1712 #endif 1735 1713 break; 1736 #endif /* CONFIG_USE_PLT_ENTRIES */1737 1738 #if defined( CONFIG_USE_GOT_ENTRIES)1714 #endif /* USE_PLT_ENTRIES */ 1715 1716 #if defined(USE_GOT_ENTRIES) 1739 1717 bb_use_got: 1740 1718 1741 assert(isym != NULL);1742 1719 /* needs an entry in the .got: set it, once */ 1743 1720 if (!isym->gotent.inited) { … … 1753 1730 break; 1754 1731 1755 #endif /* CONFIG_USE_GOT_ENTRIES */1732 #endif /* USE_GOT_ENTRIES */ 1756 1733 } 1757 1734 … … 1760 1737 1761 1738 1762 #if defined( CONFIG_USE_LIST)1739 #if defined(USE_LIST) 1763 1740 1764 1741 static int arch_list_add(ElfW(RelM) *rel, struct arch_list_entry **list, … … 1787 1764 #endif 1788 1765 1789 #if defined( CONFIG_USE_SINGLE)1766 #if defined(USE_SINGLE) 1790 1767 1791 1768 static int arch_single_init(ElfW(RelM) *rel, struct arch_single_entry *single, … … 1803 1780 #endif 1804 1781 1805 #if defined( CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES)1806 1807 static struct obj_section *arch_xsect_init(struct obj_file *f, c har *name,1782 #if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES) 1783 1784 static struct obj_section *arch_xsect_init(struct obj_file *f, const char *name, 1808 1785 int offset, int size) 1809 1786 { … … 1819 1796 myrelsec = obj_create_alloced_section(f, name, 1820 1797 size, offset); 1821 assert(myrelsec);1822 1798 } 1823 1799 … … 1829 1805 static void arch_create_got(struct obj_file *f) 1830 1806 { 1831 #if defined( CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES)1807 #if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES) 1832 1808 struct arch_file *ifile = (struct arch_file *) f; 1833 1809 int i; 1834 #if defined( CONFIG_USE_GOT_ENTRIES)1810 #if defined(USE_GOT_ENTRIES) 1835 1811 int got_offset = 0, got_needed = 0, got_allocate; 1836 1812 #endif 1837 #if defined( CONFIG_USE_PLT_ENTRIES)1813 #if defined(USE_PLT_ENTRIES) 1838 1814 int plt_offset = 0, plt_needed = 0, plt_allocate; 1839 1815 #endif … … 1860 1836 extsym = &symtab[ELF_R_SYM(rel->r_info)]; 1861 1837 1862 #if defined( CONFIG_USE_GOT_ENTRIES)1838 #if defined(USE_GOT_ENTRIES) 1863 1839 got_allocate = 0; 1864 1840 #endif 1865 #if defined( CONFIG_USE_PLT_ENTRIES)1841 #if defined(USE_PLT_ENTRIES) 1866 1842 plt_allocate = 0; 1867 1843 #endif … … 1869 1845 switch (ELF_R_TYPE(rel->r_info)) { 1870 1846 #if defined(__arm__) 1871 1872 1873 1874 1875 1876 1877 1878 1879 1880 1881 1882 1883 1847 case R_ARM_PC24: 1848 case R_ARM_PLT32: 1849 plt_allocate = 1; 1850 break; 1851 1852 case R_ARM_GOTOFF: 1853 case R_ARM_GOTPC: 1854 got_needed = 1; 1855 continue; 1856 1857 case R_ARM_GOT32: 1858 got_allocate = 1; 1859 break; 1884 1860 1885 1861 #elif defined(__i386__) 1886 1887 1888 1889 1890 1891 1892 1893 1862 case R_386_GOTPC: 1863 case R_386_GOTOFF: 1864 got_needed = 1; 1865 continue; 1866 1867 case R_386_GOT32: 1868 got_allocate = 1; 1869 break; 1894 1870 1895 1871 #elif defined(__powerpc__) 1896 1897 1898 1872 case R_PPC_REL24: 1873 plt_allocate = 1; 1874 break; 1899 1875 1900 1876 #elif defined(__mc68000__) 1901 1902 1903 1877 case R_68K_GOT32: 1878 got_allocate = 1; 1879 break; 1904 1880 1905 1881 #ifdef R_68K_GOTOFF 1906 1907 1908 1882 case R_68K_GOTOFF: 1883 got_needed = 1; 1884 continue; 1909 1885 #endif 1910 1886 1911 1887 #elif defined(__sh__) 1912 1913 1914 1915 1916 1917 1918 1919 1920 1921 #elif defined 1922 1923 1924 1925 1926 #endif 1927 1928 1888 case R_SH_GOT32: 1889 got_allocate = 1; 1890 break; 1891 1892 case R_SH_GOTPC: 1893 case R_SH_GOTOFF: 1894 got_needed = 1; 1895 continue; 1896 1897 #elif defined(__v850e__) 1898 case R_V850_22_PCREL: 1899 plt_needed = 1; 1900 break; 1901 1902 #endif 1903 default: 1904 continue; 1929 1905 } 1930 1906 … … 1935 1911 } 1936 1912 intsym = (struct arch_symbol *) obj_find_symbol(f, name); 1937 #if defined( CONFIG_USE_GOT_ENTRIES)1913 #if defined(USE_GOT_ENTRIES) 1938 1914 if (got_allocate) { 1939 1915 got_offset += arch_single_init( 1940 1916 rel, &intsym->gotent, 1941 got_offset, CONFIG_GOT_ENTRY_SIZE);1917 got_offset, GOT_ENTRY_SIZE); 1942 1918 1943 1919 got_needed = 1; 1944 1920 } 1945 1921 #endif 1946 #if defined( CONFIG_USE_PLT_ENTRIES)1922 #if defined(USE_PLT_ENTRIES) 1947 1923 if (plt_allocate) { 1948 #if defined( CONFIG_USE_PLT_LIST)1924 #if defined(USE_PLT_LIST) 1949 1925 plt_offset += arch_list_add( 1950 1926 rel, &intsym->pltent, 1951 plt_offset, CONFIG_PLT_ENTRY_SIZE);1927 plt_offset, PLT_ENTRY_SIZE); 1952 1928 #else 1953 1929 plt_offset += arch_single_init( 1954 1930 rel, &intsym->pltent, 1955 plt_offset, CONFIG_PLT_ENTRY_SIZE);1931 plt_offset, PLT_ENTRY_SIZE); 1956 1932 #endif 1957 1933 plt_needed = 1; … … 1961 1937 } 1962 1938 1963 #if defined( CONFIG_USE_GOT_ENTRIES)1939 #if defined(USE_GOT_ENTRIES) 1964 1940 if (got_needed) { 1965 1941 ifile->got = arch_xsect_init(f, ".got", got_offset, 1966 CONFIG_GOT_ENTRY_SIZE);1967 } 1968 #endif 1969 1970 #if defined( CONFIG_USE_PLT_ENTRIES)1942 GOT_ENTRY_SIZE); 1943 } 1944 #endif 1945 1946 #if defined(USE_PLT_ENTRIES) 1971 1947 if (plt_needed) { 1972 1948 ifile->plt = arch_xsect_init(f, ".plt", plt_offset, 1973 CONFIG_PLT_ENTRY_SIZE);1974 } 1975 #endif 1976 1977 #endif /* defined( CONFIG_USE_GOT_ENTRIES) || defined(CONFIG_USE_PLT_ENTRIES) */1949 PLT_ENTRY_SIZE); 1950 } 1951 #endif 1952 1953 #endif /* defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES) */ 1978 1954 } 1979 1955 … … 1981 1957 1982 1958 /* Standard ELF hash function. */ 1983 static inlineunsigned long obj_elf_hash_n(const char *name, unsigned long n)1959 static unsigned long obj_elf_hash_n(const char *name, unsigned long n) 1984 1960 { 1985 1961 unsigned long h = 0; … … 2004 1980 } 2005 1981 2006 #if def CONFIG_FEATURE_INSMOD_VERSION_CHECKING1982 #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 2007 1983 /* String comparison for non-co-versioned kernel and module. */ 2008 1984 … … 2056 2032 } 2057 2033 2058 #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */2034 #endif /* FEATURE_INSMOD_VERSION_CHECKING */ 2059 2035 2060 2036 static struct obj_symbol * 2061 2037 obj_add_symbol(struct obj_file *f, const char *name, 2062 2063 2064 2038 unsigned long symidx, int info, 2039 int secidx, ElfW(Addr) value, 2040 unsigned long size) 2065 2041 { 2066 2042 struct obj_symbol *sym; … … 2166 2142 } 2167 2143 2168 static ElfW(Addr) 2169 obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym) 2144 static ElfW(Addr) obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym) 2170 2145 { 2171 2146 if (sym) { … … 2226 2201 2227 2202 static struct obj_section *obj_create_alloced_section(struct obj_file *f, 2228 2229 2230 2203 const char *name, 2204 unsigned long align, 2205 unsigned long size) 2231 2206 { 2232 2207 int newidx = f->header.e_shnum++; … … 2252 2227 2253 2228 static struct obj_section *obj_create_alloced_section_first(struct obj_file *f, 2254 2255 2256 2229 const char *name, 2230 unsigned long align, 2231 unsigned long size) 2257 2232 { 2258 2233 int newidx = f->header.e_shnum++; … … 2304 2279 size_t name_alloced_size = 0; 2305 2280 #endif 2306 #if def CONFIG_FEATURE_CHECK_TAINTED_MODULE2281 #if ENABLE_FEATURE_CHECK_TAINTED_MODULE 2307 2282 int gpl; 2308 2283 … … 2324 2299 */ 2325 2300 if (strncmp((char *)s->name, "GPLONLY_", 8) == 0) { 2326 #if def CONFIG_FEATURE_CHECK_TAINTED_MODULE2301 #if ENABLE_FEATURE_CHECK_TAINTED_MODULE 2327 2302 if (gpl) 2328 2303 s->name += 8; … … 2338 2313 reference `linker names'). */ 2339 2314 size_t extra = sizeof SYMBOL_PREFIX; 2340 size_t name_size = strlen 2315 size_t name_size = strlen(name) + extra; 2341 2316 if (name_size > name_alloced_size) { 2342 2317 name_alloced_size = name_size * 2; 2343 name_buf = alloca 2318 name_buf = alloca(name_alloced_size); 2344 2319 } 2345 strcpy 2346 strcpy 2320 strcpy(name_buf, SYMBOL_PREFIX); 2321 strcpy(name_buf + extra - 1, name); 2347 2322 name = name_buf; 2348 2323 #endif /* SYMBOL_PREFIX */ … … 2352 2327 #ifdef SYMBOL_PREFIX 2353 2328 /* Put NAME_BUF into more permanent storage. */ 2354 name = xmalloc 2355 strcpy 2329 name = xmalloc(name_size); 2330 strcpy(name, name_buf); 2356 2331 #endif 2357 2332 sym = obj_add_symbol(f, name, -1, … … 2376 2351 /* Add module symbols first. */ 2377 2352 2378 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m) 2353 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m) { 2379 2354 if (m->nsyms 2380 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms, 2381 m->nsyms)) m->used = 1, ++nused; 2355 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms, m->nsyms) 2356 ) { 2357 m->used = 1; 2358 ++nused; 2359 } 2360 } 2382 2361 2383 2362 n_ext_modules_used = nused; … … 2448 2427 2449 2428 #ifdef SYMBOL_PREFIX 2450 sym_name = alloca (strlen(key) + sizeof SYMBOL_PREFIX);2451 strcpy 2452 strcat 2429 sym_name = alloca(strlen(key) + sizeof SYMBOL_PREFIX); 2430 strcpy(sym_name, SYMBOL_PREFIX); 2431 strcat(sym_name, key); 2453 2432 #else 2454 2433 sym_name = key; … … 2491 2470 } else if (*q == '\\') 2492 2471 switch (*++q) { 2493 case 'a': 2494 *r = '\a'; 2495 break; 2496 case 'b': 2497 *r = '\b'; 2498 break; 2499 case 'e': 2500 *r = '\033'; 2501 break; 2502 case 'f': 2503 *r = '\f'; 2504 break; 2505 case 'n': 2506 *r = '\n'; 2507 break; 2508 case 'r': 2509 *r = '\r'; 2510 break; 2511 case 't': 2512 *r = '\t'; 2513 break; 2514 2515 case '0': 2516 case '1': 2517 case '2': 2518 case '3': 2519 case '4': 2520 case '5': 2521 case '6': 2522 case '7': 2523 { 2524 int c = *q - '0'; 2525 if (q[1] >= '0' && q[1] <= '7') { 2472 case 'a': 2473 *r = '\a'; 2474 break; 2475 case 'b': 2476 *r = '\b'; 2477 break; 2478 case 'e': 2479 *r = '\033'; 2480 break; 2481 case 'f': 2482 *r = '\f'; 2483 break; 2484 case 'n': 2485 *r = '\n'; 2486 break; 2487 case 'r': 2488 *r = '\r'; 2489 break; 2490 case 't': 2491 *r = '\t'; 2492 break; 2493 2494 case '0': 2495 case '1': 2496 case '2': 2497 case '3': 2498 case '4': 2499 case '5': 2500 case '6': 2501 case '7': 2502 { 2503 int c = *q - '0'; 2504 if (q[1] >= '0' && q[1] <= '7') { 2505 c = (c * 8) + *++q - '0'; 2506 if (q[1] >= '0' && q[1] <= '7') 2526 2507 c = (c * 8) + *++q - '0'; 2527 if (q[1] >= '0' && q[1] <= '7')2528 c = (c * 8) + *++q - '0';2529 }2530 *r = c;2531 2508 } 2532 break; 2533 2534 default: 2535 *r = *q; 2536 break; 2509 *r = c; 2510 } 2511 break; 2512 2513 default: 2514 *r = *q; 2515 break; 2537 2516 } else 2538 2517 *r = *q; … … 2565 2544 /* last string */ 2566 2545 str = q; 2567 q = "";2546 q = (char*)""; 2568 2547 } 2569 2548 } … … 2574 2553 loc += tgt_sizeof_char_p; 2575 2554 } else { 2576 /* Array of chars (in fact, matrix 2555 /* Array of chars (in fact, matrix!) */ 2577 2556 unsigned long charssize; /* size of each member */ 2578 2557 … … 2600 2579 long v = strtoul(q, &q, 0); 2601 2580 switch (*p) { 2602 2603 2604 2605 2606 2607 2608 2609 2610 2611 2612 2613 2614 2615 2616 2617 2618 2619 2620 2581 case 'b': 2582 *loc++ = v; 2583 break; 2584 case 'h': 2585 *(short *) loc = v; 2586 loc += tgt_sizeof_short; 2587 break; 2588 case 'i': 2589 *(int *) loc = v; 2590 loc += tgt_sizeof_int; 2591 break; 2592 case 'l': 2593 *(long *) loc = v; 2594 loc += tgt_sizeof_long; 2595 break; 2596 2597 default: 2598 bb_error_msg("unknown parameter type '%c' for %s", *p, key); 2599 return 0; 2621 2600 } 2622 2601 } … … 2624 2603 retry_end_of_value: 2625 2604 switch (*q) { 2626 case '\0': 2627 goto end_of_arg; 2628 2629 case ' ': 2630 case '\t': 2631 case '\n': 2632 case '\r': 2633 ++q; 2634 goto retry_end_of_value; 2635 2636 case ',': 2637 if (++n > max) { 2638 bb_error_msg("too many values for %s (max %d)", key, max); 2639 return 0; 2640 } 2641 ++q; 2642 break; 2643 2644 default: 2645 bb_error_msg("invalid argument syntax for %s", key); 2605 case '\0': 2606 goto end_of_arg; 2607 2608 case ' ': 2609 case '\t': 2610 case '\n': 2611 case '\r': 2612 ++q; 2613 goto retry_end_of_value; 2614 2615 case ',': 2616 if (++n > max) { 2617 bb_error_msg("too many values for %s (max %d)", key, max); 2646 2618 return 0; 2619 } 2620 ++q; 2621 break; 2622 2623 default: 2624 bb_error_msg("invalid argument syntax for %s", key); 2625 return 0; 2647 2626 } 2648 2627 } … … 2660 2639 } 2661 2640 2662 #if def CONFIG_FEATURE_INSMOD_VERSION_CHECKING2641 #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 2663 2642 static int new_is_module_checksummed(struct obj_file *f) 2664 2643 { 2665 2644 const char *p = get_modinfo_value(f, "using_checksums"); 2666 2645 if (p) 2667 return atoi(p);2646 return xatoi(p); 2668 2647 else 2669 2648 return 0; … … 2696 2675 } 2697 2676 2698 #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */2677 #endif /* FEATURE_INSMOD_VERSION_CHECKING */ 2699 2678 2700 2679 … … 2725 2704 /* Collect the modules' symbols. */ 2726 2705 2727 if (nmod) {2706 if (nmod) { 2728 2707 ext_modules = modules = xmalloc(nmod * sizeof(*modules)); 2729 2708 memset(modules, 0, nmod * sizeof(*modules)); … … 2826 2805 } 2827 2806 2828 #if def CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS2807 #if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS 2829 2808 /* add an entry to the __ksymtab section, creating it if necessary */ 2830 2809 static void new_add_ksymtab(struct obj_file *f, struct obj_symbol *sym) … … 2849 2828 return; 2850 2829 sec->header.sh_flags |= SHF_ALLOC; 2851 sec->header.sh_addralign = tgt_sizeof_void_p; /* Empty section might2852 be byte-aligned */2830 /* Empty section might be byte-aligned */ 2831 sec->header.sh_addralign = tgt_sizeof_void_p; 2853 2832 ofs = sec->header.sh_size; 2854 2833 obj_symbol_patch(f, sec->idx, ofs, sym); … … 2856 2835 obj_extend_section(sec, 2 * tgt_sizeof_char_p); 2857 2836 } 2858 #endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */2837 #endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */ 2859 2838 2860 2839 static int new_create_module_ksymtab(struct obj_file *f) … … 2887 2866 } 2888 2867 2889 if ( flag_export && !obj_find_section(f, "__ksymtab")) {2868 if (!flag_noexport && !obj_find_section(f, "__ksymtab")) { 2890 2869 size_t nsyms; 2891 2870 int *loaded; 2892 2871 2893 sec = 2894 obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p, 2895 0); 2872 sec = obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p, 0); 2896 2873 2897 2874 /* We don't want to export symbols residing in sections that … … 3282 3259 /* Do it! */ 3283 3260 switch (arch_apply_relocation 3284 (f, targsec, symsec, intsym, rel, value)) { 3285 case obj_reloc_ok: 3286 break; 3287 3288 case obj_reloc_overflow: 3289 errmsg = "Relocation overflow"; 3290 goto bad_reloc; 3291 case obj_reloc_dangerous: 3292 errmsg = "Dangerous relocation"; 3293 goto bad_reloc; 3294 case obj_reloc_unhandled: 3295 errmsg = "Unhandled relocation"; 3261 (f, targsec, symsec, intsym, rel, value) 3262 ) { 3263 case obj_reloc_ok: 3264 break; 3265 3266 case obj_reloc_overflow: 3267 errmsg = "Relocation overflow"; 3268 goto bad_reloc; 3269 case obj_reloc_dangerous: 3270 errmsg = "Dangerous relocation"; 3271 goto bad_reloc; 3272 case obj_reloc_unhandled: 3273 errmsg = "Unhandled relocation"; 3296 3274 bad_reloc: 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3275 if (extsym) { 3276 bb_error_msg("%s of type %ld for %s", errmsg, 3277 (long) ELF_R_TYPE(rel->r_info), 3278 strtab + extsym->st_name); 3279 } else { 3280 bb_error_msg("%s of type %ld", errmsg, 3281 (long) ELF_R_TYPE(rel->r_info)); 3282 } 3283 ret = 0; 3284 break; 3307 3285 } 3308 3286 } … … 3432 3410 sec->idx = i; 3433 3411 3434 if(sec->header.sh_size) switch (sec->header.sh_type) { 3412 if (sec->header.sh_size) { 3413 switch (sec->header.sh_type) { 3435 3414 case SHT_NULL: 3436 3415 case SHT_NOTE: … … 3483 3462 (long) sec->header.sh_type); 3484 3463 return NULL; 3464 } 3485 3465 } 3486 3466 } … … 3508 3488 3509 3489 switch (sec->header.sh_type) { 3510 case SHT_SYMTAB: 3511 { 3512 unsigned long nsym, j; 3513 char *strtab; 3514 ElfW(Sym) * sym; 3515 3516 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) { 3517 bb_error_msg("symbol size mismatch: %lu != %lu", 3518 (unsigned long) sec->header.sh_entsize, 3519 (unsigned long) sizeof(ElfW(Sym))); 3520 return NULL; 3521 } 3522 3523 nsym = sec->header.sh_size / sizeof(ElfW(Sym)); 3524 strtab = f->sections[sec->header.sh_link]->contents; 3525 sym = (ElfW(Sym) *) sec->contents; 3526 3527 /* Allocate space for a table of local symbols. */ 3528 j = f->local_symtab_size = sec->header.sh_info; 3529 f->local_symtab = xcalloc(j, sizeof(struct obj_symbol *)); 3530 3531 /* Insert all symbols into the hash table. */ 3532 for (j = 1, ++sym; j < nsym; ++j, ++sym) { 3533 ElfW(Addr) val = sym->st_value; 3534 const char *name; 3535 if (sym->st_name) 3536 name = strtab + sym->st_name; 3537 else if (sym->st_shndx < shnum) 3538 name = f->sections[sym->st_shndx]->name; 3539 else 3540 continue; 3541 3542 #if defined(__SH5__) 3543 /* 3544 * For sh64 it is possible that the target of a branch 3545 * requires a mode switch (32 to 16 and back again). 3546 * 3547 * This is implied by the lsb being set in the target 3548 * address for SHmedia mode and clear for SHcompact. 3549 */ 3550 val |= sym->st_other & 4; 3551 #endif 3552 3553 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx, 3554 val, sym->st_size); 3555 } 3556 } 3557 break; 3558 3559 case SHT_RELM: 3560 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) { 3561 bb_error_msg("relocation entry size mismatch: %lu != %lu", 3490 case SHT_SYMTAB: 3491 { 3492 unsigned long nsym, j; 3493 char *strtab; 3494 ElfW(Sym) * sym; 3495 3496 if (sec->header.sh_entsize != sizeof(ElfW(Sym))) { 3497 bb_error_msg("symbol size mismatch: %lu != %lu", 3562 3498 (unsigned long) sec->header.sh_entsize, 3563 (unsigned long) sizeof(ElfW( RelM)));3499 (unsigned long) sizeof(ElfW(Sym))); 3564 3500 return NULL; 3565 3501 } 3566 break; 3567 /* XXX Relocation code from modutils-2.3.19 is not here. 3568 * Why? That's about 20 lines of code from obj/obj_load.c, 3569 * which gets done in a second pass through the sections. 3570 * This BusyBox insmod does similar work in obj_relocate(). */ 3502 3503 nsym = sec->header.sh_size / sizeof(ElfW(Sym)); 3504 strtab = f->sections[sec->header.sh_link]->contents; 3505 sym = (ElfW(Sym) *) sec->contents; 3506 3507 /* Allocate space for a table of local symbols. */ 3508 j = f->local_symtab_size = sec->header.sh_info; 3509 f->local_symtab = xzalloc(j * sizeof(struct obj_symbol *)); 3510 3511 /* Insert all symbols into the hash table. */ 3512 for (j = 1, ++sym; j < nsym; ++j, ++sym) { 3513 ElfW(Addr) val = sym->st_value; 3514 const char *name; 3515 if (sym->st_name) 3516 name = strtab + sym->st_name; 3517 else if (sym->st_shndx < shnum) 3518 name = f->sections[sym->st_shndx]->name; 3519 else 3520 continue; 3521 #if defined(__SH5__) 3522 /* 3523 * For sh64 it is possible that the target of a branch 3524 * requires a mode switch (32 to 16 and back again). 3525 * 3526 * This is implied by the lsb being set in the target 3527 * address for SHmedia mode and clear for SHcompact. 3528 */ 3529 val |= sym->st_other & 4; 3530 #endif 3531 3532 obj_add_symbol(f, name, j, sym->st_info, sym->st_shndx, 3533 val, sym->st_size); 3534 } 3535 } 3536 break; 3537 3538 case SHT_RELM: 3539 if (sec->header.sh_entsize != sizeof(ElfW(RelM))) { 3540 bb_error_msg("relocation entry size mismatch: %lu != %lu", 3541 (unsigned long) sec->header.sh_entsize, 3542 (unsigned long) sizeof(ElfW(RelM))); 3543 return NULL; 3544 } 3545 break; 3546 /* XXX Relocation code from modutils-2.3.19 is not here. 3547 * Why? That's about 20 lines of code from obj/obj_load.c, 3548 * which gets done in a second pass through the sections. 3549 * This BusyBox insmod does similar work in obj_relocate(). */ 3571 3550 } 3572 3551 } … … 3575 3554 } 3576 3555 3577 #if def CONFIG_FEATURE_INSMOD_LOADINKMEM3556 #if ENABLE_FEATURE_INSMOD_LOADINKMEM 3578 3557 /* 3579 3558 * load the unloaded sections directly into the memory allocated by … … 3598 3577 fseek(fp, sec->header.sh_offset, SEEK_SET); 3599 3578 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) { 3600 bb_ error_msg("error reading ELF section data: %s\n", strerror(errno));3579 bb_perror_msg("error reading ELF section data"); 3601 3580 return 0; 3602 3581 } … … 3619 3598 const char *const *p; 3620 3599 3621 for (p = specials; *p; ++p) 3622 if ((sym = obj_find_symbol(f, *p)) != NULL) 3623 sym->info = 3624 ELF_ST_INFO(STB_LOCAL, ELF_ST_TYPE(sym->info)); 3625 } 3626 3627 3628 #ifdef CONFIG_FEATURE_CHECK_TAINTED_MODULE 3600 for (p = specials; *p; ++p) { 3601 sym = obj_find_symbol(f, *p); 3602 if (sym != NULL) 3603 sym->info = ELF_ST_INFO(STB_LOCAL, ELF_ST_TYPE(sym->info)); 3604 } 3605 } 3606 3607 3608 #if ENABLE_FEATURE_CHECK_TAINTED_MODULE 3629 3609 static int obj_gpl_license(struct obj_file *f, const char **license) 3630 3610 { … … 3634 3614 * work, somebody will use "GPL sucks, this is proprietary". 3635 3615 */ 3636 static const char * 3616 static const char *const gpl_licenses[] = { 3637 3617 "GPL", 3638 3618 "GPL v2", 3639 3619 "GPL and additional rights", 3640 3620 "Dual BSD/GPL", 3641 "Dual MPL/GPL" ,3621 "Dual MPL/GPL" 3642 3622 }; 3643 3623 3644 if ((sec = obj_find_section(f, ".modinfo"))) { 3624 sec = obj_find_section(f, ".modinfo"); 3625 if (sec) { 3645 3626 const char *value, *ptr, *endptr; 3646 3627 ptr = sec->contents; 3647 3628 endptr = ptr + sec->header.sh_size; 3648 3629 while (ptr < endptr) { 3649 if ((value = strchr(ptr, '=')) && strncmp(ptr, "license", value-ptr) == 0) { 3630 value = strchr(ptr, '='); 3631 if (value && strncmp(ptr, "license", value-ptr) == 0) { 3650 3632 int i; 3651 3633 if (license) 3652 3634 *license = value+1; 3653 for (i = 0; i < sizeof(gpl_licenses)/sizeof(gpl_licenses[0]); ++i) {3635 for (i = 0; i < ARRAY_SIZE(gpl_licenses); ++i) { 3654 3636 if (strcmp(value+1, gpl_licenses[i]) == 0) 3655 return (0);3637 return 0; 3656 3638 } 3657 return (2);3639 return 2; 3658 3640 } 3659 3641 if (strchr(ptr, '\0')) … … 3663 3645 } 3664 3646 } 3665 return (1);3647 return 1; 3666 3648 } 3667 3649 … … 3675 3657 int kernel_has_tainted, int taint, const char *text1, const char *text2) 3676 3658 { 3659 static smallint printed_info; 3660 3677 3661 char buf[80]; 3678 3662 int oldval; 3679 static int first = 1; 3663 3680 3664 if (fd < 0 && !kernel_has_tainted) 3681 3665 return; /* New modutils on old kernel */ 3682 3666 printf("Warning: loading %s will taint the kernel: %s%s\n", 3683 3667 m_name, text1, text2); 3684 if ( first) {3668 if (!printed_info) { 3685 3669 printf(" See %s for information about tainted modules\n", TAINT_URL); 3686 first = 0;3670 printed_info = 1; 3687 3671 } 3688 3672 if (fd >= 0) { … … 3698 3682 static void check_tainted_module(struct obj_file *f, char *m_name) 3699 3683 { 3700 static const char tainted_file[] = TAINT_FILENAME; 3684 static const char tainted_file[] ALIGN1 = TAINT_FILENAME; 3685 3701 3686 int fd, kernel_has_tainted; 3702 3687 const char *ptr; 3703 3688 3704 3689 kernel_has_tainted = 1; 3705 if ((fd = open(tainted_file, O_RDWR)) < 0) { 3690 fd = open(tainted_file, O_RDWR); 3691 if (fd < 0) { 3706 3692 if (errno == ENOENT) 3707 3693 kernel_has_tainted = 0; … … 3738 3724 close(fd); 3739 3725 } 3740 #else /* CONFIG_FEATURE_CHECK_TAINTED_MODULE */3741 #define check_tainted_module(x, y) do { } while (0);3742 #endif /* CONFIG_FEATURE_CHECK_TAINTED_MODULE */3743 3744 #if def CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS3726 #else /* FEATURE_CHECK_TAINTED_MODULE */ 3727 #define check_tainted_module(x, y) do { } while (0); 3728 #endif /* FEATURE_CHECK_TAINTED_MODULE */ 3729 3730 #if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS 3745 3731 /* add module source, timestamp, kernel version and a symbol for the 3746 3732 * start of some sections. this info is used by ksymoops to do better … … 3750 3736 get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) 3751 3737 { 3752 #if def CONFIG_FEATURE_INSMOD_VERSION_CHECKING3738 #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 3753 3739 return new_get_module_version(f, str); 3754 #else /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */3740 #else /* FEATURE_INSMOD_VERSION_CHECKING */ 3755 3741 strncpy(str, "???", sizeof(str)); 3756 3742 return -1; 3757 #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */3743 #endif /* FEATURE_INSMOD_VERSION_CHECKING */ 3758 3744 } 3759 3745 … … 3766 3752 const char *m_name) 3767 3753 { 3768 static const char symprefix[] = "__insmod_"; 3754 static const char symprefix[] ALIGN1 = "__insmod_"; 3755 3769 3756 struct obj_section *sec; 3770 3757 struct obj_symbol *sym; … … 3783 3770 3784 3771 if (realpath(filename, real)) { 3785 absolute_filename = bb_xstrdup(real); 3786 } 3787 else { 3788 int save_errno = errno; 3789 bb_error_msg("cannot get realpath for %s", filename); 3790 errno = save_errno; 3791 perror(""); 3792 absolute_filename = bb_xstrdup(filename); 3772 absolute_filename = xstrdup(real); 3773 } else { 3774 bb_perror_msg("cannot get realpath for %s", filename); 3775 absolute_filename = xstrdup(filename); 3793 3776 } 3794 3777 … … 3800 3783 * "export all symbols" compatibility code will export these symbols later. 3801 3784 */ 3802 use_ksymtab = obj_find_section(f, "__ksymtab") || !flag_export; 3803 3804 if ((sec = obj_find_section(f, ".this"))) { 3785 use_ksymtab = obj_find_section(f, "__ksymtab") || flag_noexport; 3786 3787 sec = obj_find_section(f, ".this"); 3788 if (sec) { 3805 3789 /* tag the module header with the object name, last modified 3806 3790 * timestamp and module version. worst case for module version … … 3852 3836 /* tag the desired sections if size is non-zero */ 3853 3837 3854 for (i = 0; i < sizeof(section_names)/sizeof(section_names[0]); ++i) {3855 if ((sec = obj_find_section(f, section_names[i])) &&3856 3838 for (i = 0; i < ARRAY_SIZE(section_names); ++i) { 3839 sec = obj_find_section(f, section_names[i]); 3840 if (sec && sec->header.sh_size) { 3857 3841 l = sizeof(symprefix)+ /* "__insmod_" */ 3858 3842 lm_name+ /* module name */ … … 3873 3857 } 3874 3858 } 3875 #endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */3876 3877 #if def CONFIG_FEATURE_INSMOD_LOAD_MAP3859 #endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */ 3860 3861 #if ENABLE_FEATURE_INSMOD_LOAD_MAP 3878 3862 static void print_load_map(struct obj_file *f) 3879 3863 { 3864 struct obj_section *sec; 3865 #if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL 3866 struct obj_symbol **all, **p; 3867 int i, nsyms, *loaded; 3880 3868 struct obj_symbol *sym; 3881 struct obj_symbol **all, **p; 3882 struct obj_section *sec; 3883 int i, nsyms, *loaded; 3884 3869 #endif 3885 3870 /* Report on the section layout. */ 3886 3871 … … 3904 3889 a); 3905 3890 } 3906 #if def CONFIG_FEATURE_INSMOD_LOAD_MAP_FULL3891 #if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL 3907 3892 /* Quick reference which section indicies are loaded. */ 3908 3893 … … 3964 3949 #endif 3965 3950 } 3966 3967 #endif 3968 3951 #else /* !FEATURE_INSMOD_LOAD_MAP */ 3952 void print_load_map(struct obj_file *f); 3953 #endif 3954 3955 int insmod_main( int argc, char **argv); 3969 3956 int insmod_main( int argc, char **argv) 3970 3957 { 3971 int opt;3958 char *opt_o, *arg1; 3972 3959 int len; 3973 3960 int k_crcs; … … 3980 3967 int exit_status = EXIT_FAILURE; 3981 3968 int m_has_modinfo; 3982 #if def CONFIG_FEATURE_INSMOD_VERSION_CHECKING3969 #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 3983 3970 struct utsname uts_info; 3984 3971 char m_strversion[STRVERSIONLEN]; 3985 3972 int m_version, m_crcs; 3986 3973 #endif 3987 #if def CONFIG_FEATURE_CLEAN_UP3974 #if ENABLE_FEATURE_CLEAN_UP 3988 3975 FILE *fp = 0; 3989 3976 #else 3990 3977 FILE *fp; 3991 3978 #endif 3992 #ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP3993 int flag_print_load_map = 0;3994 #endif3995 3979 int k_version = 0; 3996 3980 struct utsname myuname; 3997 3981 3998 3982 /* Parse any options */ 3999 #ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP 4000 while ((opt = getopt(argc, argv, "fkqsvxmLo:")) > 0) 4001 #else 4002 while ((opt = getopt(argc, argv, "fkqsvxLo:")) > 0) 4003 #endif 4004 { 4005 switch (opt) { 4006 case 'f': /* force loading */ 4007 flag_force_load = 1; 4008 break; 4009 case 'k': /* module loaded by kerneld, auto-cleanable */ 4010 flag_autoclean = 1; 4011 break; 4012 case 's': /* log to syslog */ 4013 /* log to syslog -- not supported */ 4014 /* but kernel needs this for request_module(), */ 4015 /* as this calls: modprobe -k -s -- <module> */ 4016 /* so silently ignore this flag */ 4017 break; 4018 case 'v': /* verbose output */ 4019 flag_verbose = 1; 4020 break; 4021 case 'q': /* silent */ 4022 flag_quiet = 1; 4023 break; 4024 case 'x': /* do not export externs */ 4025 flag_export = 0; 4026 break; 4027 case 'o': /* name the output module */ 4028 free(m_name); 4029 m_name = bb_xstrdup(optarg); 4030 break; 4031 case 'L': /* Stub warning */ 4032 /* This is needed for compatibility with modprobe. 4033 * In theory, this does locking, but we don't do 4034 * that. So be careful and plan your life around not 4035 * loading the same module 50 times concurrently. */ 4036 break; 4037 #ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP 4038 case 'm': /* print module load map */ 4039 flag_print_load_map = 1; 4040 break; 4041 #endif 4042 default: 4043 bb_show_usage(); 4044 } 4045 } 4046 4047 if (argv[optind] == NULL) { 3983 getopt32(argv, OPTION_STR, &opt_o); 3984 arg1 = argv[optind]; 3985 if (option_mask32 & OPT_o) { // -o /* name the output module */ 3986 free(m_name); 3987 m_name = xstrdup(opt_o); 3988 } 3989 3990 if (arg1 == NULL) { 4048 3991 bb_show_usage(); 4049 3992 } 4050 3993 4051 3994 /* Grab the module name */ 4052 tmp1 = bb_xstrdup(argv[optind]);3995 tmp1 = xstrdup(arg1); 4053 3996 tmp = basename(tmp1); 4054 3997 len = strlen(tmp); … … 4060 4003 } 4061 4004 4062 #if defined(CONFIG_FEATURE_2_6_MODULES) 4063 if (k_version > 4 && len > 3 && tmp[len - 3] == '.' && 4064 tmp[len - 2] == 'k' && tmp[len - 1] == 'o') { 4065 len-=3; 4005 #if ENABLE_FEATURE_2_6_MODULES 4006 if (k_version > 4 && len > 3 && tmp[len - 3] == '.' 4007 && tmp[len - 2] == 'k' && tmp[len - 1] == 'o' 4008 ) { 4009 len -= 3; 4066 4010 tmp[len] = '\0'; 4067 } 4068 else 4011 } else 4069 4012 #endif 4070 4013 if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o') { 4071 len -=2;4014 len -= 2; 4072 4015 tmp[len] = '\0'; 4073 4016 } 4074 4017 4075 4018 4076 #if defined(CONFIG_FEATURE_2_6_MODULES)4019 #if ENABLE_FEATURE_2_6_MODULES 4077 4020 if (k_version > 4) 4078 m_fullName = bb_xasprintf("%s.ko", tmp);4021 m_fullName = xasprintf("%s.ko", tmp); 4079 4022 else 4080 4023 #endif 4081 m_fullName = bb_xasprintf("%s.o", tmp);4024 m_fullName = xasprintf("%s.o", tmp); 4082 4025 4083 4026 if (!m_name) { … … 4089 4032 4090 4033 /* Get a filedesc for the module. Check we we have a complete path */ 4091 if (stat(argv[optind], &st) < 0 || !S_ISREG(st.st_mode) || 4092 (fp = fopen(argv[optind], "r")) == NULL) { 4034 if (stat(arg1, &st) < 0 || !S_ISREG(st.st_mode) 4035 || (fp = fopen(arg1, "r")) == NULL 4036 ) { 4093 4037 /* Hmm. Could not open it. First search under /lib/modules/`uname -r`, 4094 4038 * but do not error out yet if we fail to find it... */ … … 4104 4048 * /lib/modules/`uname -r` dir, So resolve it ourselves 4105 4049 * if it is a link... */ 4106 if (realpath 4050 if (realpath(tmdn, real_module_dir) == NULL) 4107 4051 module_dir = tmdn; 4108 4052 else 4109 4053 module_dir = real_module_dir; 4110 recursive_action(module_dir, TRUE, FALSE, FALSE,4111 check_module_name_match, 0, m_fullName );4054 recursive_action(module_dir, ACTION_RECURSE, 4055 check_module_name_match, 0, m_fullName, 0); 4112 4056 free(tmdn); 4113 4057 } 4114 4058 4115 4059 /* Check if we have found anything yet */ 4116 if (m_filename == 0 || ((fp = fopen(m_filename, "r")) == NULL)) 4117 { 4060 if (m_filename == 0 || ((fp = fopen(m_filename, "r")) == NULL)) { 4118 4061 char module_dir[FILENAME_MAX]; 4119 4062 … … 4124 4067 /* No module found under /lib/modules/`uname -r`, this 4125 4068 * time cast the net a bit wider. Search /lib/modules/ */ 4126 if (! recursive_action(module_dir, TRUE, FALSE, FALSE,4127 check_module_name_match, 0, m_fullName))4128 {4069 if (!recursive_action(module_dir, ACTION_RECURSE, 4070 check_module_name_match, 0, m_fullName, 0) 4071 ) { 4129 4072 if (m_filename == 0 4130 || ((fp = fopen(m_filename, "r")) == NULL))4131 {4073 || ((fp = fopen(m_filename, "r")) == NULL) 4074 ) { 4132 4075 bb_error_msg("%s: no module by that name found", m_fullName); 4133 4076 goto out; … … 4137 4080 } 4138 4081 } else 4139 m_filename = bb_xstrdup(argv[optind]);4082 m_filename = xstrdup(arg1); 4140 4083 4141 4084 if (flag_verbose) 4142 4085 printf("Using %s\n", m_filename); 4143 4086 4144 #if def CONFIG_FEATURE_2_6_MODULES4145 if (k_version > 4) 4146 {4087 #if ENABLE_FEATURE_2_6_MODULES 4088 if (k_version > 4) { 4089 argv[optind] = m_filename; 4147 4090 optind--; 4148 argv[optind + 1] = m_filename;4149 4091 return insmod_ng_main(argc - optind, argv + optind); 4150 4092 } 4151 4093 #endif 4152 4094 4153 if ((f = obj_load(fp, LOADBITS)) == NULL) 4154 bb_perror_msg_and_die("Could not load the module"); 4095 f = obj_load(fp, LOADBITS); 4096 if (f == NULL) 4097 bb_perror_msg_and_die("cannot load the module"); 4155 4098 4156 4099 if (get_modinfo_value(f, "kernel_version") == NULL) … … 4159 4102 m_has_modinfo = 1; 4160 4103 4161 #if def CONFIG_FEATURE_INSMOD_VERSION_CHECKING4104 #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 4162 4105 /* Version correspondence? */ 4163 4106 if (!flag_quiet) { … … 4167 4110 m_version = new_get_module_version(f, m_strversion); 4168 4111 if (m_version == -1) { 4169 bb_error_msg("c ouldn't find the kernel version the module was "4112 bb_error_msg("cannot find the kernel version the module was " 4170 4113 "compiled for"); 4171 4114 goto out; … … 4174 4117 4175 4118 if (strncmp(uts_info.release, m_strversion, STRVERSIONLEN) != 0) { 4176 if (flag_force_load) { 4177 bb_error_msg("Warning: kernel-module version mismatch\n" 4178 "\t%s was compiled for kernel version %s\n" 4179 "\twhile this kernel is version %s", 4180 m_filename, m_strversion, uts_info.release); 4181 } else { 4182 bb_error_msg("kernel-module version mismatch\n" 4183 "\t%s was compiled for kernel version %s\n" 4184 "\twhile this kernel is version %s.", 4185 m_filename, m_strversion, uts_info.release); 4119 bb_error_msg("%skernel-module version mismatch\n" 4120 "\t%s was compiled for kernel version %s\n" 4121 "\twhile this kernel is version %s", 4122 flag_force_load ? "warning: " : "", 4123 m_filename, m_strversion, uts_info.release); 4124 if (!flag_force_load) 4186 4125 goto out; 4187 }4188 4126 } 4189 4127 } 4190 4128 k_crcs = 0; 4191 #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */4129 #endif /* FEATURE_INSMOD_VERSION_CHECKING */ 4192 4130 4193 4131 if (!query_module(NULL, 0, NULL, 0, NULL)) { … … 4196 4134 k_crcs = new_is_kernel_checksummed(); 4197 4135 } else { 4198 bb_error_msg(" Not configured to support old kernels");4136 bb_error_msg("not configured to support old kernels"); 4199 4137 goto out; 4200 4138 } 4201 4139 4202 #if def CONFIG_FEATURE_INSMOD_VERSION_CHECKING4140 #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 4203 4141 m_crcs = 0; 4204 4142 if (m_has_modinfo) … … 4207 4145 if (m_crcs != k_crcs) 4208 4146 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash); 4209 #endif /* CONFIG_FEATURE_INSMOD_VERSION_CHECKING */4147 #endif /* FEATURE_INSMOD_VERSION_CHECKING */ 4210 4148 4211 4149 /* Let the module know about the kernel symbols. */ … … 4214 4152 /* Allocate common symbols, symbol tables, and string tables. */ 4215 4153 4216 if (!new_create_this_module(f, m_name)) 4217 { 4154 if (!new_create_this_module(f, m_name)) { 4218 4155 goto out; 4219 4156 } … … 4227 4164 /* done with the module name, on to the optional var=value arguments */ 4228 4165 ++optind; 4229 4230 4166 if (optind < argc) { 4231 if (!new_process_module_arguments(f, argc - optind, argv + optind)) 4232 { 4167 if (!new_process_module_arguments(f, argc - optind, argv + optind)) { 4233 4168 goto out; 4234 4169 } … … 4238 4173 hide_special_symbols(f); 4239 4174 4240 #if def CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS4175 #if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS 4241 4176 add_ksymoops_symbols(f, m_filename, m_name); 4242 #endif /* CONFIG_FEATURE_INSMOD_KSYMOOPS_SYMBOLS */4177 #endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */ 4243 4178 4244 4179 new_create_module_ksymtab(f); … … 4251 4186 if (m_addr == -1) switch (errno) { 4252 4187 case EEXIST: 4253 bb_error_msg(" Amodule named %s already exists", m_name);4188 bb_error_msg("a module named %s already exists", m_name); 4254 4189 goto out; 4255 4190 case ENOMEM: 4256 bb_error_msg(" Can't allocate kernel memory for module; needed %lu bytes",4191 bb_error_msg("can't allocate kernel memory for module; needed %lu bytes", 4257 4192 m_size); 4258 4193 goto out; … … 4278 4213 } 4279 4214 4280 if (!new_init_module(m_name, f, m_size)) 4281 { 4215 if (!new_init_module(m_name, f, m_size)) { 4282 4216 delete_module(m_name); 4283 4217 goto out; 4284 4218 } 4285 4219 4286 #ifdef CONFIG_FEATURE_INSMOD_LOAD_MAP 4287 if(flag_print_load_map) 4220 if (flag_print_load_map) 4288 4221 print_load_map(f); 4289 #endif4290 4222 4291 4223 exit_status = EXIT_SUCCESS; 4292 4224 4293 4225 out: 4294 #if def CONFIG_FEATURE_CLEAN_UP4295 if (fp)4226 #if ENABLE_FEATURE_CLEAN_UP 4227 if (fp) 4296 4228 fclose(fp); 4297 4229 free(tmp1); 4298 if (!tmp1) {4230 if (!tmp1) 4299 4231 free(m_name); 4300 }4301 4232 free(m_filename); 4302 4233 #endif 4303 return (exit_status);4304 } 4305 4306 4307 #endif 4308 4309 4310 #if def CONFIG_FEATURE_2_6_MODULES4234 return exit_status; 4235 } 4236 4237 4238 #endif 4239 4240 4241 #if ENABLE_FEATURE_2_6_MODULES 4311 4242 4312 4243 #include <sys/mman.h> … … 4318 4249 { 4319 4250 switch (err) { 4320 case ENOEXEC: 4321 return "Invalid module format"; 4322 case ENOENT: 4323 return "Unknown symbol in module"; 4324 case ESRCH: 4325 return "Module has wrong symbol version"; 4326 case EINVAL: 4327 return "Invalid parameters"; 4328 default: 4329 return strerror(err); 4330 } 4331 } 4332 4333 int insmod_ng_main( int argc, char **argv) 4334 { 4335 int i; 4251 case ENOEXEC: 4252 return "Invalid module format"; 4253 case ENOENT: 4254 return "Unknown symbol in module"; 4255 case ESRCH: 4256 return "Module has wrong symbol version"; 4257 case EINVAL: 4258 return "Invalid parameters"; 4259 default: 4260 return strerror(err); 4261 } 4262 } 4263 4264 int insmod_ng_main(int argc, char **argv); 4265 int insmod_ng_main(int argc, char **argv) 4266 { 4267 long ret; 4268 size_t len; 4269 int optlen; 4270 void *map; 4271 char *filename, *options; 4272 4273 filename = *++argv; 4274 if (!filename) 4275 bb_show_usage(); 4276 4277 /* Rest is options */ 4278 options = xzalloc(1); 4279 optlen = 0; 4280 while (*++argv) { 4281 options = xrealloc(options, optlen + 2 + strlen(*argv) + 2); 4282 /* Spaces handled by "" pairs, but no way of escaping quotes */ 4283 optlen += sprintf(options + optlen, (strchr(*argv,' ') ? "\"%s\" " : "%s "), *argv); 4284 } 4285 4286 #if 0 4287 /* Any special reason why mmap? It isn't performace critical... */ 4336 4288 int fd; 4337 long int ret;4338 4289 struct stat st; 4339 4290 unsigned long len; 4340 void *map; 4341 char *filename, *options = bb_xstrdup(""); 4342 4343 filename = argv[1]; 4344 if (!filename) { 4345 bb_show_usage(); 4346 return -1; 4347 } 4348 4349 /* Rest is options */ 4350 for (i = 2; i < argc; i++) { 4351 options = xrealloc(options, strlen(options) + 2 + strlen(argv[i]) + 2); 4352 /* Spaces handled by "" pairs, but no way of escaping quotes */ 4353 if (strchr(argv[i], ' ')) { 4354 strcat(options, "\""); 4355 strcat(options, argv[i]); 4356 strcat(options, "\""); 4357 } else { 4358 strcat(options, argv[i]); 4359 } 4360 strcat(options, " "); 4361 } 4362 4363 fd = bb_xopen3(filename, O_RDONLY, 0); 4364 4291 fd = xopen(filename, O_RDONLY); 4365 4292 fstat(fd, &st); 4366 4293 len = st.st_size; 4367 4294 map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); 4368 4295 if (map == MAP_FAILED) { 4369 bb_perror_msg_and_die("cannot mmap `%s'", filename); 4370 } 4296 bb_perror_msg_and_die("cannot mmap '%s'", filename); 4297 } 4298 4299 /* map == NULL on Blackfin, probably on other MMU-less systems too. Workaround. */ 4300 if (map == NULL) { 4301 map = xmalloc(len); 4302 xread(fd, map, len); 4303 } 4304 #else 4305 len = MAXINT(ssize_t); 4306 map = xmalloc_open_read_close(filename, &len); 4307 #endif 4371 4308 4372 4309 ret = syscall(__NR_init_module, map, len, options); 4373 4310 if (ret != 0) { 4374 bb_perror_msg_and_die("cannot insert `%s': %s (%li)",4311 bb_perror_msg_and_die("cannot insert '%s': %s (%li)", 4375 4312 filename, moderror(errno), ret); 4376 4313 }
Note:
See TracChangeset
for help on using the changeset viewer.