Changeset 2725 in MondoRescue for branches/2.2.9/mindi-busybox/modutils
- Timestamp:
- Feb 25, 2011, 9:26:54 PM (13 years ago)
- Location:
- branches/2.2.9/mindi-busybox/modutils
- Files:
-
- 9 added
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
branches/2.2.9/mindi-busybox/modutils/Config.in
r1765 r2725 1 # DO NOT EDIT. This file is generated from Config.src 1 2 # 2 3 # For a description of the syntax of this configuration file, … … 5 6 6 7 menu "Linux Module Utilities" 8 depends on PLATFORM_LINUX 9 10 config MODINFO 11 bool "modinfo" 12 default y 13 help 14 Show information about a Linux Kernel module 15 16 config MODPROBE_SMALL 17 bool "Simplified modutils" 18 default y 19 help 20 Simplified modutils. 21 22 With this option modprobe does not require modules.dep file 23 and does not use /etc/modules.conf file. 24 It scans module files in /lib/modules/`uname -r` and 25 determines dependencies and module alias names on the fly. 26 This may make module loading slower, most notably 27 when one needs to load module by alias (this requires 28 scanning through module _bodies_). 29 30 At the first attempt to load a module by alias modprobe 31 will try to generate modules.dep.bb file in order to speed up 32 future loads by alias. Failure to do so (read-only /lib/modules, 33 etc) is not reported, and future modprobes will be slow too. 34 35 NB: modules.dep.bb file format is not compatible 36 with modules.dep file as created/used by standard module tools. 37 38 Additional module parameters can be stored in 39 /etc/modules/$module_name files. 40 41 Apart from modprobe, other utilities are also provided: 42 - insmod is an alias to modprobe 43 - rmmod is an alias to modprobe -r 44 - depmod generates modules.dep.bb 45 46 As of 2008-07, this code is experimental. It is 14kb smaller 47 than "non-small" modutils. 48 49 config FEATURE_MODPROBE_SMALL_OPTIONS_ON_CMDLINE 50 bool "Accept module options on modprobe command line" 51 default y 52 depends on MODPROBE_SMALL 53 help 54 Allow insmod and modprobe take module options from command line. 55 56 config FEATURE_MODPROBE_SMALL_CHECK_ALREADY_LOADED 57 bool "Skip loading of already loaded modules" 58 default y 59 depends on MODPROBE_SMALL 60 help 61 Check if the module is already loaded. 7 62 8 63 config INSMOD 9 64 bool "insmod" 10 65 default n 66 depends on !MODPROBE_SMALL 11 67 help 12 68 insmod is used to load specified modules in the running kernel. 13 69 70 config RMMOD 71 bool "rmmod" 72 default n 73 depends on !MODPROBE_SMALL 74 help 75 rmmod is used to unload specified modules from the kernel. 76 77 config LSMOD 78 bool "lsmod" 79 default n 80 depends on !MODPROBE_SMALL 81 help 82 lsmod is used to display a list of loaded modules. 83 84 config FEATURE_LSMOD_PRETTY_2_6_OUTPUT 85 bool "Pretty output" 86 default n 87 depends on LSMOD 88 help 89 This option makes output format of lsmod adjusted to 90 the format of module-init-tools for Linux kernel 2.6. 91 Increases size somewhat. 92 93 config MODPROBE 94 bool "modprobe" 95 default n 96 depends on !MODPROBE_SMALL 97 help 98 Handle the loading of modules, and their dependencies on a high 99 level. 100 101 config FEATURE_MODPROBE_BLACKLIST 102 bool "Blacklist support" 103 default n 104 depends on MODPROBE 105 help 106 Say 'y' here to enable support for the 'blacklist' command in 107 modprobe.conf. This prevents the alias resolver to resolve 108 blacklisted modules. This is useful if you want to prevent your 109 hardware autodetection scripts to load modules like evdev, frame 110 buffer drivers etc. 111 112 config DEPMOD 113 bool "depmod" 114 default n 115 depends on !MODPROBE_SMALL 116 help 117 depmod generates modules.dep (and potentially modules.alias 118 and modules.symbols) that contain dependency information 119 for modprobe. 120 121 comment "Options common to multiple modutils" 122 123 config FEATURE_2_4_MODULES 124 bool "Support version 2.2/2.4 Linux kernels" 125 default n 126 depends on INSMOD || RMMOD || LSMOD 127 help 128 Support module loading for 2.2.x and 2.4.x Linux kernels. 129 This increases size considerably. Say N unless you plan 130 to run ancient kernels. 131 132 config FEATURE_INSMOD_TRY_MMAP 133 bool "Try to load module from a mmap'ed area" 134 default n 135 depends on INSMOD || MODPROBE_SMALL 136 help 137 This option causes module loading code to try to mmap 138 module first. If it does not work (for example, 139 it does not work for compressed modules), module will be read 140 (and unpacked if needed) into a memory block allocated by malloc. 141 142 The only case when mmap works but malloc does not is when 143 you are trying to load a big module on a very memory-constrained 144 machine. Malloc will momentarily need 2x as much memory as mmap. 145 146 Choosing N saves about 250 bytes of code (on 32-bit x86). 147 14 148 config FEATURE_INSMOD_VERSION_CHECKING 15 bool " Module version checking"16 default n 17 depends on INSMOD && FEATURE_2_4_MODULES18 help 19 Support checking of versions for modules. 149 bool "Enable module version checking" 150 default n 151 depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) 152 help 153 Support checking of versions for modules. This is used to 20 154 ensure that the kernel and module are made for each other. 21 155 … … 23 157 bool "Add module symbols to kernel symbol table" 24 158 default n 25 depends on INSMOD && FEATURE_2_4_MODULES159 depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) 26 160 help 27 161 By adding module symbols to the kernel symbol table, Oops messages 28 occuring within kernel modules can be properly debugged. 162 occuring within kernel modules can be properly debugged. By enabling 29 163 this feature, module symbols will always be added to the kernel symbol 30 table for proper ly debugging support.If you are not interested in164 table for proper debugging support. If you are not interested in 31 165 Oops messages from kernel modules, say N. 32 166 … … 34 168 bool "In kernel memory optimization (uClinux only)" 35 169 default n 36 depends on INSMOD && FEATURE_2_4_MODULES170 depends on FEATURE_2_4_MODULES && (INSMOD || MODPROBE) 37 171 help 38 172 This is a special uClinux only memory optimization that lets insmod … … 42 176 43 177 config FEATURE_INSMOD_LOAD_MAP 44 bool "Enable load map (-m) option"45 default n 46 depends on INSMOD && ( FEATURE_2_4_MODULES || FEATURE_2_6_MODULES )178 bool "Enable insmod load map (-m) option" 179 default n 180 depends on FEATURE_2_4_MODULES && INSMOD 47 181 help 48 182 Enabling this, one would be able to get a load map … … 55 189 bool "Symbols in load map" 56 190 default y 57 depends on FEATURE_INSMOD_LOAD_MAP 191 depends on FEATURE_INSMOD_LOAD_MAP && !MODPROBE_SMALL 58 192 help 59 193 Without this option, -m will only output section 60 load map. 194 load map. With this option, -m will also output 61 195 symbols load map. 62 196 63 config RMMOD64 bool "rmmod"65 default n66 help67 rmmod is used to unload specified modules from the kernel.68 69 config LSMOD70 bool "lsmod"71 default n72 help73 lsmod is used to display a list of loaded modules.74 75 config FEATURE_LSMOD_PRETTY_2_6_OUTPUT76 bool "lsmod pretty output for 2.6.x Linux kernels "77 default n78 depends on LSMOD79 help80 This option makes output format of lsmod adjusted to81 the format of module-init-tools for Linux kernel 2.6.82 83 config MODPROBE84 bool "modprobe"85 default n86 help87 Handle the loading of modules, and their dependencies on a high88 level.89 90 Note that in the state, modprobe does not understand multiple91 module options from the configuration file. See option below.92 93 config FEATURE_MODPROBE_MULTIPLE_OPTIONS94 bool95 prompt "Multiple options parsing" if NITPICK96 default y97 depends on MODPROBE98 help99 Allow modprobe to understand more than one option to pass to100 modules.101 102 This is a WIP, while waiting for a common argument parsing103 common amongst all BB applets (shell, modprobe, etc...) and104 adds around 600 bytes on x86, 700 bytes on ARM. The code is105 biggish and uggly, but just works.106 107 Saying Y here is not a bad idea if you're not that short108 on storage capacity.109 110 config FEATURE_MODPROBE_FANCY_ALIAS111 bool112 prompt "Fancy alias parsing" if NITPICK113 default y114 depends on MODPROBE && FEATURE_2_6_MODULES115 help116 Say 'y' here to enable parsing of aliases with underscore/dash117 mismatch between module name and file name, along with bus-specific118 aliases (such as pci:... or usb:... aliases).119 120 comment "Options common to multiple modutils"121 depends on INSMOD || RMMOD || MODPROBE || LSMOD122 123 197 config FEATURE_CHECK_TAINTED_MODULE 124 # Simulate indentation125 198 bool "Support tainted module checking with new kernels" 126 199 default y 127 depends on INSMOD || LSMOD128 help 129 Support checking for tainted modules. 200 depends on (LSMOD || FEATURE_2_4_MODULES) && !MODPROBE_SMALL 201 help 202 Support checking for tainted modules. These are usually binary 130 203 only modules that will make the linux-kernel list ignore your 131 204 support request. 132 205 This option is required to support GPLONLY modules. 133 206 134 config FEATURE_2_4_MODULES 135 # Simulate indentation 136 bool "Support version 2.2.x to 2.4.x Linux kernels" 137 default y 138 depends on INSMOD || RMMOD || MODPROBE 139 help 140 Support module loading for 2.2.x and 2.4.x Linux kernels. 141 142 config FEATURE_2_6_MODULES 143 # Simulate indentation 144 bool "Support version 2.6.x Linux kernels" 145 default y 146 depends on INSMOD || RMMOD || MODPROBE 147 help 148 Support module loading for newer 2.6.x Linux kernels. 149 150 151 config FEATURE_QUERY_MODULE_INTERFACE 152 bool 153 default y 154 depends on FEATURE_2_4_MODULES && !FEATURE_2_6_MODULES 155 207 config FEATURE_MODUTILS_ALIAS 208 bool "Support for module.aliases file" 209 default y 210 depends on DEPMOD || MODPROBE 211 help 212 Generate and parse modules.alias containing aliases for bus 213 identifiers: 214 alias pcmcia:m*c*f03fn*pfn*pa*pb*pc*pd* parport_cs 215 216 and aliases for logical modules names e.g.: 217 alias padlock_aes aes 218 alias aes_i586 aes 219 alias aes_generic aes 220 221 Say Y if unsure. 222 223 config FEATURE_MODUTILS_SYMBOLS 224 bool "Support for module.symbols file" 225 default y 226 depends on DEPMOD || MODPROBE 227 help 228 Generate and parse modules.symbols containing aliases for 229 symbol_request() kernel calls, such as: 230 alias symbol:usb_sg_init usbcore 231 232 Say Y if unsure. 233 234 config DEFAULT_MODULES_DIR 235 string "Default directory containing modules" 236 default "/lib/modules" 237 depends on DEPMOD || MODPROBE || MODPROBE_SMALL || MODINFO 238 help 239 Directory that contains kernel modules. 240 Defaults to "/lib/modules" 241 242 config DEFAULT_DEPMOD_FILE 243 string "Default name of modules.dep" 244 default "modules.dep" 245 depends on DEPMOD || MODPROBE || MODPROBE_SMALL || MODINFO 246 help 247 Filename that contains kernel modules dependencies. 248 Defaults to "modules.dep" 156 249 157 250 endmenu 158 -
branches/2.2.9/mindi-busybox/modutils/Kbuild
r1765 r2725 1 # DO NOT EDIT. This file is generated from Kbuild.src 1 2 # Makefile for busybox 2 3 # 3 4 # Copyright (C) 1999-2005 by Erik Andersen <andersen@codepoet.org> 4 5 # 5 # Licensed under the GPL v2, see the file LICENSE in this tarball.6 # Licensed under GPLv2, see file LICENSE in this source tree. 6 7 7 8 lib-y:= 8 lib-$(CONFIG_INSMOD) += insmod.o 9 lib-$(CONFIG_LSMOD) += lsmod.o 10 lib-$(CONFIG_MODPROBE) += modprobe.o 11 lib-$(CONFIG_RMMOD) += rmmod.o 9 10 lib-$(CONFIG_MODINFO) += modinfo.o modutils.o 11 lib-$(CONFIG_MODPROBE_SMALL) += modprobe-small.o 12 lib-$(CONFIG_DEPMOD) += depmod.o modutils.o 13 lib-$(CONFIG_INSMOD) += insmod.o modutils.o 14 lib-$(CONFIG_LSMOD) += lsmod.o modutils.o 15 lib-$(CONFIG_MODPROBE) += modprobe.o modutils.o 16 lib-$(CONFIG_RMMOD) += rmmod.o modutils.o 17 lib-$(CONFIG_FEATURE_2_4_MODULES) += modutils-24.o -
branches/2.2.9/mindi-busybox/modutils/insmod.c
r1765 r2725 3 3 * Mini insmod implementation for busybox 4 4 * 5 * This version of insmod supports ARM, CRIS, H8/300, x86, ia64, x86_64, 6 * m68k, MIPS, PowerPC, S390, SH3/4/5, Sparc, v850e, and x86_64. 5 * Copyright (C) 2008 Timo Teras <timo.teras@iki.fi> 7 6 * 8 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 9 * and Ron Alder <alder@lineo.com> 10 * 11 * Rodney Radford <rradford@mindspring.com> 17-Aug-2004. 12 * Added x86_64 support. 13 * 14 * Miles Bader <miles@gnu.org> added NEC V850E support. 15 * 16 * Modified by Bryan Rittmeyer <bryan@ixiacom.com> to support SH4 17 * and (theoretically) SH3. I have only tested SH4 in little endian mode. 18 * 19 * Modified by Alcove, Julien Gaulmin <julien.gaulmin@alcove.fr> and 20 * Nicolas Ferre <nicolas.ferre@alcove.fr> to support ARM7TDMI. Only 21 * very minor changes required to also work with StrongArm and presumably 22 * all ARM based systems. 23 * 24 * Yoshinori Sato <ysato@users.sourceforge.jp> 19-May-2004. 25 * added Renesas H8/300 support. 26 * 27 * Paul Mundt <lethal@linux-sh.org> 08-Aug-2003. 28 * Integrated support for sh64 (SH-5), from preliminary modutils 29 * patches from Benedict Gaster <benedict.gaster@superh.com>. 30 * Currently limited to support for 32bit ABI. 31 * 32 * Magnus Damm <damm@opensource.se> 22-May-2002. 33 * The plt and got code are now using the same structs. 34 * Added generic linked list code to fully support PowerPC. 35 * Replaced the mess in arch_apply_relocation() with architecture blocks. 36 * The arch_create_got() function got cleaned up with architecture blocks. 37 * These blocks should be easy maintain and sync with obj_xxx.c in modutils. 38 * 39 * Magnus Damm <damm@opensource.se> added PowerPC support 20-Feb-2001. 40 * PowerPC specific code stolen from modutils-2.3.16, 41 * written by Paul Mackerras, Copyright 1996, 1997 Linux International. 42 * I've only tested the code on mpc8xx platforms in big-endian mode. 43 * Did some cleanup and added USE_xxx_ENTRIES... 44 * 45 * Quinn Jensen <jensenq@lineo.com> added MIPS support 23-Feb-2001. 46 * based on modutils-2.4.2 47 * MIPS specific support for Elf loading and relocation. 48 * Copyright 1996, 1997 Linux International. 49 * Contributed by Ralf Baechle <ralf@gnu.ai.mit.edu> 50 * 51 * Based almost entirely on the Linux modutils-2.3.11 implementation. 52 * Copyright 1996, 1997 Linux International. 53 * New implementation contributed by Richard Henderson <rth@tamu.edu> 54 * Based on original work by Bjorn Ekwall <bj0rn@blox.se> 55 * Restructured (and partly rewritten) by: 56 * Björn Ekwall <bj0rn@blox.se> February 1999 57 * 58 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 7 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 59 8 */ 60 9 10 //applet:IF_INSMOD(APPLET(insmod, _BB_DIR_SBIN, _BB_SUID_DROP)) 11 61 12 #include "libbb.h" 62 #include <libgen.h> 63 #include <sys/utsname.h> 13 #include "modutils.h" 64 14 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 15 /* 2.6 style insmod has no options and required filename 16 * (not module name - .ko can't be omitted) */ 69 17 70 #if !ENABLE_FEATURE_2_4_MODULES 71 #define insmod_ng_main insmod_main 72 #endif 18 //usage:#if !ENABLE_MODPROBE_SMALL 19 //usage:#define insmod_trivial_usage 20 //usage: IF_FEATURE_2_4_MODULES("[OPTIONS] MODULE ") 21 //usage: IF_NOT_FEATURE_2_4_MODULES("FILE ") 22 //usage: "[SYMBOL=VALUE]..." 23 //usage:#define insmod_full_usage "\n\n" 24 //usage: "Load the specified kernel modules into the kernel" 25 //usage: IF_FEATURE_2_4_MODULES( "\n" 26 //usage: "\nOptions:" 27 //usage: "\n -f Force module to load into the wrong kernel version" 28 //usage: "\n -k Make module autoclean-able" 29 //usage: "\n -v Verbose" 30 //usage: "\n -q Quiet" 31 //usage: "\n -L Lock: prevent simultaneous loads" 32 //usage: IF_FEATURE_INSMOD_LOAD_MAP( 33 //usage: "\n -m Output load map to stdout" 34 //usage: ) 35 //usage: "\n -x Don't export externs" 36 //usage: ) 37 //usage:#endif 73 38 74 #if ENABLE_FEATURE_2_6_MODULES 75 extern int insmod_ng_main( int argc, char **argv); 76 #endif 39 int insmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 40 int insmod_main(int argc UNUSED_PARAM, char **argv) 41 { 42 char *filename; 43 int rc; 77 44 45 /* Compat note: 46 * 2.6 style insmod has no options and required filename 47 * (not module name - .ko can't be omitted). 48 * 2.4 style insmod can take module name without .o 49 * and performs module search in default directories 50 * or in $MODPATH. 51 */ 78 52 79 #if ENABLE_FEATURE_2_4_MODULES 80 81 82 #if ENABLE_FEATURE_INSMOD_LOADINKMEM 83 #define LOADBITS 0 84 #else 85 #define LOADBITS 1 86 #endif 87 88 89 /* Alpha */ 90 #if defined(__alpha__) 91 #define MATCH_MACHINE(x) (x == EM_ALPHA) 92 #define SHT_RELM SHT_RELA 93 #define Elf64_RelM Elf64_Rela 94 #define ELFCLASSM ELFCLASS64 95 #endif 96 97 /* ARM support */ 98 #if defined(__arm__) 99 #define MATCH_MACHINE(x) (x == EM_ARM) 100 #define SHT_RELM SHT_REL 101 #define Elf32_RelM Elf32_Rel 102 #define ELFCLASSM ELFCLASS32 103 #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 108 #endif 109 110 /* blackfin */ 111 #if defined(BFIN) 112 #define MATCH_MACHINE(x) (x == EM_BLACKFIN) 113 #define SHT_RELM SHT_RELA 114 #define Elf32_RelM Elf32_Rela 115 #define ELFCLASSM ELFCLASS32 116 #endif 117 118 /* CRIS */ 119 #if defined(__cris__) 120 #define MATCH_MACHINE(x) (x == EM_CRIS) 121 #define SHT_RELM SHT_RELA 122 #define Elf32_RelM Elf32_Rela 123 #define ELFCLASSM ELFCLASS32 124 #ifndef EM_CRIS 125 #define EM_CRIS 76 126 #define R_CRIS_NONE 0 127 #define R_CRIS_32 3 128 #endif 129 #endif 130 131 /* H8/300 */ 132 #if defined(__H8300H__) || defined(__H8300S__) 133 #define MATCH_MACHINE(x) (x == EM_H8_300) 134 #define SHT_RELM SHT_RELA 135 #define Elf32_RelM Elf32_Rela 136 #define ELFCLASSM ELFCLASS32 137 #define USE_SINGLE 138 #define SYMBOL_PREFIX "_" 139 #endif 140 141 /* PA-RISC / HP-PA */ 142 #if defined(__hppa__) 143 #define MATCH_MACHINE(x) (x == EM_PARISC) 144 #define SHT_RELM SHT_RELA 145 #if defined(__LP64__) 146 #define Elf64_RelM Elf64_Rela 147 #define ELFCLASSM ELFCLASS64 148 #else 149 #define Elf32_RelM Elf32_Rela 150 #define ELFCLASSM ELFCLASS32 151 #endif 152 #endif 153 154 /* x86 */ 155 #if defined(__i386__) 156 #ifndef EM_486 157 #define MATCH_MACHINE(x) (x == EM_386) 158 #else 159 #define MATCH_MACHINE(x) (x == EM_386 || x == EM_486) 160 #endif 161 #define SHT_RELM SHT_REL 162 #define Elf32_RelM Elf32_Rel 163 #define ELFCLASSM ELFCLASS32 164 #define USE_GOT_ENTRIES 165 #define GOT_ENTRY_SIZE 4 166 #define USE_SINGLE 167 #endif 168 169 /* IA64, aka Itanium */ 170 #if defined(__ia64__) 171 #define MATCH_MACHINE(x) (x == EM_IA_64) 172 #define SHT_RELM SHT_RELA 173 #define Elf64_RelM Elf64_Rela 174 #define ELFCLASSM ELFCLASS64 175 #endif 176 177 /* m68k */ 178 #if defined(__mc68000__) 179 #define MATCH_MACHINE(x) (x == EM_68K) 180 #define SHT_RELM SHT_RELA 181 #define Elf32_RelM Elf32_Rela 182 #define ELFCLASSM ELFCLASS32 183 #define USE_GOT_ENTRIES 184 #define GOT_ENTRY_SIZE 4 185 #define USE_SINGLE 186 #endif 187 188 /* Microblaze */ 189 #if defined(__microblaze__) 190 #define USE_SINGLE 191 #define MATCH_MACHINE(x) (x == EM_XILINX_MICROBLAZE) 192 #define SHT_RELM SHT_RELA 193 #define Elf32_RelM Elf32_Rela 194 #define ELFCLASSM ELFCLASS32 195 #endif 196 197 /* MIPS */ 198 #if defined(__mips__) 199 #define MATCH_MACHINE(x) (x == EM_MIPS || x == EM_MIPS_RS3_LE) 200 #define SHT_RELM SHT_REL 201 #define Elf32_RelM Elf32_Rel 202 #define ELFCLASSM ELFCLASS32 203 /* Account for ELF spec changes. */ 204 #ifndef EM_MIPS_RS3_LE 205 #ifdef EM_MIPS_RS4_BE 206 #define EM_MIPS_RS3_LE EM_MIPS_RS4_BE 207 #else 208 #define EM_MIPS_RS3_LE 10 209 #endif 210 #endif /* !EM_MIPS_RS3_LE */ 211 #define ARCHDATAM "__dbe_table" 212 #endif 213 214 /* Nios II */ 215 #if defined(__nios2__) 216 #define MATCH_MACHINE(x) (x == EM_ALTERA_NIOS2) 217 #define SHT_RELM SHT_RELA 218 #define Elf32_RelM Elf32_Rela 219 #define ELFCLASSM ELFCLASS32 220 #endif 221 222 /* PowerPC */ 223 #if defined(__powerpc64__) 224 #define MATCH_MACHINE(x) (x == EM_PPC64) 225 #define SHT_RELM SHT_RELA 226 #define Elf64_RelM Elf64_Rela 227 #define ELFCLASSM ELFCLASS64 228 #elif defined(__powerpc__) 229 #define MATCH_MACHINE(x) (x == EM_PPC) 230 #define SHT_RELM SHT_RELA 231 #define Elf32_RelM Elf32_Rela 232 #define ELFCLASSM ELFCLASS32 233 #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 238 #define ARCHDATAM "__ftr_fixup" 239 #endif 240 241 /* S390 */ 242 #if defined(__s390__) 243 #define MATCH_MACHINE(x) (x == EM_S390) 244 #define SHT_RELM SHT_RELA 245 #define Elf32_RelM Elf32_Rela 246 #define ELFCLASSM ELFCLASS32 247 #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 252 #endif 253 254 /* SuperH */ 255 #if defined(__sh__) 256 #define MATCH_MACHINE(x) (x == EM_SH) 257 #define SHT_RELM SHT_RELA 258 #define Elf32_RelM Elf32_Rela 259 #define ELFCLASSM ELFCLASS32 260 #define USE_GOT_ENTRIES 261 #define GOT_ENTRY_SIZE 4 262 #define USE_SINGLE 263 /* the SH changes have only been tested in =little endian= mode */ 264 /* I'm not sure about big endian, so let's warn: */ 265 #if defined(__sh__) && BB_BIG_ENDIAN 266 # error insmod.c may require changes for use on big endian SH 267 #endif 268 /* it may or may not work on the SH1/SH2... Error on those also */ 269 #if ((!(defined(__SH3__) || defined(__SH4__) || defined(__SH5__)))) && (defined(__sh__)) 270 #error insmod.c may require changes for SH1 or SH2 use 271 #endif 272 #endif 273 274 /* Sparc */ 275 #if defined(__sparc__) 276 #define MATCH_MACHINE(x) (x == EM_SPARC) 277 #define SHT_RELM SHT_RELA 278 #define Elf32_RelM Elf32_Rela 279 #define ELFCLASSM ELFCLASS32 280 #endif 281 282 /* v850e */ 283 #if defined(__v850e__) 284 #define MATCH_MACHINE(x) ((x) == EM_V850 || (x) == EM_CYGNUS_V850) 285 #define SHT_RELM SHT_RELA 286 #define Elf32_RelM Elf32_Rela 287 #define ELFCLASSM ELFCLASS32 288 #define USE_PLT_ENTRIES 289 #define PLT_ENTRY_SIZE 8 290 #define USE_SINGLE 291 #ifndef EM_CYGNUS_V850 /* grumble */ 292 #define EM_CYGNUS_V850 0x9080 293 #endif 294 #define SYMBOL_PREFIX "_" 295 #endif 296 297 /* X86_64 */ 298 #if defined(__x86_64__) 299 #define MATCH_MACHINE(x) (x == EM_X86_64) 300 #define SHT_RELM SHT_RELA 301 #define USE_GOT_ENTRIES 302 #define GOT_ENTRY_SIZE 8 303 #define USE_SINGLE 304 #define Elf64_RelM Elf64_Rela 305 #define ELFCLASSM ELFCLASS64 306 #endif 307 308 #ifndef SHT_RELM 309 #error Sorry, but insmod.c does not yet support this architecture... 310 #endif 311 312 313 //---------------------------------------------------------------------------- 314 //--------modutils module.h, lines 45-242 315 //---------------------------------------------------------------------------- 316 317 /* Definitions for the Linux module syscall interface. 318 Copyright 1996, 1997 Linux International. 319 320 Contributed by Richard Henderson <rth@tamu.edu> 321 322 This file is part of the Linux modutils. 323 324 This program is free software; you can redistribute it and/or modify it 325 under the terms of the GNU General Public License as published by the 326 Free Software Foundation; either version 2 of the License, or (at your 327 option) any later version. 328 329 This program is distributed in the hope that it will be useful, but 330 WITHOUT ANY WARRANTY; without even the implied warranty of 331 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 332 General Public License for more details. 333 334 You should have received a copy of the GNU General Public License 335 along with this program; if not, write to the Free Software Foundation, 336 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 337 338 339 #ifndef MODUTILS_MODULE_H 340 341 /*======================================================================*/ 342 /* For sizeof() which are related to the module platform and not to the 343 environment isnmod is running in, use sizeof_xx instead of sizeof(xx). */ 344 345 #define tgt_sizeof_char sizeof(char) 346 #define tgt_sizeof_short sizeof(short) 347 #define tgt_sizeof_int sizeof(int) 348 #define tgt_sizeof_long sizeof(long) 349 #define tgt_sizeof_char_p sizeof(char *) 350 #define tgt_sizeof_void_p sizeof(void *) 351 #define tgt_long long 352 353 #if defined(__sparc__) && !defined(__sparc_v9__) && defined(ARCH_sparc64) 354 #undef tgt_sizeof_long 355 #undef tgt_sizeof_char_p 356 #undef tgt_sizeof_void_p 357 #undef tgt_long 358 enum { 359 tgt_sizeof_long = 8, 360 tgt_sizeof_char_p = 8, 361 tgt_sizeof_void_p = 8 362 }; 363 #define tgt_long long long 364 #endif 365 366 /*======================================================================*/ 367 /* The structures used in Linux 2.1. */ 368 369 /* Note: new_module_symbol does not use tgt_long intentionally */ 370 struct new_module_symbol { 371 unsigned long value; 372 unsigned long name; 373 }; 374 375 struct new_module_persist; 376 377 struct new_module_ref { 378 unsigned tgt_long dep; /* kernel addresses */ 379 unsigned tgt_long ref; 380 unsigned tgt_long next_ref; 381 }; 382 383 struct new_module { 384 unsigned tgt_long size_of_struct; /* == sizeof(module) */ 385 unsigned tgt_long next; 386 unsigned tgt_long name; 387 unsigned tgt_long size; 388 389 tgt_long usecount; 390 unsigned tgt_long flags; /* AUTOCLEAN et al */ 391 392 unsigned nsyms; 393 unsigned ndeps; 394 395 unsigned tgt_long syms; 396 unsigned tgt_long deps; 397 unsigned tgt_long refs; 398 unsigned tgt_long init; 399 unsigned tgt_long cleanup; 400 unsigned tgt_long ex_table_start; 401 unsigned tgt_long ex_table_end; 402 #ifdef __alpha__ 403 unsigned tgt_long gp; 404 #endif 405 /* Everything after here is extension. */ 406 unsigned tgt_long persist_start; 407 unsigned tgt_long persist_end; 408 unsigned tgt_long can_unload; 409 unsigned tgt_long runsize; 410 const char *kallsyms_start; /* All symbols for kernel debugging */ 411 const char *kallsyms_end; 412 const char *archdata_start; /* arch specific data for module */ 413 const char *archdata_end; 414 const char *kernel_data; /* Reserved for kernel internal use */ 415 }; 416 417 #ifdef ARCHDATAM 418 #define ARCHDATA_SEC_NAME ARCHDATAM 419 #else 420 #define ARCHDATA_SEC_NAME "__archdata" 421 #endif 422 #define KALLSYMS_SEC_NAME "__kallsyms" 423 424 425 struct new_module_info { 426 unsigned long addr; 427 unsigned long size; 428 unsigned long flags; 429 long usecount; 430 }; 431 432 /* Bits of module.flags. */ 433 enum { 434 NEW_MOD_RUNNING = 1, 435 NEW_MOD_DELETED = 2, 436 NEW_MOD_AUTOCLEAN = 4, 437 NEW_MOD_VISITED = 8, 438 NEW_MOD_USED_ONCE = 16 439 }; 440 441 int init_module(const char *name, const struct new_module *); 442 int query_module(const char *name, int which, void *buf, 443 size_t bufsize, size_t *ret); 444 445 /* Values for query_module's which. */ 446 enum { 447 QM_MODULES = 1, 448 QM_DEPS = 2, 449 QM_REFS = 3, 450 QM_SYMBOLS = 4, 451 QM_INFO = 5 452 }; 453 454 /*======================================================================*/ 455 /* The system calls unchanged between 2.0 and 2.1. */ 456 457 unsigned long create_module(const char *, size_t); 458 int delete_module(const char *); 459 460 461 #endif /* module.h */ 462 463 //---------------------------------------------------------------------------- 464 //--------end of modutils module.h 465 //---------------------------------------------------------------------------- 466 467 468 469 //---------------------------------------------------------------------------- 470 //--------modutils obj.h, lines 253-462 471 //---------------------------------------------------------------------------- 472 473 /* Elf object file loading and relocation routines. 474 Copyright 1996, 1997 Linux International. 475 476 Contributed by Richard Henderson <rth@tamu.edu> 477 478 This file is part of the Linux modutils. 479 480 This program is free software; you can redistribute it and/or modify it 481 under the terms of the GNU General Public License as published by the 482 Free Software Foundation; either version 2 of the License, or (at your 483 option) any later version. 484 485 This program is distributed in the hope that it will be useful, but 486 WITHOUT ANY WARRANTY; without even the implied warranty of 487 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 488 General Public License for more details. 489 490 You should have received a copy of the GNU General Public License 491 along with this program; if not, write to the Free Software Foundation, 492 Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 493 494 495 #ifndef MODUTILS_OBJ_H 496 497 /* The relocatable object is manipulated using elfin types. */ 498 499 #include <elf.h> 500 #include <endian.h> 501 502 #ifndef ElfW 503 # if ELFCLASSM == ELFCLASS32 504 # define ElfW(x) Elf32_ ## x 505 # define ELFW(x) ELF32_ ## x 506 # else 507 # define ElfW(x) Elf64_ ## x 508 # define ELFW(x) ELF64_ ## x 509 # endif 510 #endif 511 512 /* For some reason this is missing from some ancient C libraries.... */ 513 #ifndef ELF32_ST_INFO 514 # define ELF32_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) 515 #endif 516 517 #ifndef ELF64_ST_INFO 518 # define ELF64_ST_INFO(bind, type) (((bind) << 4) + ((type) & 0xf)) 519 #endif 520 521 #define ELF_ST_BIND(info) ELFW(ST_BIND)(info) 522 #define ELF_ST_TYPE(info) ELFW(ST_TYPE)(info) 523 #define ELF_ST_INFO(bind, type) ELFW(ST_INFO)(bind, type) 524 #define ELF_R_TYPE(val) ELFW(R_TYPE)(val) 525 #define ELF_R_SYM(val) ELFW(R_SYM)(val) 526 527 struct obj_string_patch; 528 struct obj_symbol_patch; 529 530 struct obj_section 531 { 532 ElfW(Shdr) header; 533 const char *name; 534 char *contents; 535 struct obj_section *load_next; 536 int idx; 537 }; 538 539 struct obj_symbol 540 { 541 struct obj_symbol *next; /* hash table link */ 542 const char *name; 543 unsigned long value; 544 unsigned long size; 545 int secidx; /* the defining section index/module */ 546 int info; 547 int ksymidx; /* for export to the kernel symtab */ 548 int referenced; /* actually used in the link */ 549 }; 550 551 /* Hardcode the hash table size. We shouldn't be needing so many 552 symbols that we begin to degrade performance, and we get a big win 553 by giving the compiler a constant divisor. */ 554 555 #define HASH_BUCKETS 521 556 557 struct obj_file { 558 ElfW(Ehdr) header; 559 ElfW(Addr) baseaddr; 560 struct obj_section **sections; 561 struct obj_section *load_order; 562 struct obj_section **load_order_search_start; 563 struct obj_string_patch *string_patches; 564 struct obj_symbol_patch *symbol_patches; 565 int (*symbol_cmp)(const char *, const char *); 566 unsigned long (*symbol_hash)(const char *); 567 unsigned long local_symtab_size; 568 struct obj_symbol **local_symtab; 569 struct obj_symbol *symtab[HASH_BUCKETS]; 570 }; 571 572 enum obj_reloc { 573 obj_reloc_ok, 574 obj_reloc_overflow, 575 obj_reloc_dangerous, 576 obj_reloc_unhandled 577 }; 578 579 struct obj_string_patch { 580 struct obj_string_patch *next; 581 int reloc_secidx; 582 ElfW(Addr) reloc_offset; 583 ElfW(Addr) string_offset; 584 }; 585 586 struct obj_symbol_patch { 587 struct obj_symbol_patch *next; 588 int reloc_secidx; 589 ElfW(Addr) reloc_offset; 590 struct obj_symbol *sym; 591 }; 592 593 594 /* Generic object manipulation routines. */ 595 596 static unsigned long obj_elf_hash(const char *); 597 598 static unsigned long obj_elf_hash_n(const char *, unsigned long len); 599 600 static struct obj_symbol *obj_find_symbol(struct obj_file *f, 601 const char *name); 602 603 static ElfW(Addr) obj_symbol_final_value(struct obj_file *f, 604 struct obj_symbol *sym); 605 606 #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 607 static void obj_set_symbol_compare(struct obj_file *f, 608 int (*cmp)(const char *, const char *), 609 unsigned long (*hash)(const char *)); 610 #endif 611 612 static struct obj_section *obj_find_section(struct obj_file *f, 613 const char *name); 614 615 static void obj_insert_section_load_order(struct obj_file *f, 616 struct obj_section *sec); 617 618 static struct obj_section *obj_create_alloced_section(struct obj_file *f, 619 const char *name, 620 unsigned long align, 621 unsigned long size); 622 623 static struct obj_section *obj_create_alloced_section_first(struct obj_file *f, 624 const char *name, 625 unsigned long align, 626 unsigned long size); 627 628 static void *obj_extend_section(struct obj_section *sec, unsigned long more); 629 630 static int obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, 631 const char *string); 632 633 static int obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, 634 struct obj_symbol *sym); 635 636 static int obj_check_undefineds(struct obj_file *f); 637 638 static void obj_allocate_commons(struct obj_file *f); 639 640 static unsigned long obj_load_size(struct obj_file *f); 641 642 static int obj_relocate(struct obj_file *f, ElfW(Addr) base); 643 644 static struct obj_file *obj_load(FILE *f, int loadprogbits); 645 646 static int obj_create_image(struct obj_file *f, char *image); 647 648 /* Architecture specific manipulation routines. */ 649 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, 657 struct obj_section *targsec, 658 struct obj_section *symsec, 659 struct obj_symbol *sym, 660 ElfW(RelM) *rel, ElfW(Addr) value); 661 662 static void arch_create_got(struct obj_file *f); 663 #if ENABLE_FEATURE_CHECK_TAINTED_MODULE 664 static int obj_gpl_license(struct obj_file *f, const char **license); 665 #endif /* FEATURE_CHECK_TAINTED_MODULE */ 666 #endif /* obj.h */ 667 //---------------------------------------------------------------------------- 668 //--------end of modutils obj.h 669 //---------------------------------------------------------------------------- 670 671 672 /* SPFX is always a string, so it can be concatenated to string constants. */ 673 #ifdef SYMBOL_PREFIX 674 #define SPFX SYMBOL_PREFIX 675 #else 676 #define SPFX "" 677 #endif 678 679 680 #define _PATH_MODULES "/lib/modules" 681 enum { STRVERSIONLEN = 64 }; 682 683 /*======================================================================*/ 684 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 714 715 /*======================================================================*/ 716 717 #if defined(USE_LIST) 718 719 struct arch_list_entry 720 { 721 struct arch_list_entry *next; 722 LIST_ARCHTYPE addend; 723 int offset; 724 int inited : 1; 725 }; 726 727 #endif 728 729 #if defined(USE_SINGLE) 730 731 struct arch_single_entry 732 { 733 int offset; 734 int inited : 1; 735 int allocated : 1; 736 }; 737 738 #endif 739 740 #if defined(__mips__) 741 struct mips_hi16 742 { 743 struct mips_hi16 *next; 744 ElfW(Addr) *addr; 745 ElfW(Addr) value; 746 }; 747 #endif 748 749 struct arch_file { 750 struct obj_file root; 751 #if defined(USE_PLT_ENTRIES) 752 struct obj_section *plt; 753 #endif 754 #if defined(USE_GOT_ENTRIES) 755 struct obj_section *got; 756 #endif 757 #if defined(__mips__) 758 struct mips_hi16 *mips_hi16_list; 759 #endif 760 }; 761 762 struct arch_symbol { 763 struct obj_symbol root; 764 #if defined(USE_PLT_ENTRIES) 765 #if defined(USE_PLT_LIST) 766 struct arch_list_entry *pltent; 767 #else 768 struct arch_single_entry pltent; 769 #endif 770 #endif 771 #if defined(USE_GOT_ENTRIES) 772 struct arch_single_entry gotent; 773 #endif 774 }; 775 776 777 struct external_module { 778 const char *name; 779 ElfW(Addr) addr; 780 int used; 781 size_t nsyms; 782 struct new_module_symbol *syms; 783 }; 784 785 static struct new_module_symbol *ksyms; 786 static size_t nksyms; 787 788 static struct external_module *ext_modules; 789 static int n_ext_modules; 790 static int n_ext_modules_used; 791 extern int delete_module(const char *); 792 793 static char *m_filename; 794 static char *m_fullName; 795 796 797 /*======================================================================*/ 798 799 800 static int check_module_name_match(const char *filename, struct stat *statbuf, 801 void *userdata, int depth) 802 { 803 char *fullname = (char *) userdata; 804 805 if (fullname[0] == '\0') 806 return FALSE; 807 else { 808 char *tmp, *tmp1 = xstrdup(filename); 809 tmp = bb_get_last_path_component(tmp1); 810 if (strcmp(tmp, fullname) == 0) { 811 free(tmp1); 812 /* Stop searching if we find a match */ 813 m_filename = xstrdup(filename); 814 return FALSE; 815 } 816 free(tmp1); 817 } 818 return TRUE; 819 } 820 821 822 /*======================================================================*/ 823 824 static struct obj_file *arch_new_file(void) 825 { 826 struct arch_file *f; 827 f = xmalloc(sizeof(*f)); 828 829 memset(f, 0, sizeof(*f)); 830 831 return &f->root; 832 } 833 834 static struct obj_section *arch_new_section(void) 835 { 836 return xmalloc(sizeof(struct obj_section)); 837 } 838 839 static struct obj_symbol *arch_new_symbol(void) 840 { 841 struct arch_symbol *sym; 842 sym = xmalloc(sizeof(*sym)); 843 844 memset(sym, 0, sizeof(*sym)); 845 846 return &sym->root; 847 } 848 849 static enum obj_reloc 850 arch_apply_relocation(struct obj_file *f, 851 struct obj_section *targsec, 852 struct obj_section *symsec, 853 struct obj_symbol *sym, 854 ElfW(RelM) *rel, ElfW(Addr) v) 855 { 856 struct arch_file *ifile = (struct arch_file *) f; 857 enum obj_reloc ret = obj_reloc_ok; 858 ElfW(Addr) *loc = (ElfW(Addr) *) (targsec->contents + rel->r_offset); 859 ElfW(Addr) dot = targsec->header.sh_addr + rel->r_offset; 860 #if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES) 861 struct arch_symbol *isym = (struct arch_symbol *) sym; 862 #endif 863 #if defined(__arm__) || defined(__i386__) || defined(__mc68000__) || defined(__sh__) || defined(__s390__) 864 #if defined(USE_GOT_ENTRIES) 865 ElfW(Addr) got = ifile->got ? ifile->got->header.sh_addr : 0; 866 #endif 867 #endif 868 #if defined(USE_PLT_ENTRIES) 869 ElfW(Addr) plt = ifile->plt ? ifile->plt->header.sh_addr : 0; 870 unsigned long *ip; 871 # if defined(USE_PLT_LIST) 872 struct arch_list_entry *pe; 873 # else 874 struct arch_single_entry *pe; 875 # endif 876 #endif 877 878 switch (ELF_R_TYPE(rel->r_info)) { 879 880 #if defined(__arm__) 881 882 case R_ARM_NONE: 883 break; 884 885 case R_ARM_ABS32: 886 *loc += v; 887 break; 888 889 case R_ARM_GOT32: 890 goto bb_use_got; 891 892 case R_ARM_GOTPC: 893 /* relative reloc, always to _GLOBAL_OFFSET_TABLE_ 894 * (which is .got) similar to branch, 895 * but is full 32 bits relative */ 896 897 *loc += got - dot; 898 break; 899 900 case R_ARM_PC24: 901 case R_ARM_PLT32: 902 goto bb_use_plt; 903 904 case R_ARM_GOTOFF: /* address relative to the got */ 905 *loc += v - got; 906 break; 907 908 #elif defined(__cris__) 909 910 case R_CRIS_NONE: 911 break; 912 913 case R_CRIS_32: 914 /* CRIS keeps the relocation value in the r_addend field and 915 * should not use whats in *loc at all 916 */ 917 *loc = v; 918 break; 919 920 #elif defined(__H8300H__) || defined(__H8300S__) 921 922 case R_H8_DIR24R8: 923 loc = (ElfW(Addr) *)((ElfW(Addr))loc - 1); 924 *loc = (*loc & 0xff000000) | ((*loc & 0xffffff) + v); 925 break; 926 case R_H8_DIR24A8: 927 *loc += v; 928 break; 929 case R_H8_DIR32: 930 case R_H8_DIR32A16: 931 *loc += v; 932 break; 933 case R_H8_PCREL16: 934 v -= dot + 2; 935 if ((ElfW(Sword))v > 0x7fff || 936 (ElfW(Sword))v < -(ElfW(Sword))0x8000) 937 ret = obj_reloc_overflow; 938 else 939 *(unsigned short *)loc = v; 940 break; 941 case R_H8_PCREL8: 942 v -= dot + 1; 943 if ((ElfW(Sword))v > 0x7f || 944 (ElfW(Sword))v < -(ElfW(Sword))0x80) 945 ret = obj_reloc_overflow; 946 else 947 *(unsigned char *)loc = v; 948 break; 949 950 #elif defined(__i386__) 951 952 case R_386_NONE: 953 break; 954 955 case R_386_32: 956 *loc += v; 957 break; 958 959 case R_386_PLT32: 960 case R_386_PC32: 961 *loc += v - dot; 962 break; 963 964 case R_386_GLOB_DAT: 965 case R_386_JMP_SLOT: 966 *loc = v; 967 break; 968 969 case R_386_RELATIVE: 970 *loc += f->baseaddr; 971 break; 972 973 case R_386_GOTPC: 974 *loc += got - dot; 975 break; 976 977 case R_386_GOT32: 978 goto bb_use_got; 979 980 case R_386_GOTOFF: 981 *loc += v - got; 982 break; 983 984 #elif defined(__microblaze__) 985 case R_MICROBLAZE_NONE: 986 case R_MICROBLAZE_64_NONE: 987 case R_MICROBLAZE_32_SYM_OP_SYM: 988 case R_MICROBLAZE_32_PCREL: 989 break; 990 991 case R_MICROBLAZE_64_PCREL: { 992 /* dot is the address of the current instruction. 993 * v is the target symbol address. 994 * So we need to extract the offset in the code, 995 * adding v, then subtrating the current address 996 * of this instruction. 997 * Ex: "IMM 0xFFFE bralid 0x0000" = "bralid 0xFFFE0000" 998 */ 999 1000 /* Get split offset stored in code */ 1001 unsigned int temp = (loc[0] & 0xFFFF) << 16 | 1002 (loc[1] & 0xFFFF); 1003 1004 /* Adjust relative offset. -4 adjustment required 1005 * because dot points to the IMM insn, but branch 1006 * is computed relative to the branch instruction itself. 1007 */ 1008 temp += v - dot - 4; 1009 1010 /* Store back into code */ 1011 loc[0] = (loc[0] & 0xFFFF0000) | temp >> 16; 1012 loc[1] = (loc[1] & 0xFFFF0000) | (temp & 0xFFFF); 1013 1014 break; 1015 } 1016 1017 case R_MICROBLAZE_32: 1018 *loc += v; 1019 break; 1020 1021 case R_MICROBLAZE_64: { 1022 /* Get split pointer stored in code */ 1023 unsigned int temp1 = (loc[0] & 0xFFFF) << 16 | 1024 (loc[1] & 0xFFFF); 1025 1026 /* Add reloc offset */ 1027 temp1+=v; 1028 1029 /* Store back into code */ 1030 loc[0] = (loc[0] & 0xFFFF0000) | temp1 >> 16; 1031 loc[1] = (loc[1] & 0xFFFF0000) | (temp1 & 0xFFFF); 1032 1033 break; 1034 } 1035 1036 case R_MICROBLAZE_32_PCREL_LO: 1037 case R_MICROBLAZE_32_LO: 1038 case R_MICROBLAZE_SRO32: 1039 case R_MICROBLAZE_SRW32: 1040 ret = obj_reloc_unhandled; 1041 break; 1042 1043 #elif defined(__mc68000__) 1044 1045 case R_68K_NONE: 1046 break; 1047 1048 case R_68K_32: 1049 *loc += v; 1050 break; 1051 1052 case R_68K_8: 1053 if (v > 0xff) { 1054 ret = obj_reloc_overflow; 1055 } 1056 *(char *)loc = v; 1057 break; 1058 1059 case R_68K_16: 1060 if (v > 0xffff) { 1061 ret = obj_reloc_overflow; 1062 } 1063 *(short *)loc = v; 1064 break; 1065 1066 case R_68K_PC8: 1067 v -= dot; 1068 if ((ElfW(Sword))v > 0x7f || 1069 (ElfW(Sword))v < -(ElfW(Sword))0x80) { 1070 ret = obj_reloc_overflow; 1071 } 1072 *(char *)loc = v; 1073 break; 1074 1075 case R_68K_PC16: 1076 v -= dot; 1077 if ((ElfW(Sword))v > 0x7fff || 1078 (ElfW(Sword))v < -(ElfW(Sword))0x8000) { 1079 ret = obj_reloc_overflow; 1080 } 1081 *(short *)loc = v; 1082 break; 1083 1084 case R_68K_PC32: 1085 *(int *)loc = v - dot; 1086 break; 1087 1088 case R_68K_GLOB_DAT: 1089 case R_68K_JMP_SLOT: 1090 *loc = v; 1091 break; 1092 1093 case R_68K_RELATIVE: 1094 *(int *)loc += f->baseaddr; 1095 break; 1096 1097 case R_68K_GOT32: 1098 goto bb_use_got; 1099 1100 # ifdef R_68K_GOTOFF 1101 case R_68K_GOTOFF: 1102 *loc += v - got; 1103 break; 1104 # endif 1105 1106 #elif defined(__mips__) 1107 1108 case R_MIPS_NONE: 1109 break; 1110 1111 case R_MIPS_32: 1112 *loc += v; 1113 break; 1114 1115 case R_MIPS_26: 1116 if (v % 4) 1117 ret = obj_reloc_dangerous; 1118 if ((v & 0xf0000000) != ((dot + 4) & 0xf0000000)) 1119 ret = obj_reloc_overflow; 1120 *loc = 1121 (*loc & ~0x03ffffff) | ((*loc + (v >> 2)) & 1122 0x03ffffff); 1123 break; 1124 1125 case R_MIPS_HI16: 1126 { 1127 struct mips_hi16 *n; 1128 1129 /* We cannot relocate this one now because we don't know the value 1130 of the carry we need to add. Save the information, and let LO16 1131 do the actual relocation. */ 1132 n = xmalloc(sizeof *n); 1133 n->addr = loc; 1134 n->value = v; 1135 n->next = ifile->mips_hi16_list; 1136 ifile->mips_hi16_list = n; 1137 break; 1138 } 1139 1140 case R_MIPS_LO16: 1141 { 1142 unsigned long insnlo = *loc; 1143 ElfW(Addr) val, vallo; 1144 1145 /* Sign extend the addend we extract from the lo insn. */ 1146 vallo = ((insnlo & 0xffff) ^ 0x8000) - 0x8000; 1147 1148 if (ifile->mips_hi16_list != NULL) { 1149 struct mips_hi16 *l; 1150 1151 l = ifile->mips_hi16_list; 1152 while (l != NULL) { 1153 struct mips_hi16 *next; 1154 unsigned long insn; 1155 1156 /* Do the HI16 relocation. Note that we actually don't 1157 need to know anything about the LO16 itself, except where 1158 to find the low 16 bits of the addend needed by the LO16. */ 1159 insn = *l->addr; 1160 val = 1161 ((insn & 0xffff) << 16) + 1162 vallo; 1163 val += v; 1164 1165 /* Account for the sign extension that will happen in the 1166 low bits. */ 1167 val = 1168 ((val >> 16) + 1169 ((val & 0x8000) != 1170 0)) & 0xffff; 1171 1172 insn = (insn & ~0xffff) | val; 1173 *l->addr = insn; 1174 1175 next = l->next; 1176 free(l); 1177 l = next; 1178 } 1179 1180 ifile->mips_hi16_list = NULL; 1181 } 1182 1183 /* Ok, we're done with the HI16 relocs. Now deal with the LO16. */ 1184 val = v + vallo; 1185 insnlo = (insnlo & ~0xffff) | (val & 0xffff); 1186 *loc = insnlo; 1187 break; 1188 } 1189 1190 #elif defined(__nios2__) 1191 1192 case R_NIOS2_NONE: 1193 break; 1194 1195 case R_NIOS2_BFD_RELOC_32: 1196 *loc += v; 1197 break; 1198 1199 case R_NIOS2_BFD_RELOC_16: 1200 if (v > 0xffff) { 1201 ret = obj_reloc_overflow; 1202 } 1203 *(short *)loc = v; 1204 break; 1205 1206 case R_NIOS2_BFD_RELOC_8: 1207 if (v > 0xff) { 1208 ret = obj_reloc_overflow; 1209 } 1210 *(char *)loc = v; 1211 break; 1212 1213 case R_NIOS2_S16: 1214 { 1215 Elf32_Addr word; 1216 1217 if ((Elf32_Sword)v > 0x7fff || 1218 (Elf32_Sword)v < -(Elf32_Sword)0x8000) { 1219 ret = obj_reloc_overflow; 1220 } 1221 1222 word = *loc; 1223 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | 1224 (word & 0x3f); 1225 } 1226 break; 1227 1228 case R_NIOS2_U16: 1229 { 1230 Elf32_Addr word; 1231 1232 if (v > 0xffff) { 1233 ret = obj_reloc_overflow; 1234 } 1235 1236 word = *loc; 1237 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | 1238 (word & 0x3f); 1239 } 1240 break; 1241 1242 case R_NIOS2_PCREL16: 1243 { 1244 Elf32_Addr word; 1245 1246 v -= dot + 4; 1247 if ((Elf32_Sword)v > 0x7fff || 1248 (Elf32_Sword)v < -(Elf32_Sword)0x8000) { 1249 ret = obj_reloc_overflow; 1250 } 1251 1252 word = *loc; 1253 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f); 1254 } 1255 break; 1256 1257 case R_NIOS2_GPREL: 1258 { 1259 Elf32_Addr word, gp; 1260 /* get _gp */ 1261 gp = obj_symbol_final_value(f, obj_find_symbol(f, SPFX "_gp")); 1262 v-=gp; 1263 if ((Elf32_Sword)v > 0x7fff || 1264 (Elf32_Sword)v < -(Elf32_Sword)0x8000) { 1265 ret = obj_reloc_overflow; 1266 } 1267 1268 word = *loc; 1269 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | (word & 0x3f); 1270 } 1271 break; 1272 1273 case R_NIOS2_CALL26: 1274 if (v & 3) 1275 ret = obj_reloc_dangerous; 1276 if ((v >> 28) != (dot >> 28)) 1277 ret = obj_reloc_overflow; 1278 *loc = (*loc & 0x3f) | ((v >> 2) << 6); 1279 break; 1280 1281 case R_NIOS2_IMM5: 1282 { 1283 Elf32_Addr word; 1284 1285 if (v > 0x1f) { 1286 ret = obj_reloc_overflow; 1287 } 1288 1289 word = *loc & ~0x7c0; 1290 *loc = word | ((v & 0x1f) << 6); 1291 } 1292 break; 1293 1294 case R_NIOS2_IMM6: 1295 { 1296 Elf32_Addr word; 1297 1298 if (v > 0x3f) { 1299 ret = obj_reloc_overflow; 1300 } 1301 1302 word = *loc & ~0xfc0; 1303 *loc = word | ((v & 0x3f) << 6); 1304 } 1305 break; 1306 1307 case R_NIOS2_IMM8: 1308 { 1309 Elf32_Addr word; 1310 1311 if (v > 0xff) { 1312 ret = obj_reloc_overflow; 1313 } 1314 1315 word = *loc & ~0x3fc0; 1316 *loc = word | ((v & 0xff) << 6); 1317 } 1318 break; 1319 1320 case R_NIOS2_HI16: 1321 { 1322 Elf32_Addr word; 1323 1324 word = *loc; 1325 *loc = ((((word >> 22) << 16) | ((v >>16) & 0xffff)) << 6) | 1326 (word & 0x3f); 1327 } 1328 break; 1329 1330 case R_NIOS2_LO16: 1331 { 1332 Elf32_Addr word; 1333 1334 word = *loc; 1335 *loc = ((((word >> 22) << 16) | (v & 0xffff)) << 6) | 1336 (word & 0x3f); 1337 } 1338 break; 1339 1340 case R_NIOS2_HIADJ16: 1341 { 1342 Elf32_Addr word1, word2; 1343 1344 word1 = *loc; 1345 word2 = ((v >> 16) + ((v >> 15) & 1)) & 0xffff; 1346 *loc = ((((word1 >> 22) << 16) | word2) << 6) | 1347 (word1 & 0x3f); 1348 } 1349 break; 1350 1351 #elif defined(__powerpc64__) 1352 /* PPC64 needs a 2.6 kernel, 2.4 module relocation irrelevant */ 1353 1354 #elif defined(__powerpc__) 1355 1356 case R_PPC_ADDR16_HA: 1357 *(unsigned short *)loc = (v + 0x8000) >> 16; 1358 break; 1359 1360 case R_PPC_ADDR16_HI: 1361 *(unsigned short *)loc = v >> 16; 1362 break; 1363 1364 case R_PPC_ADDR16_LO: 1365 *(unsigned short *)loc = v; 1366 break; 1367 1368 case R_PPC_REL24: 1369 goto bb_use_plt; 1370 1371 case R_PPC_REL32: 1372 *loc = v - dot; 1373 break; 1374 1375 case R_PPC_ADDR32: 1376 *loc = v; 1377 break; 1378 1379 #elif defined(__s390__) 1380 1381 case R_390_32: 1382 *(unsigned int *) loc += v; 1383 break; 1384 case R_390_16: 1385 *(unsigned short *) loc += v; 1386 break; 1387 case R_390_8: 1388 *(unsigned char *) loc += v; 1389 break; 1390 1391 case R_390_PC32: 1392 *(unsigned int *) loc += v - dot; 1393 break; 1394 case R_390_PC16DBL: 1395 *(unsigned short *) loc += (v - dot) >> 1; 1396 break; 1397 case R_390_PC16: 1398 *(unsigned short *) loc += v - dot; 1399 break; 1400 1401 case R_390_PLT32: 1402 case R_390_PLT16DBL: 1403 /* find the plt entry and initialize it. */ 1404 pe = (struct arch_single_entry *) &isym->pltent; 1405 if (pe->inited == 0) { 1406 ip = (unsigned long *)(ifile->plt->contents + pe->offset); 1407 ip[0] = 0x0d105810; /* basr 1,0; lg 1,10(1); br 1 */ 1408 ip[1] = 0x100607f1; 1409 if (ELF_R_TYPE(rel->r_info) == R_390_PLT16DBL) 1410 ip[2] = v - 2; 1411 else 1412 ip[2] = v; 1413 pe->inited = 1; 1414 } 1415 1416 /* Insert relative distance to target. */ 1417 v = plt + pe->offset - dot; 1418 if (ELF_R_TYPE(rel->r_info) == R_390_PLT32) 1419 *(unsigned int *) loc = (unsigned int) v; 1420 else if (ELF_R_TYPE(rel->r_info) == R_390_PLT16DBL) 1421 *(unsigned short *) loc = (unsigned short) ((v + 2) >> 1); 1422 break; 1423 1424 case R_390_GLOB_DAT: 1425 case R_390_JMP_SLOT: 1426 *loc = v; 1427 break; 1428 1429 case R_390_RELATIVE: 1430 *loc += f->baseaddr; 1431 break; 1432 1433 case R_390_GOTPC: 1434 *(unsigned long *) loc += got - dot; 1435 break; 1436 1437 case R_390_GOT12: 1438 case R_390_GOT16: 1439 case R_390_GOT32: 1440 if (!isym->gotent.inited) 1441 { 1442 isym->gotent.inited = 1; 1443 *(ElfW(Addr) *)(ifile->got->contents + isym->gotent.offset) = v; 1444 } 1445 if (ELF_R_TYPE(rel->r_info) == R_390_GOT12) 1446 *(unsigned short *) loc |= (*(unsigned short *) loc + isym->gotent.offset) & 0xfff; 1447 else if (ELF_R_TYPE(rel->r_info) == R_390_GOT16) 1448 *(unsigned short *) loc += isym->gotent.offset; 1449 else if (ELF_R_TYPE(rel->r_info) == R_390_GOT32) 1450 *(unsigned int *) loc += isym->gotent.offset; 1451 break; 1452 1453 # ifndef R_390_GOTOFF32 1454 # define R_390_GOTOFF32 R_390_GOTOFF 1455 # endif 1456 case R_390_GOTOFF32: 1457 *loc += v - got; 1458 break; 1459 1460 #elif defined(__sh__) 1461 1462 case R_SH_NONE: 1463 break; 1464 1465 case R_SH_DIR32: 1466 *loc += v; 1467 break; 1468 1469 case R_SH_REL32: 1470 *loc += v - dot; 1471 break; 1472 1473 case R_SH_PLT32: 1474 *loc = v - dot; 1475 break; 1476 1477 case R_SH_GLOB_DAT: 1478 case R_SH_JMP_SLOT: 1479 *loc = v; 1480 break; 1481 1482 case R_SH_RELATIVE: 1483 *loc = f->baseaddr + rel->r_addend; 1484 break; 1485 1486 case R_SH_GOTPC: 1487 *loc = got - dot + rel->r_addend; 1488 break; 1489 1490 case R_SH_GOT32: 1491 goto bb_use_got; 1492 1493 case R_SH_GOTOFF: 1494 *loc = v - got; 1495 break; 1496 1497 # if defined(__SH5__) 1498 case R_SH_IMM_MEDLOW16: 1499 case R_SH_IMM_LOW16: 1500 { 1501 ElfW(Addr) word; 1502 1503 if (ELF_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16) 1504 v >>= 16; 1505 1506 /* 1507 * movi and shori have the format: 1508 * 1509 * | op | imm | reg | reserved | 1510 * 31..26 25..10 9.. 4 3 .. 0 1511 * 1512 * so we simply mask and or in imm. 1513 */ 1514 word = *loc & ~0x3fffc00; 1515 word |= (v & 0xffff) << 10; 1516 1517 *loc = word; 1518 1519 break; 1520 } 1521 1522 case R_SH_IMM_MEDLOW16_PCREL: 1523 case R_SH_IMM_LOW16_PCREL: 1524 { 1525 ElfW(Addr) word; 1526 1527 word = *loc & ~0x3fffc00; 1528 1529 v -= dot; 1530 1531 if (ELF_R_TYPE(rel->r_info) == R_SH_IMM_MEDLOW16_PCREL) 1532 v >>= 16; 1533 1534 word |= (v & 0xffff) << 10; 1535 1536 *loc = word; 1537 1538 break; 1539 } 1540 # endif /* __SH5__ */ 1541 1542 #elif defined(__v850e__) 1543 1544 case R_V850_NONE: 1545 break; 1546 1547 case R_V850_32: 1548 /* We write two shorts instead of a long because even 1549 32-bit insns only need half-word alignment, but 1550 32-bit data needs to be long-word aligned. */ 1551 v += ((unsigned short *)loc)[0]; 1552 v += ((unsigned short *)loc)[1] << 16; 1553 ((unsigned short *)loc)[0] = v & 0xffff; 1554 ((unsigned short *)loc)[1] = (v >> 16) & 0xffff; 1555 break; 1556 1557 case R_V850_22_PCREL: 1558 goto bb_use_plt; 1559 1560 #elif defined(__x86_64__) 1561 1562 case R_X86_64_NONE: 1563 break; 1564 1565 case R_X86_64_64: 1566 *loc += v; 1567 break; 1568 1569 case R_X86_64_32: 1570 *(unsigned int *) loc += v; 1571 if (v > 0xffffffff) 1572 { 1573 ret = obj_reloc_overflow; /* Kernel module compiled without -mcmodel=kernel. */ 1574 /* error("Possibly is module compiled without -mcmodel=kernel!"); */ 1575 } 1576 break; 1577 1578 case R_X86_64_32S: 1579 *(signed int *) loc += v; 1580 break; 1581 1582 case R_X86_64_16: 1583 *(unsigned short *) loc += v; 1584 break; 1585 1586 case R_X86_64_8: 1587 *(unsigned char *) loc += v; 1588 break; 1589 1590 case R_X86_64_PC32: 1591 *(unsigned int *) loc += v - dot; 1592 break; 1593 1594 case R_X86_64_PC16: 1595 *(unsigned short *) loc += v - dot; 1596 break; 1597 1598 case R_X86_64_PC8: 1599 *(unsigned char *) loc += v - dot; 1600 break; 1601 1602 case R_X86_64_GLOB_DAT: 1603 case R_X86_64_JUMP_SLOT: 1604 *loc = v; 1605 break; 1606 1607 case R_X86_64_RELATIVE: 1608 *loc += f->baseaddr; 1609 break; 1610 1611 case R_X86_64_GOT32: 1612 case R_X86_64_GOTPCREL: 1613 goto bb_use_got; 1614 # if 0 1615 if (!isym->gotent.reloc_done) 1616 { 1617 isym->gotent.reloc_done = 1; 1618 *(Elf64_Addr *)(ifile->got->contents + isym->gotent.offset) = v; 1619 } 1620 /* XXX are these really correct? */ 1621 if (ELF64_R_TYPE(rel->r_info) == R_X86_64_GOTPCREL) 1622 *(unsigned int *) loc += v + isym->gotent.offset; 1623 else 1624 *loc += isym->gotent.offset; 1625 break; 1626 # endif 1627 1628 #else 1629 # warning "no idea how to handle relocations on your arch" 1630 #endif 1631 1632 default: 1633 printf("Warning: unhandled reloc %d\n",(int)ELF_R_TYPE(rel->r_info)); 1634 ret = obj_reloc_unhandled; 1635 break; 1636 1637 #if defined(USE_PLT_ENTRIES) 1638 1639 bb_use_plt: 1640 1641 /* find the plt entry and initialize it if necessary */ 1642 1643 #if defined(USE_PLT_LIST) 1644 for (pe = isym->pltent; pe != NULL && pe->addend != rel->r_addend;) 1645 pe = pe->next; 1646 #else 1647 pe = &isym->pltent; 1648 #endif 1649 1650 if (! pe->inited) { 1651 ip = (unsigned long *) (ifile->plt->contents + pe->offset); 1652 1653 /* generate some machine code */ 1654 1655 #if defined(__arm__) 1656 ip[0] = 0xe51ff004; /* ldr pc,[pc,#-4] */ 1657 ip[1] = v; /* sym@ */ 1658 #endif 1659 #if defined(__powerpc__) 1660 ip[0] = 0x3d600000 + ((v + 0x8000) >> 16); /* lis r11,sym@ha */ 1661 ip[1] = 0x396b0000 + (v & 0xffff); /* addi r11,r11,sym@l */ 1662 ip[2] = 0x7d6903a6; /* mtctr r11 */ 1663 ip[3] = 0x4e800420; /* bctr */ 1664 #endif 1665 #if defined(__v850e__) 1666 /* We have to trash a register, so we assume that any control 1667 transfer more than 21-bits away must be a function call 1668 (so we can use a call-clobbered register). */ 1669 ip[0] = 0x0621 + ((v & 0xffff) << 16); /* mov sym, r1 ... */ 1670 ip[1] = ((v >> 16) & 0xffff) + 0x610000; /* ...; jmp r1 */ 1671 #endif 1672 pe->inited = 1; 1673 } 1674 1675 /* relative distance to target */ 1676 v -= dot; 1677 /* if the target is too far away.... */ 1678 #if defined(__arm__) || defined(__powerpc__) 1679 if ((int)v < -0x02000000 || (int)v >= 0x02000000) 1680 #elif defined(__v850e__) 1681 if ((ElfW(Sword))v > 0x1fffff || (ElfW(Sword))v < (ElfW(Sword))-0x200000) 1682 #endif 1683 /* go via the plt */ 1684 v = plt + pe->offset - dot; 1685 1686 #if defined(__v850e__) 1687 if (v & 1) 1688 #else 1689 if (v & 3) 1690 #endif 1691 ret = obj_reloc_dangerous; 1692 1693 /* merge the offset into the instruction. */ 1694 #if defined(__arm__) 1695 /* Convert to words. */ 1696 v >>= 2; 1697 1698 *loc = (*loc & ~0x00ffffff) | ((v + *loc) & 0x00ffffff); 1699 #endif 1700 #if defined(__powerpc__) 1701 *loc = (*loc & ~0x03fffffc) | (v & 0x03fffffc); 1702 #endif 1703 #if defined(__v850e__) 1704 /* We write two shorts instead of a long because even 32-bit insns 1705 only need half-word alignment, but the 32-bit data write needs 1706 to be long-word aligned. */ 1707 ((unsigned short *)loc)[0] = 1708 (*(unsigned short *)loc & 0xffc0) /* opcode + reg */ 1709 | ((v >> 16) & 0x3f); /* offs high part */ 1710 ((unsigned short *)loc)[1] = 1711 (v & 0xffff); /* offs low part */ 1712 #endif 1713 break; 1714 #endif /* USE_PLT_ENTRIES */ 1715 1716 #if defined(USE_GOT_ENTRIES) 1717 bb_use_got: 1718 1719 /* needs an entry in the .got: set it, once */ 1720 if (!isym->gotent.inited) { 1721 isym->gotent.inited = 1; 1722 *(ElfW(Addr) *) (ifile->got->contents + isym->gotent.offset) = v; 1723 } 1724 /* make the reloc with_respect_to_.got */ 1725 #if defined(__sh__) 1726 *loc += isym->gotent.offset + rel->r_addend; 1727 #elif defined(__i386__) || defined(__arm__) || defined(__mc68000__) 1728 *loc += isym->gotent.offset; 1729 #endif 1730 break; 1731 1732 #endif /* USE_GOT_ENTRIES */ 1733 } 1734 1735 return ret; 1736 } 1737 1738 1739 #if defined(USE_LIST) 1740 1741 static int arch_list_add(ElfW(RelM) *rel, struct arch_list_entry **list, 1742 int offset, int size) 1743 { 1744 struct arch_list_entry *pe; 1745 1746 for (pe = *list; pe != NULL; pe = pe->next) { 1747 if (pe->addend == rel->r_addend) { 1748 break; 1749 } 1750 } 1751 1752 if (pe == NULL) { 1753 pe = xmalloc(sizeof(struct arch_list_entry)); 1754 pe->next = *list; 1755 pe->addend = rel->r_addend; 1756 pe->offset = offset; 1757 pe->inited = 0; 1758 *list = pe; 1759 return size; 1760 } 1761 return 0; 1762 } 1763 1764 #endif 1765 1766 #if defined(USE_SINGLE) 1767 1768 static int arch_single_init(ElfW(RelM) *rel, struct arch_single_entry *single, 1769 int offset, int size) 1770 { 1771 if (single->allocated == 0) { 1772 single->allocated = 1; 1773 single->offset = offset; 1774 single->inited = 0; 1775 return size; 1776 } 1777 return 0; 1778 } 1779 1780 #endif 1781 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, 1785 int offset, int size) 1786 { 1787 struct obj_section *myrelsec = obj_find_section(f, name); 1788 1789 if (offset == 0) { 1790 offset += size; 1791 } 1792 1793 if (myrelsec) { 1794 obj_extend_section(myrelsec, offset); 1795 } else { 1796 myrelsec = obj_create_alloced_section(f, name, 1797 size, offset); 1798 } 1799 1800 return myrelsec; 1801 } 1802 1803 #endif 1804 1805 static void arch_create_got(struct obj_file *f) 1806 { 1807 #if defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES) 1808 struct arch_file *ifile = (struct arch_file *) f; 1809 int i; 1810 #if defined(USE_GOT_ENTRIES) 1811 int got_offset = 0, got_needed = 0, got_allocate; 1812 #endif 1813 #if defined(USE_PLT_ENTRIES) 1814 int plt_offset = 0, plt_needed = 0, plt_allocate; 1815 #endif 1816 struct obj_section *relsec, *symsec, *strsec; 1817 ElfW(RelM) *rel, *relend; 1818 ElfW(Sym) *symtab, *extsym; 1819 const char *strtab, *name; 1820 struct arch_symbol *intsym; 1821 1822 for (i = 0; i < f->header.e_shnum; ++i) { 1823 relsec = f->sections[i]; 1824 if (relsec->header.sh_type != SHT_RELM) 1825 continue; 1826 1827 symsec = f->sections[relsec->header.sh_link]; 1828 strsec = f->sections[symsec->header.sh_link]; 1829 1830 rel = (ElfW(RelM) *) relsec->contents; 1831 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM))); 1832 symtab = (ElfW(Sym) *) symsec->contents; 1833 strtab = (const char *) strsec->contents; 1834 1835 for (; rel < relend; ++rel) { 1836 extsym = &symtab[ELF_R_SYM(rel->r_info)]; 1837 1838 #if defined(USE_GOT_ENTRIES) 1839 got_allocate = 0; 1840 #endif 1841 #if defined(USE_PLT_ENTRIES) 1842 plt_allocate = 0; 1843 #endif 1844 1845 switch (ELF_R_TYPE(rel->r_info)) { 1846 #if defined(__arm__) 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; 1860 1861 #elif defined(__i386__) 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; 1870 1871 #elif defined(__powerpc__) 1872 case R_PPC_REL24: 1873 plt_allocate = 1; 1874 break; 1875 1876 #elif defined(__mc68000__) 1877 case R_68K_GOT32: 1878 got_allocate = 1; 1879 break; 1880 1881 #ifdef R_68K_GOTOFF 1882 case R_68K_GOTOFF: 1883 got_needed = 1; 1884 continue; 1885 #endif 1886 1887 #elif defined(__sh__) 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; 1905 } 1906 1907 if (extsym->st_name != 0) { 1908 name = strtab + extsym->st_name; 1909 } else { 1910 name = f->sections[extsym->st_shndx]->name; 1911 } 1912 intsym = (struct arch_symbol *) obj_find_symbol(f, name); 1913 #if defined(USE_GOT_ENTRIES) 1914 if (got_allocate) { 1915 got_offset += arch_single_init( 1916 rel, &intsym->gotent, 1917 got_offset, GOT_ENTRY_SIZE); 1918 1919 got_needed = 1; 1920 } 1921 #endif 1922 #if defined(USE_PLT_ENTRIES) 1923 if (plt_allocate) { 1924 #if defined(USE_PLT_LIST) 1925 plt_offset += arch_list_add( 1926 rel, &intsym->pltent, 1927 plt_offset, PLT_ENTRY_SIZE); 1928 #else 1929 plt_offset += arch_single_init( 1930 rel, &intsym->pltent, 1931 plt_offset, PLT_ENTRY_SIZE); 1932 #endif 1933 plt_needed = 1; 1934 } 1935 #endif 1936 } 1937 } 1938 1939 #if defined(USE_GOT_ENTRIES) 1940 if (got_needed) { 1941 ifile->got = arch_xsect_init(f, ".got", got_offset, 1942 GOT_ENTRY_SIZE); 1943 } 1944 #endif 1945 1946 #if defined(USE_PLT_ENTRIES) 1947 if (plt_needed) { 1948 ifile->plt = arch_xsect_init(f, ".plt", plt_offset, 1949 PLT_ENTRY_SIZE); 1950 } 1951 #endif 1952 1953 #endif /* defined(USE_GOT_ENTRIES) || defined(USE_PLT_ENTRIES) */ 1954 } 1955 1956 /*======================================================================*/ 1957 1958 /* Standard ELF hash function. */ 1959 static unsigned long obj_elf_hash_n(const char *name, unsigned long n) 1960 { 1961 unsigned long h = 0; 1962 unsigned long g; 1963 unsigned char ch; 1964 1965 while (n > 0) { 1966 ch = *name++; 1967 h = (h << 4) + ch; 1968 if ((g = (h & 0xf0000000)) != 0) { 1969 h ^= g >> 24; 1970 h &= ~g; 1971 } 1972 n--; 1973 } 1974 return h; 1975 } 1976 1977 static unsigned long obj_elf_hash(const char *name) 1978 { 1979 return obj_elf_hash_n(name, strlen(name)); 1980 } 1981 1982 #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 1983 /* String comparison for non-co-versioned kernel and module. */ 1984 1985 static int ncv_strcmp(const char *a, const char *b) 1986 { 1987 size_t alen = strlen(a), blen = strlen(b); 1988 1989 if (blen == alen + 10 && b[alen] == '_' && b[alen + 1] == 'R') 1990 return strncmp(a, b, alen); 1991 else if (alen == blen + 10 && a[blen] == '_' && a[blen + 1] == 'R') 1992 return strncmp(a, b, blen); 1993 else 1994 return strcmp(a, b); 1995 } 1996 1997 /* String hashing for non-co-versioned kernel and module. Here 1998 we are simply forced to drop the crc from the hash. */ 1999 2000 static unsigned long ncv_symbol_hash(const char *str) 2001 { 2002 size_t len = strlen(str); 2003 if (len > 10 && str[len - 10] == '_' && str[len - 9] == 'R') 2004 len -= 10; 2005 return obj_elf_hash_n(str, len); 2006 } 2007 2008 static void 2009 obj_set_symbol_compare(struct obj_file *f, 2010 int (*cmp) (const char *, const char *), 2011 unsigned long (*hash) (const char *)) 2012 { 2013 if (cmp) 2014 f->symbol_cmp = cmp; 2015 if (hash) { 2016 struct obj_symbol *tmptab[HASH_BUCKETS], *sym, *next; 2017 int i; 2018 2019 f->symbol_hash = hash; 2020 2021 memcpy(tmptab, f->symtab, sizeof(tmptab)); 2022 memset(f->symtab, 0, sizeof(f->symtab)); 2023 2024 for (i = 0; i < HASH_BUCKETS; ++i) 2025 for (sym = tmptab[i]; sym; sym = next) { 2026 unsigned long h = hash(sym->name) % HASH_BUCKETS; 2027 next = sym->next; 2028 sym->next = f->symtab[h]; 2029 f->symtab[h] = sym; 2030 } 2031 } 2032 } 2033 2034 #endif /* FEATURE_INSMOD_VERSION_CHECKING */ 2035 2036 static struct obj_symbol * 2037 obj_add_symbol(struct obj_file *f, const char *name, 2038 unsigned long symidx, int info, 2039 int secidx, ElfW(Addr) value, 2040 unsigned long size) 2041 { 2042 struct obj_symbol *sym; 2043 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS; 2044 int n_type = ELF_ST_TYPE(info); 2045 int n_binding = ELF_ST_BIND(info); 2046 2047 for (sym = f->symtab[hash]; sym; sym = sym->next) 2048 if (f->symbol_cmp(sym->name, name) == 0) { 2049 int o_secidx = sym->secidx; 2050 int o_info = sym->info; 2051 int o_type = ELF_ST_TYPE(o_info); 2052 int o_binding = ELF_ST_BIND(o_info); 2053 2054 /* A redefinition! Is it legal? */ 2055 2056 if (secidx == SHN_UNDEF) 2057 return sym; 2058 else if (o_secidx == SHN_UNDEF) 2059 goto found; 2060 else if (n_binding == STB_GLOBAL && o_binding == STB_LOCAL) { 2061 /* Cope with local and global symbols of the same name 2062 in the same object file, as might have been created 2063 by ld -r. The only reason locals are now seen at this 2064 level at all is so that we can do semi-sensible things 2065 with parameters. */ 2066 2067 struct obj_symbol *nsym, **p; 2068 2069 nsym = arch_new_symbol(); 2070 nsym->next = sym->next; 2071 nsym->ksymidx = -1; 2072 2073 /* Excise the old (local) symbol from the hash chain. */ 2074 for (p = &f->symtab[hash]; *p != sym; p = &(*p)->next) 2075 continue; 2076 *p = sym = nsym; 2077 goto found; 2078 } else if (n_binding == STB_LOCAL) { 2079 /* Another symbol of the same name has already been defined. 2080 Just add this to the local table. */ 2081 sym = arch_new_symbol(); 2082 sym->next = NULL; 2083 sym->ksymidx = -1; 2084 f->local_symtab[symidx] = sym; 2085 goto found; 2086 } else if (n_binding == STB_WEAK) 2087 return sym; 2088 else if (o_binding == STB_WEAK) 2089 goto found; 2090 /* Don't unify COMMON symbols with object types the programmer 2091 doesn't expect. */ 2092 else if (secidx == SHN_COMMON 2093 && (o_type == STT_NOTYPE || o_type == STT_OBJECT)) 2094 return sym; 2095 else if (o_secidx == SHN_COMMON 2096 && (n_type == STT_NOTYPE || n_type == STT_OBJECT)) 2097 goto found; 2098 else { 2099 /* Don't report an error if the symbol is coming from 2100 the kernel or some external module. */ 2101 if (secidx <= SHN_HIRESERVE) 2102 bb_error_msg("%s multiply defined", name); 2103 return sym; 2104 } 2105 } 2106 2107 /* Completely new symbol. */ 2108 sym = arch_new_symbol(); 2109 sym->next = f->symtab[hash]; 2110 f->symtab[hash] = sym; 2111 sym->ksymidx = -1; 2112 2113 if (ELF_ST_BIND(info) == STB_LOCAL && symidx != -1) { 2114 if (symidx >= f->local_symtab_size) 2115 bb_error_msg("local symbol %s with index %ld exceeds local_symtab_size %ld", 2116 name, (long) symidx, (long) f->local_symtab_size); 2117 else 2118 f->local_symtab[symidx] = sym; 2119 } 2120 2121 found: 2122 sym->name = name; 2123 sym->value = value; 2124 sym->size = size; 2125 sym->secidx = secidx; 2126 sym->info = info; 2127 2128 return sym; 2129 } 2130 2131 static struct obj_symbol * 2132 obj_find_symbol(struct obj_file *f, const char *name) 2133 { 2134 struct obj_symbol *sym; 2135 unsigned long hash = f->symbol_hash(name) % HASH_BUCKETS; 2136 2137 for (sym = f->symtab[hash]; sym; sym = sym->next) 2138 if (f->symbol_cmp(sym->name, name) == 0) 2139 return sym; 2140 2141 return NULL; 2142 } 2143 2144 static ElfW(Addr) obj_symbol_final_value(struct obj_file * f, struct obj_symbol * sym) 2145 { 2146 if (sym) { 2147 if (sym->secidx >= SHN_LORESERVE) 2148 return sym->value; 2149 2150 return sym->value + f->sections[sym->secidx]->header.sh_addr; 2151 } else { 2152 /* As a special case, a NULL sym has value zero. */ 2153 return 0; 2154 } 2155 } 2156 2157 static struct obj_section *obj_find_section(struct obj_file *f, const char *name) 2158 { 2159 int i, n = f->header.e_shnum; 2160 2161 for (i = 0; i < n; ++i) 2162 if (strcmp(f->sections[i]->name, name) == 0) 2163 return f->sections[i]; 2164 2165 return NULL; 2166 } 2167 2168 static int obj_load_order_prio(struct obj_section *a) 2169 { 2170 unsigned long af, ac; 2171 2172 af = a->header.sh_flags; 2173 2174 ac = 0; 2175 if (a->name[0] != '.' || strlen(a->name) != 10 || 2176 strcmp(a->name + 5, ".init")) 2177 ac |= 32; 2178 if (af & SHF_ALLOC) 2179 ac |= 16; 2180 if (!(af & SHF_WRITE)) 2181 ac |= 8; 2182 if (af & SHF_EXECINSTR) 2183 ac |= 4; 2184 if (a->header.sh_type != SHT_NOBITS) 2185 ac |= 2; 2186 2187 return ac; 2188 } 2189 2190 static void 2191 obj_insert_section_load_order(struct obj_file *f, struct obj_section *sec) 2192 { 2193 struct obj_section **p; 2194 int prio = obj_load_order_prio(sec); 2195 for (p = f->load_order_search_start; *p; p = &(*p)->load_next) 2196 if (obj_load_order_prio(*p) < prio) 2197 break; 2198 sec->load_next = *p; 2199 *p = sec; 2200 } 2201 2202 static struct obj_section *obj_create_alloced_section(struct obj_file *f, 2203 const char *name, 2204 unsigned long align, 2205 unsigned long size) 2206 { 2207 int newidx = f->header.e_shnum++; 2208 struct obj_section *sec; 2209 2210 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec)); 2211 f->sections[newidx] = sec = arch_new_section(); 2212 2213 memset(sec, 0, sizeof(*sec)); 2214 sec->header.sh_type = SHT_PROGBITS; 2215 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; 2216 sec->header.sh_size = size; 2217 sec->header.sh_addralign = align; 2218 sec->name = name; 2219 sec->idx = newidx; 2220 if (size) 2221 sec->contents = xmalloc(size); 2222 2223 obj_insert_section_load_order(f, sec); 2224 2225 return sec; 2226 } 2227 2228 static struct obj_section *obj_create_alloced_section_first(struct obj_file *f, 2229 const char *name, 2230 unsigned long align, 2231 unsigned long size) 2232 { 2233 int newidx = f->header.e_shnum++; 2234 struct obj_section *sec; 2235 2236 f->sections = xrealloc(f->sections, (newidx + 1) * sizeof(sec)); 2237 f->sections[newidx] = sec = arch_new_section(); 2238 2239 memset(sec, 0, sizeof(*sec)); 2240 sec->header.sh_type = SHT_PROGBITS; 2241 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; 2242 sec->header.sh_size = size; 2243 sec->header.sh_addralign = align; 2244 sec->name = name; 2245 sec->idx = newidx; 2246 if (size) 2247 sec->contents = xmalloc(size); 2248 2249 sec->load_next = f->load_order; 2250 f->load_order = sec; 2251 if (f->load_order_search_start == &f->load_order) 2252 f->load_order_search_start = &sec->load_next; 2253 2254 return sec; 2255 } 2256 2257 static void *obj_extend_section(struct obj_section *sec, unsigned long more) 2258 { 2259 unsigned long oldsize = sec->header.sh_size; 2260 if (more) { 2261 sec->contents = xrealloc(sec->contents, sec->header.sh_size += more); 2262 } 2263 return sec->contents + oldsize; 2264 } 2265 2266 2267 /* Conditionally add the symbols from the given symbol set to the 2268 new module. */ 2269 2270 static int 2271 add_symbols_from( struct obj_file *f, 2272 int idx, struct new_module_symbol *syms, size_t nsyms) 2273 { 2274 struct new_module_symbol *s; 2275 size_t i; 2276 int used = 0; 2277 #ifdef SYMBOL_PREFIX 2278 char *name_buf = 0; 2279 size_t name_alloced_size = 0; 2280 #endif 2281 #if ENABLE_FEATURE_CHECK_TAINTED_MODULE 2282 int gpl; 2283 2284 gpl = obj_gpl_license(f, NULL) == 0; 2285 #endif 2286 for (i = 0, s = syms; i < nsyms; ++i, ++s) { 2287 /* Only add symbols that are already marked external. 2288 If we override locals we may cause problems for 2289 argument initialization. We will also create a false 2290 dependency on the module. */ 2291 struct obj_symbol *sym; 2292 char *name; 2293 2294 /* GPL licensed modules can use symbols exported with 2295 * EXPORT_SYMBOL_GPL, so ignore any GPLONLY_ prefix on the 2296 * exported names. Non-GPL modules never see any GPLONLY_ 2297 * symbols so they cannot fudge it by adding the prefix on 2298 * their references. 2299 */ 2300 if (strncmp((char *)s->name, "GPLONLY_", 8) == 0) { 2301 #if ENABLE_FEATURE_CHECK_TAINTED_MODULE 2302 if (gpl) 2303 s->name += 8; 2304 else 2305 #endif 2306 continue; 2307 } 2308 name = (char *)s->name; 2309 2310 #ifdef SYMBOL_PREFIX 2311 /* Prepend SYMBOL_PREFIX to the symbol's name (the 2312 kernel exports `C names', but module object files 2313 reference `linker names'). */ 2314 size_t extra = sizeof SYMBOL_PREFIX; 2315 size_t name_size = strlen(name) + extra; 2316 if (name_size > name_alloced_size) { 2317 name_alloced_size = name_size * 2; 2318 name_buf = alloca(name_alloced_size); 2319 } 2320 strcpy(name_buf, SYMBOL_PREFIX); 2321 strcpy(name_buf + extra - 1, name); 2322 name = name_buf; 2323 #endif /* SYMBOL_PREFIX */ 2324 2325 sym = obj_find_symbol(f, name); 2326 if (sym && !(ELF_ST_BIND(sym->info) == STB_LOCAL)) { 2327 #ifdef SYMBOL_PREFIX 2328 /* Put NAME_BUF into more permanent storage. */ 2329 name = xmalloc(name_size); 2330 strcpy(name, name_buf); 2331 #endif 2332 sym = obj_add_symbol(f, name, -1, 2333 ELF_ST_INFO(STB_GLOBAL, 2334 STT_NOTYPE), 2335 idx, s->value, 0); 2336 /* Did our symbol just get installed? If so, mark the 2337 module as "used". */ 2338 if (sym->secidx == idx) 2339 used = 1; 2340 } 2341 } 2342 2343 return used; 2344 } 2345 2346 static void add_kernel_symbols(struct obj_file *f) 2347 { 2348 struct external_module *m; 2349 int i, nused = 0; 2350 2351 /* Add module symbols first. */ 2352 2353 for (i = 0, m = ext_modules; i < n_ext_modules; ++i, ++m) { 2354 if (m->nsyms 2355 && add_symbols_from(f, SHN_HIRESERVE + 2 + i, m->syms, m->nsyms) 2356 ) { 2357 m->used = 1; 2358 ++nused; 2359 } 2360 } 2361 2362 n_ext_modules_used = nused; 2363 2364 /* And finally the symbols from the kernel proper. */ 2365 2366 if (nksyms) 2367 add_symbols_from(f, SHN_HIRESERVE + 1, ksyms, nksyms); 2368 } 2369 2370 static char *get_modinfo_value(struct obj_file *f, const char *key) 2371 { 2372 struct obj_section *sec; 2373 char *p, *v, *n, *ep; 2374 size_t klen = strlen(key); 2375 2376 sec = obj_find_section(f, ".modinfo"); 2377 if (sec == NULL) 2378 return NULL; 2379 p = sec->contents; 2380 ep = p + sec->header.sh_size; 2381 while (p < ep) { 2382 v = strchr(p, '='); 2383 n = strchr(p, '\0'); 2384 if (v) { 2385 if (p + klen == v && strncmp(p, key, klen) == 0) 2386 return v + 1; 2387 } else { 2388 if (p + klen == n && strcmp(p, key) == 0) 2389 return n; 2390 } 2391 p = n + 1; 2392 } 2393 2394 return NULL; 2395 } 2396 2397 2398 /*======================================================================*/ 2399 /* Functions relating to module loading after 2.1.18. */ 2400 2401 static int 2402 new_process_module_arguments(struct obj_file *f, int argc, char **argv) 2403 { 2404 while (argc > 0) { 2405 char *p, *q, *key, *sym_name; 2406 struct obj_symbol *sym; 2407 char *contents, *loc; 2408 int min, max, n; 2409 2410 p = *argv; 2411 if ((q = strchr(p, '=')) == NULL) { 2412 argc--; 2413 continue; 2414 } 2415 2416 key = alloca(q - p + 6); 2417 memcpy(key, "parm_", 5); 2418 memcpy(key + 5, p, q - p); 2419 key[q - p + 5] = 0; 2420 2421 p = get_modinfo_value(f, key); 2422 key += 5; 2423 if (p == NULL) { 2424 bb_error_msg("invalid parameter %s", key); 2425 return 0; 2426 } 2427 2428 #ifdef SYMBOL_PREFIX 2429 sym_name = alloca(strlen(key) + sizeof SYMBOL_PREFIX); 2430 strcpy(sym_name, SYMBOL_PREFIX); 2431 strcat(sym_name, key); 2432 #else 2433 sym_name = key; 2434 #endif 2435 sym = obj_find_symbol(f, sym_name); 2436 2437 /* Also check that the parameter was not resolved from the kernel. */ 2438 if (sym == NULL || sym->secidx > SHN_HIRESERVE) { 2439 bb_error_msg("symbol for parameter %s not found", key); 2440 return 0; 2441 } 2442 2443 if (isdigit(*p)) { 2444 min = strtoul(p, &p, 10); 2445 if (*p == '-') 2446 max = strtoul(p + 1, &p, 10); 2447 else 2448 max = min; 2449 } else 2450 min = max = 1; 2451 2452 contents = f->sections[sym->secidx]->contents; 2453 loc = contents + sym->value; 2454 n = (*++q != '\0'); 2455 2456 while (1) { 2457 if ((*p == 's') || (*p == 'c')) { 2458 char *str; 2459 2460 /* Do C quoting if we begin with a ", else slurp the lot. */ 2461 if (*q == '"') { 2462 char *r; 2463 2464 str = alloca(strlen(q)); 2465 for (r = str, q++; *q != '"'; ++q, ++r) { 2466 if (*q == '\0') { 2467 bb_error_msg("improperly terminated string argument for %s", 2468 key); 2469 return 0; 2470 } else if (*q == '\\') 2471 switch (*++q) { 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') 2507 c = (c * 8) + *++q - '0'; 2508 } 2509 *r = c; 2510 } 2511 break; 2512 2513 default: 2514 *r = *q; 2515 break; 2516 } else 2517 *r = *q; 2518 } 2519 *r = '\0'; 2520 ++q; 2521 } else { 2522 char *r; 2523 2524 /* In this case, the string is not quoted. We will break 2525 it using the coma (like for ints). If the user wants to 2526 include comas in a string, he just has to quote it */ 2527 2528 /* Search the next coma */ 2529 r = strchr(q, ','); 2530 2531 /* Found ? */ 2532 if (r != (char *) NULL) { 2533 /* Recopy the current field */ 2534 str = alloca(r - q + 1); 2535 memcpy(str, q, r - q); 2536 2537 /* I don't know if it is useful, as the previous case 2538 doesn't nul terminate the string ??? */ 2539 str[r - q] = '\0'; 2540 2541 /* Keep next fields */ 2542 q = r; 2543 } else { 2544 /* last string */ 2545 str = q; 2546 q = (char*)""; 2547 } 2548 } 2549 2550 if (*p == 's') { 2551 /* Normal string */ 2552 obj_string_patch(f, sym->secidx, loc - contents, str); 2553 loc += tgt_sizeof_char_p; 2554 } else { 2555 /* Array of chars (in fact, matrix!) */ 2556 unsigned long charssize; /* size of each member */ 2557 2558 /* Get the size of each member */ 2559 /* Probably we should do that outside the loop ? */ 2560 if (!isdigit(*(p + 1))) { 2561 bb_error_msg("parameter type 'c' for %s must be followed by" 2562 " the maximum size", key); 2563 return 0; 2564 } 2565 charssize = strtoul(p + 1, (char **) NULL, 10); 2566 2567 /* Check length */ 2568 if (strlen(str) >= charssize) { 2569 bb_error_msg("string too long for %s (max %ld)", key, 2570 charssize - 1); 2571 return 0; 2572 } 2573 2574 /* Copy to location */ 2575 strcpy((char *) loc, str); 2576 loc += charssize; 2577 } 2578 } else { 2579 long v = strtoul(q, &q, 0); 2580 switch (*p) { 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; 2600 } 2601 } 2602 2603 retry_end_of_value: 2604 switch (*q) { 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); 2618 return 0; 2619 } 2620 ++q; 2621 break; 2622 2623 default: 2624 bb_error_msg("invalid argument syntax for %s", key); 2625 return 0; 2626 } 2627 } 2628 2629 end_of_arg: 2630 if (n < min) { 2631 bb_error_msg("too few values for %s (min %d)", key, min); 2632 return 0; 2633 } 2634 2635 argc--, argv++; 2636 } 2637 2638 return 1; 2639 } 2640 2641 #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 2642 static int new_is_module_checksummed(struct obj_file *f) 2643 { 2644 const char *p = get_modinfo_value(f, "using_checksums"); 2645 if (p) 2646 return xatoi(p); 2647 else 2648 return 0; 2649 } 2650 2651 /* Get the module's kernel version in the canonical integer form. */ 2652 2653 static int 2654 new_get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) 2655 { 2656 char *p, *q; 2657 int a, b, c; 2658 2659 p = get_modinfo_value(f, "kernel_version"); 2660 if (p == NULL) 2661 return -1; 2662 safe_strncpy(str, p, STRVERSIONLEN); 2663 2664 a = strtoul(p, &p, 10); 2665 if (*p != '.') 2666 return -1; 2667 b = strtoul(p + 1, &p, 10); 2668 if (*p != '.') 2669 return -1; 2670 c = strtoul(p + 1, &q, 10); 2671 if (p + 1 == q) 2672 return -1; 2673 2674 return a << 16 | b << 8 | c; 2675 } 2676 2677 #endif /* FEATURE_INSMOD_VERSION_CHECKING */ 2678 2679 2680 /* Fetch the loaded modules, and all currently exported symbols. */ 2681 2682 static int new_get_kernel_symbols(void) 2683 { 2684 char *module_names, *mn; 2685 struct external_module *modules, *m; 2686 struct new_module_symbol *syms, *s; 2687 size_t ret, bufsize, nmod, nsyms, i, j; 2688 2689 /* Collect the loaded modules. */ 2690 2691 module_names = xmalloc(bufsize = 256); 2692 retry_modules_load: 2693 if (query_module(NULL, QM_MODULES, module_names, bufsize, &ret)) { 2694 if (errno == ENOSPC && bufsize < ret) { 2695 module_names = xrealloc(module_names, bufsize = ret); 2696 goto retry_modules_load; 2697 } 2698 bb_perror_msg("QM_MODULES"); 2699 return 0; 2700 } 2701 2702 n_ext_modules = nmod = ret; 2703 2704 /* Collect the modules' symbols. */ 2705 2706 if (nmod) { 2707 ext_modules = modules = xmalloc(nmod * sizeof(*modules)); 2708 memset(modules, 0, nmod * sizeof(*modules)); 2709 for (i = 0, mn = module_names, m = modules; 2710 i < nmod; ++i, ++m, mn += strlen(mn) + 1) { 2711 struct new_module_info info; 2712 2713 if (query_module(mn, QM_INFO, &info, sizeof(info), &ret)) { 2714 if (errno == ENOENT) { 2715 /* The module was removed out from underneath us. */ 2716 continue; 2717 } 2718 bb_perror_msg("query_module: QM_INFO: %s", mn); 2719 return 0; 2720 } 2721 2722 syms = xmalloc(bufsize = 1024); 2723 retry_mod_sym_load: 2724 if (query_module(mn, QM_SYMBOLS, syms, bufsize, &ret)) { 2725 switch (errno) { 2726 case ENOSPC: 2727 syms = xrealloc(syms, bufsize = ret); 2728 goto retry_mod_sym_load; 2729 case ENOENT: 2730 /* The module was removed out from underneath us. */ 2731 continue; 2732 default: 2733 bb_perror_msg("query_module: QM_SYMBOLS: %s", mn); 2734 return 0; 2735 } 2736 } 2737 nsyms = ret; 2738 2739 m->name = mn; 2740 m->addr = info.addr; 2741 m->nsyms = nsyms; 2742 m->syms = syms; 2743 2744 for (j = 0, s = syms; j < nsyms; ++j, ++s) { 2745 s->name += (unsigned long) syms; 2746 } 2747 } 2748 } 2749 2750 /* Collect the kernel's symbols. */ 2751 2752 syms = xmalloc(bufsize = 16 * 1024); 2753 retry_kern_sym_load: 2754 if (query_module(NULL, QM_SYMBOLS, syms, bufsize, &ret)) { 2755 if (errno == ENOSPC && bufsize < ret) { 2756 syms = xrealloc(syms, bufsize = ret); 2757 goto retry_kern_sym_load; 2758 } 2759 bb_perror_msg("kernel: QM_SYMBOLS"); 2760 return 0; 2761 } 2762 nksyms = nsyms = ret; 2763 ksyms = syms; 2764 2765 for (j = 0, s = syms; j < nsyms; ++j, ++s) { 2766 s->name += (unsigned long) syms; 2767 } 2768 return 1; 2769 } 2770 2771 2772 /* Return the kernel symbol checksum version, or zero if not used. */ 2773 2774 static int new_is_kernel_checksummed(void) 2775 { 2776 struct new_module_symbol *s; 2777 size_t i; 2778 2779 /* Using_Versions is not the first symbol, but it should be in there. */ 2780 2781 for (i = 0, s = ksyms; i < nksyms; ++i, ++s) 2782 if (strcmp((char *) s->name, "Using_Versions") == 0) 2783 return s->value; 2784 2785 return 0; 2786 } 2787 2788 2789 static int new_create_this_module(struct obj_file *f, const char *m_name) 2790 { 2791 struct obj_section *sec; 2792 2793 sec = obj_create_alloced_section_first(f, ".this", tgt_sizeof_long, 2794 sizeof(struct new_module)); 2795 memset(sec->contents, 0, sizeof(struct new_module)); 2796 2797 obj_add_symbol(f, SPFX "__this_module", -1, 2798 ELF_ST_INFO(STB_LOCAL, STT_OBJECT), sec->idx, 0, 2799 sizeof(struct new_module)); 2800 2801 obj_string_patch(f, sec->idx, offsetof(struct new_module, name), 2802 m_name); 2803 2804 return 1; 2805 } 2806 2807 #if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS 2808 /* add an entry to the __ksymtab section, creating it if necessary */ 2809 static void new_add_ksymtab(struct obj_file *f, struct obj_symbol *sym) 2810 { 2811 struct obj_section *sec; 2812 ElfW(Addr) ofs; 2813 2814 /* ensure __ksymtab is allocated, EXPORT_NOSYMBOLS creates a non-alloc section. 2815 * If __ksymtab is defined but not marked alloc, x out the first character 2816 * (no obj_delete routine) and create a new __ksymtab with the correct 2817 * characteristics. 2818 */ 2819 sec = obj_find_section(f, "__ksymtab"); 2820 if (sec && !(sec->header.sh_flags & SHF_ALLOC)) { 2821 *((char *)(sec->name)) = 'x'; /* override const */ 2822 sec = NULL; 2823 } 2824 if (!sec) 2825 sec = obj_create_alloced_section(f, "__ksymtab", 2826 tgt_sizeof_void_p, 0); 2827 if (!sec) 2828 return; 2829 sec->header.sh_flags |= SHF_ALLOC; 2830 /* Empty section might be byte-aligned */ 2831 sec->header.sh_addralign = tgt_sizeof_void_p; 2832 ofs = sec->header.sh_size; 2833 obj_symbol_patch(f, sec->idx, ofs, sym); 2834 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, sym->name); 2835 obj_extend_section(sec, 2 * tgt_sizeof_char_p); 2836 } 2837 #endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */ 2838 2839 static int new_create_module_ksymtab(struct obj_file *f) 2840 { 2841 struct obj_section *sec; 2842 int i; 2843 2844 /* We must always add the module references. */ 2845 2846 if (n_ext_modules_used) { 2847 struct new_module_ref *dep; 2848 struct obj_symbol *tm; 2849 2850 sec = obj_create_alloced_section(f, ".kmodtab", tgt_sizeof_void_p, 2851 (sizeof(struct new_module_ref) 2852 * n_ext_modules_used)); 2853 if (!sec) 2854 return 0; 2855 2856 tm = obj_find_symbol(f, SPFX "__this_module"); 2857 dep = (struct new_module_ref *) sec->contents; 2858 for (i = 0; i < n_ext_modules; ++i) 2859 if (ext_modules[i].used) { 2860 dep->dep = ext_modules[i].addr; 2861 obj_symbol_patch(f, sec->idx, 2862 (char *) &dep->ref - sec->contents, tm); 2863 dep->next_ref = 0; 2864 ++dep; 2865 } 2866 } 2867 2868 if (!flag_noexport && !obj_find_section(f, "__ksymtab")) { 2869 size_t nsyms; 2870 int *loaded; 2871 2872 sec = obj_create_alloced_section(f, "__ksymtab", tgt_sizeof_void_p, 0); 2873 2874 /* We don't want to export symbols residing in sections that 2875 aren't loaded. There are a number of these created so that 2876 we make sure certain module options don't appear twice. */ 2877 2878 loaded = alloca(sizeof(int) * (i = f->header.e_shnum)); 2879 while (--i >= 0) 2880 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0; 2881 2882 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) { 2883 struct obj_symbol *sym; 2884 for (sym = f->symtab[i]; sym; sym = sym->next) 2885 if (ELF_ST_BIND(sym->info) != STB_LOCAL 2886 && sym->secidx <= SHN_HIRESERVE 2887 && (sym->secidx >= SHN_LORESERVE 2888 || loaded[sym->secidx])) { 2889 ElfW(Addr) ofs = nsyms * 2 * tgt_sizeof_void_p; 2890 2891 obj_symbol_patch(f, sec->idx, ofs, sym); 2892 obj_string_patch(f, sec->idx, ofs + tgt_sizeof_void_p, 2893 sym->name); 2894 2895 nsyms++; 2896 } 2897 } 2898 2899 obj_extend_section(sec, nsyms * 2 * tgt_sizeof_char_p); 2900 } 2901 2902 return 1; 2903 } 2904 2905 2906 static int 2907 new_init_module(const char *m_name, struct obj_file *f, unsigned long m_size) 2908 { 2909 struct new_module *module; 2910 struct obj_section *sec; 2911 void *image; 2912 int ret; 2913 tgt_long m_addr; 2914 2915 sec = obj_find_section(f, ".this"); 2916 if (!sec || !sec->contents) { 2917 bb_perror_msg_and_die("corrupt module %s?",m_name); 2918 } 2919 module = (struct new_module *) sec->contents; 2920 m_addr = sec->header.sh_addr; 2921 2922 module->size_of_struct = sizeof(*module); 2923 module->size = m_size; 2924 module->flags = flag_autoclean ? NEW_MOD_AUTOCLEAN : 0; 2925 2926 sec = obj_find_section(f, "__ksymtab"); 2927 if (sec && sec->header.sh_size) { 2928 module->syms = sec->header.sh_addr; 2929 module->nsyms = sec->header.sh_size / (2 * tgt_sizeof_char_p); 2930 } 2931 2932 if (n_ext_modules_used) { 2933 sec = obj_find_section(f, ".kmodtab"); 2934 module->deps = sec->header.sh_addr; 2935 module->ndeps = n_ext_modules_used; 2936 } 2937 2938 module->init = 2939 obj_symbol_final_value(f, obj_find_symbol(f, SPFX "init_module")); 2940 module->cleanup = 2941 obj_symbol_final_value(f, obj_find_symbol(f, SPFX "cleanup_module")); 2942 2943 sec = obj_find_section(f, "__ex_table"); 2944 if (sec) { 2945 module->ex_table_start = sec->header.sh_addr; 2946 module->ex_table_end = sec->header.sh_addr + sec->header.sh_size; 2947 } 2948 2949 sec = obj_find_section(f, ".text.init"); 2950 if (sec) { 2951 module->runsize = sec->header.sh_addr - m_addr; 2952 } 2953 sec = obj_find_section(f, ".data.init"); 2954 if (sec) { 2955 if (!module->runsize || 2956 module->runsize > sec->header.sh_addr - m_addr) 2957 module->runsize = sec->header.sh_addr - m_addr; 2958 } 2959 sec = obj_find_section(f, ARCHDATA_SEC_NAME); 2960 if (sec && sec->header.sh_size) { 2961 module->archdata_start = (void*)sec->header.sh_addr; 2962 module->archdata_end = module->archdata_start + sec->header.sh_size; 2963 } 2964 sec = obj_find_section(f, KALLSYMS_SEC_NAME); 2965 if (sec && sec->header.sh_size) { 2966 module->kallsyms_start = (void*)sec->header.sh_addr; 2967 module->kallsyms_end = module->kallsyms_start + sec->header.sh_size; 2968 } 2969 2970 /* Whew! All of the initialization is complete. Collect the final 2971 module image and give it to the kernel. */ 2972 2973 image = xmalloc(m_size); 2974 obj_create_image(f, image); 2975 2976 ret = init_module(m_name, (struct new_module *) image); 2977 if (ret) 2978 bb_perror_msg("init_module: %s", m_name); 2979 2980 free(image); 2981 2982 return ret == 0; 2983 } 2984 2985 2986 /*======================================================================*/ 2987 2988 static int 2989 obj_string_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, 2990 const char *string) 2991 { 2992 struct obj_string_patch *p; 2993 struct obj_section *strsec; 2994 size_t len = strlen(string) + 1; 2995 char *loc; 2996 2997 p = xmalloc(sizeof(*p)); 2998 p->next = f->string_patches; 2999 p->reloc_secidx = secidx; 3000 p->reloc_offset = offset; 3001 f->string_patches = p; 3002 3003 strsec = obj_find_section(f, ".kstrtab"); 3004 if (strsec == NULL) { 3005 strsec = obj_create_alloced_section(f, ".kstrtab", 1, len); 3006 p->string_offset = 0; 3007 loc = strsec->contents; 3008 } else { 3009 p->string_offset = strsec->header.sh_size; 3010 loc = obj_extend_section(strsec, len); 3011 } 3012 memcpy(loc, string, len); 3013 3014 return 1; 3015 } 3016 3017 static int 3018 obj_symbol_patch(struct obj_file *f, int secidx, ElfW(Addr) offset, 3019 struct obj_symbol *sym) 3020 { 3021 struct obj_symbol_patch *p; 3022 3023 p = xmalloc(sizeof(*p)); 3024 p->next = f->symbol_patches; 3025 p->reloc_secidx = secidx; 3026 p->reloc_offset = offset; 3027 p->sym = sym; 3028 f->symbol_patches = p; 3029 3030 return 1; 3031 } 3032 3033 static int obj_check_undefineds(struct obj_file *f) 3034 { 3035 unsigned long i; 3036 int ret = 1; 3037 3038 for (i = 0; i < HASH_BUCKETS; ++i) { 3039 struct obj_symbol *sym; 3040 for (sym = f->symtab[i]; sym; sym = sym->next) 3041 if (sym->secidx == SHN_UNDEF) { 3042 if (ELF_ST_BIND(sym->info) == STB_WEAK) { 3043 sym->secidx = SHN_ABS; 3044 sym->value = 0; 3045 } else { 3046 if (!flag_quiet) { 3047 bb_error_msg("unresolved symbol %s", sym->name); 3048 } 3049 ret = 0; 3050 } 3051 } 3052 } 3053 3054 return ret; 3055 } 3056 3057 static void obj_allocate_commons(struct obj_file *f) 3058 { 3059 struct common_entry { 3060 struct common_entry *next; 3061 struct obj_symbol *sym; 3062 } *common_head = NULL; 3063 3064 unsigned long i; 3065 3066 for (i = 0; i < HASH_BUCKETS; ++i) { 3067 struct obj_symbol *sym; 3068 for (sym = f->symtab[i]; sym; sym = sym->next) 3069 if (sym->secidx == SHN_COMMON) { 3070 /* Collect all COMMON symbols and sort them by size so as to 3071 minimize space wasted by alignment requirements. */ 3072 { 3073 struct common_entry **p, *n; 3074 for (p = &common_head; *p; p = &(*p)->next) 3075 if (sym->size <= (*p)->sym->size) 3076 break; 3077 3078 n = alloca(sizeof(*n)); 3079 n->next = *p; 3080 n->sym = sym; 3081 *p = n; 3082 } 3083 } 3084 } 3085 3086 for (i = 1; i < f->local_symtab_size; ++i) { 3087 struct obj_symbol *sym = f->local_symtab[i]; 3088 if (sym && sym->secidx == SHN_COMMON) { 3089 struct common_entry **p, *n; 3090 for (p = &common_head; *p; p = &(*p)->next) 3091 if (sym == (*p)->sym) 3092 break; 3093 else if (sym->size < (*p)->sym->size) { 3094 n = alloca(sizeof(*n)); 3095 n->next = *p; 3096 n->sym = sym; 3097 *p = n; 3098 break; 3099 } 3100 } 3101 } 3102 3103 if (common_head) { 3104 /* Find the bss section. */ 3105 for (i = 0; i < f->header.e_shnum; ++i) 3106 if (f->sections[i]->header.sh_type == SHT_NOBITS) 3107 break; 3108 3109 /* If for some reason there hadn't been one, create one. */ 3110 if (i == f->header.e_shnum) { 3111 struct obj_section *sec; 3112 3113 f->sections = xrealloc(f->sections, (i + 1) * sizeof(sec)); 3114 f->sections[i] = sec = arch_new_section(); 3115 f->header.e_shnum = i + 1; 3116 3117 memset(sec, 0, sizeof(*sec)); 3118 sec->header.sh_type = SHT_PROGBITS; 3119 sec->header.sh_flags = SHF_WRITE | SHF_ALLOC; 3120 sec->name = ".bss"; 3121 sec->idx = i; 3122 } 3123 3124 /* Allocate the COMMONS. */ 3125 { 3126 ElfW(Addr) bss_size = f->sections[i]->header.sh_size; 3127 ElfW(Addr) max_align = f->sections[i]->header.sh_addralign; 3128 struct common_entry *c; 3129 3130 for (c = common_head; c; c = c->next) { 3131 ElfW(Addr) align = c->sym->value; 3132 3133 if (align > max_align) 3134 max_align = align; 3135 if (bss_size & (align - 1)) 3136 bss_size = (bss_size | (align - 1)) + 1; 3137 3138 c->sym->secidx = i; 3139 c->sym->value = bss_size; 3140 3141 bss_size += c->sym->size; 3142 } 3143 3144 f->sections[i]->header.sh_size = bss_size; 3145 f->sections[i]->header.sh_addralign = max_align; 3146 } 3147 } 3148 3149 /* For the sake of patch relocation and parameter initialization, 3150 allocate zeroed data for NOBITS sections now. Note that after 3151 this we cannot assume NOBITS are really empty. */ 3152 for (i = 0; i < f->header.e_shnum; ++i) { 3153 struct obj_section *s = f->sections[i]; 3154 if (s->header.sh_type == SHT_NOBITS) { 3155 if (s->header.sh_size != 0) 3156 s->contents = memset(xmalloc(s->header.sh_size), 3157 0, s->header.sh_size); 3158 else 3159 s->contents = NULL; 3160 3161 s->header.sh_type = SHT_PROGBITS; 3162 } 3163 } 3164 } 3165 3166 static unsigned long obj_load_size(struct obj_file *f) 3167 { 3168 unsigned long dot = 0; 3169 struct obj_section *sec; 3170 3171 /* Finalize the positions of the sections relative to one another. */ 3172 3173 for (sec = f->load_order; sec; sec = sec->load_next) { 3174 ElfW(Addr) align; 3175 3176 align = sec->header.sh_addralign; 3177 if (align && (dot & (align - 1))) 3178 dot = (dot | (align - 1)) + 1; 3179 3180 sec->header.sh_addr = dot; 3181 dot += sec->header.sh_size; 3182 } 3183 3184 return dot; 3185 } 3186 3187 static int obj_relocate(struct obj_file *f, ElfW(Addr) base) 3188 { 3189 int i, n = f->header.e_shnum; 3190 int ret = 1; 3191 3192 /* Finalize the addresses of the sections. */ 3193 3194 f->baseaddr = base; 3195 for (i = 0; i < n; ++i) 3196 f->sections[i]->header.sh_addr += base; 3197 3198 /* And iterate over all of the relocations. */ 3199 3200 for (i = 0; i < n; ++i) { 3201 struct obj_section *relsec, *symsec, *targsec, *strsec; 3202 ElfW(RelM) * rel, *relend; 3203 ElfW(Sym) * symtab; 3204 const char *strtab; 3205 3206 relsec = f->sections[i]; 3207 if (relsec->header.sh_type != SHT_RELM) 3208 continue; 3209 3210 symsec = f->sections[relsec->header.sh_link]; 3211 targsec = f->sections[relsec->header.sh_info]; 3212 strsec = f->sections[symsec->header.sh_link]; 3213 3214 rel = (ElfW(RelM) *) relsec->contents; 3215 relend = rel + (relsec->header.sh_size / sizeof(ElfW(RelM))); 3216 symtab = (ElfW(Sym) *) symsec->contents; 3217 strtab = (const char *) strsec->contents; 3218 3219 for (; rel < relend; ++rel) { 3220 ElfW(Addr) value = 0; 3221 struct obj_symbol *intsym = NULL; 3222 unsigned long symndx; 3223 ElfW(Sym) * extsym = 0; 3224 const char *errmsg; 3225 3226 /* Attempt to find a value to use for this relocation. */ 3227 3228 symndx = ELF_R_SYM(rel->r_info); 3229 if (symndx) { 3230 /* Note we've already checked for undefined symbols. */ 3231 3232 extsym = &symtab[symndx]; 3233 if (ELF_ST_BIND(extsym->st_info) == STB_LOCAL) { 3234 /* Local symbols we look up in the local table to be sure 3235 we get the one that is really intended. */ 3236 intsym = f->local_symtab[symndx]; 3237 } else { 3238 /* Others we look up in the hash table. */ 3239 const char *name; 3240 if (extsym->st_name) 3241 name = strtab + extsym->st_name; 3242 else 3243 name = f->sections[extsym->st_shndx]->name; 3244 intsym = obj_find_symbol(f, name); 3245 } 3246 3247 value = obj_symbol_final_value(f, intsym); 3248 intsym->referenced = 1; 3249 } 3250 #if SHT_RELM == SHT_RELA 3251 #if defined(__alpha__) && defined(AXP_BROKEN_GAS) 3252 /* Work around a nasty GAS bug, that is fixed as of 2.7.0.9. */ 3253 if (!extsym || !extsym->st_name || 3254 ELF_ST_BIND(extsym->st_info) != STB_LOCAL) 3255 #endif 3256 value += rel->r_addend; 3257 #endif 3258 3259 /* Do it! */ 3260 switch (arch_apply_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"; 3274 bad_reloc: 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; 3285 } 3286 } 3287 } 3288 3289 /* Finally, take care of the patches. */ 3290 3291 if (f->string_patches) { 3292 struct obj_string_patch *p; 3293 struct obj_section *strsec; 3294 ElfW(Addr) strsec_base; 3295 strsec = obj_find_section(f, ".kstrtab"); 3296 strsec_base = strsec->header.sh_addr; 3297 3298 for (p = f->string_patches; p; p = p->next) { 3299 struct obj_section *targsec = f->sections[p->reloc_secidx]; 3300 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset) 3301 = strsec_base + p->string_offset; 3302 } 3303 } 3304 3305 if (f->symbol_patches) { 3306 struct obj_symbol_patch *p; 3307 3308 for (p = f->symbol_patches; p; p = p->next) { 3309 struct obj_section *targsec = f->sections[p->reloc_secidx]; 3310 *(ElfW(Addr) *) (targsec->contents + p->reloc_offset) 3311 = obj_symbol_final_value(f, p->sym); 3312 } 3313 } 3314 3315 return ret; 3316 } 3317 3318 static int obj_create_image(struct obj_file *f, char *image) 3319 { 3320 struct obj_section *sec; 3321 ElfW(Addr) base = f->baseaddr; 3322 3323 for (sec = f->load_order; sec; sec = sec->load_next) { 3324 char *secimg; 3325 3326 if (sec->contents == 0 || sec->header.sh_size == 0) 3327 continue; 3328 3329 secimg = image + (sec->header.sh_addr - base); 3330 3331 /* Note that we allocated data for NOBITS sections earlier. */ 3332 memcpy(secimg, sec->contents, sec->header.sh_size); 3333 } 3334 3335 return 1; 3336 } 3337 3338 /*======================================================================*/ 3339 3340 static struct obj_file *obj_load(FILE * fp, int loadprogbits) 3341 { 3342 struct obj_file *f; 3343 ElfW(Shdr) * section_headers; 3344 int shnum, i; 3345 char *shstrtab; 3346 3347 /* Read the file header. */ 3348 3349 f = arch_new_file(); 3350 memset(f, 0, sizeof(*f)); 3351 f->symbol_cmp = strcmp; 3352 f->symbol_hash = obj_elf_hash; 3353 f->load_order_search_start = &f->load_order; 3354 3355 fseek(fp, 0, SEEK_SET); 3356 if (fread(&f->header, sizeof(f->header), 1, fp) != 1) { 3357 bb_perror_msg("error reading ELF header"); 3358 return NULL; 3359 } 3360 3361 if (f->header.e_ident[EI_MAG0] != ELFMAG0 3362 || f->header.e_ident[EI_MAG1] != ELFMAG1 3363 || f->header.e_ident[EI_MAG2] != ELFMAG2 3364 || f->header.e_ident[EI_MAG3] != ELFMAG3) { 3365 bb_error_msg("not an ELF file"); 3366 return NULL; 3367 } 3368 if (f->header.e_ident[EI_CLASS] != ELFCLASSM 3369 || f->header.e_ident[EI_DATA] != (BB_BIG_ENDIAN 3370 ? ELFDATA2MSB : ELFDATA2LSB) 3371 || f->header.e_ident[EI_VERSION] != EV_CURRENT 3372 || !MATCH_MACHINE(f->header.e_machine)) { 3373 bb_error_msg("ELF file not for this architecture"); 3374 return NULL; 3375 } 3376 if (f->header.e_type != ET_REL) { 3377 bb_error_msg("ELF file not a relocatable object"); 3378 return NULL; 3379 } 3380 3381 /* Read the section headers. */ 3382 3383 if (f->header.e_shentsize != sizeof(ElfW(Shdr))) { 3384 bb_error_msg("section header size mismatch: %lu != %lu", 3385 (unsigned long) f->header.e_shentsize, 3386 (unsigned long) sizeof(ElfW(Shdr))); 3387 return NULL; 3388 } 3389 3390 shnum = f->header.e_shnum; 3391 f->sections = xmalloc(sizeof(struct obj_section *) * shnum); 3392 memset(f->sections, 0, sizeof(struct obj_section *) * shnum); 3393 3394 section_headers = alloca(sizeof(ElfW(Shdr)) * shnum); 3395 fseek(fp, f->header.e_shoff, SEEK_SET); 3396 if (fread(section_headers, sizeof(ElfW(Shdr)), shnum, fp) != shnum) { 3397 bb_perror_msg("error reading ELF section headers"); 3398 return NULL; 3399 } 3400 3401 /* Read the section data. */ 3402 3403 for (i = 0; i < shnum; ++i) { 3404 struct obj_section *sec; 3405 3406 f->sections[i] = sec = arch_new_section(); 3407 memset(sec, 0, sizeof(*sec)); 3408 3409 sec->header = section_headers[i]; 3410 sec->idx = i; 3411 3412 if (sec->header.sh_size) { 3413 switch (sec->header.sh_type) { 3414 case SHT_NULL: 3415 case SHT_NOTE: 3416 case SHT_NOBITS: 3417 /* ignore */ 3418 break; 3419 3420 case SHT_PROGBITS: 3421 #if LOADBITS 3422 if (!loadprogbits) { 3423 sec->contents = NULL; 3424 break; 3425 } 3426 #endif 3427 case SHT_SYMTAB: 3428 case SHT_STRTAB: 3429 case SHT_RELM: 3430 if (sec->header.sh_size > 0) { 3431 sec->contents = xmalloc(sec->header.sh_size); 3432 fseek(fp, sec->header.sh_offset, SEEK_SET); 3433 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) { 3434 bb_perror_msg("error reading ELF section data"); 3435 return NULL; 3436 } 3437 } else { 3438 sec->contents = NULL; 3439 } 3440 break; 3441 3442 #if SHT_RELM == SHT_REL 3443 case SHT_RELA: 3444 bb_error_msg("RELA relocations not supported on this architecture"); 3445 return NULL; 3446 #else 3447 case SHT_REL: 3448 bb_error_msg("REL relocations not supported on this architecture"); 3449 return NULL; 3450 #endif 3451 3452 default: 3453 if (sec->header.sh_type >= SHT_LOPROC) { 3454 /* Assume processor specific section types are debug 3455 info and can safely be ignored. If this is ever not 3456 the case (Hello MIPS?), don't put ifdefs here but 3457 create an arch_load_proc_section(). */ 3458 break; 3459 } 3460 3461 bb_error_msg("can't handle sections of type %ld", 3462 (long) sec->header.sh_type); 3463 return NULL; 3464 } 3465 } 3466 } 3467 3468 /* Do what sort of interpretation as needed by each section. */ 3469 3470 shstrtab = f->sections[f->header.e_shstrndx]->contents; 3471 3472 for (i = 0; i < shnum; ++i) { 3473 struct obj_section *sec = f->sections[i]; 3474 sec->name = shstrtab + sec->header.sh_name; 3475 } 3476 3477 for (i = 0; i < shnum; ++i) { 3478 struct obj_section *sec = f->sections[i]; 3479 3480 /* .modinfo should be contents only but gcc has no attribute for that. 3481 * The kernel may have marked .modinfo as ALLOC, ignore this bit. 3482 */ 3483 if (strcmp(sec->name, ".modinfo") == 0) 3484 sec->header.sh_flags &= ~SHF_ALLOC; 3485 3486 if (sec->header.sh_flags & SHF_ALLOC) 3487 obj_insert_section_load_order(f, sec); 3488 3489 switch (sec->header.sh_type) { 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", 3498 (unsigned long) sec->header.sh_entsize, 3499 (unsigned long) sizeof(ElfW(Sym))); 3500 return NULL; 3501 } 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(). */ 3550 } 3551 } 3552 3553 return f; 3554 } 3555 3556 #if ENABLE_FEATURE_INSMOD_LOADINKMEM 3557 /* 3558 * load the unloaded sections directly into the memory allocated by 3559 * kernel for the module 3560 */ 3561 3562 static int obj_load_progbits(FILE * fp, struct obj_file* f, char* imagebase) 3563 { 3564 ElfW(Addr) base = f->baseaddr; 3565 struct obj_section* sec; 3566 3567 for (sec = f->load_order; sec; sec = sec->load_next) { 3568 3569 /* section already loaded? */ 3570 if (sec->contents != NULL) 3571 continue; 3572 3573 if (sec->header.sh_size == 0) 3574 continue; 3575 3576 sec->contents = imagebase + (sec->header.sh_addr - base); 3577 fseek(fp, sec->header.sh_offset, SEEK_SET); 3578 if (fread(sec->contents, sec->header.sh_size, 1, fp) != 1) { 3579 bb_perror_msg("error reading ELF section data"); 3580 return 0; 3581 } 3582 3583 } 3584 return 1; 3585 } 3586 #endif 3587 3588 static void hide_special_symbols(struct obj_file *f) 3589 { 3590 static const char *const specials[] = { 3591 SPFX "cleanup_module", 3592 SPFX "init_module", 3593 SPFX "kernel_version", 3594 NULL 3595 }; 3596 3597 struct obj_symbol *sym; 3598 const char *const *p; 3599 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 3609 static int obj_gpl_license(struct obj_file *f, const char **license) 3610 { 3611 struct obj_section *sec; 3612 /* This list must match *exactly* the list of allowable licenses in 3613 * linux/include/linux/module.h. Checking for leading "GPL" will not 3614 * work, somebody will use "GPL sucks, this is proprietary". 3615 */ 3616 static const char *const gpl_licenses[] = { 3617 "GPL", 3618 "GPL v2", 3619 "GPL and additional rights", 3620 "Dual BSD/GPL", 3621 "Dual MPL/GPL" 3622 }; 3623 3624 sec = obj_find_section(f, ".modinfo"); 3625 if (sec) { 3626 const char *value, *ptr, *endptr; 3627 ptr = sec->contents; 3628 endptr = ptr + sec->header.sh_size; 3629 while (ptr < endptr) { 3630 value = strchr(ptr, '='); 3631 if (value && strncmp(ptr, "license", value-ptr) == 0) { 3632 int i; 3633 if (license) 3634 *license = value+1; 3635 for (i = 0; i < ARRAY_SIZE(gpl_licenses); ++i) { 3636 if (strcmp(value+1, gpl_licenses[i]) == 0) 3637 return 0; 3638 } 3639 return 2; 3640 } 3641 if (strchr(ptr, '\0')) 3642 ptr = strchr(ptr, '\0') + 1; 3643 else 3644 ptr = endptr; 3645 } 3646 } 3647 return 1; 3648 } 3649 3650 #define TAINT_FILENAME "/proc/sys/kernel/tainted" 3651 #define TAINT_PROPRIETORY_MODULE (1<<0) 3652 #define TAINT_FORCED_MODULE (1<<1) 3653 #define TAINT_UNSAFE_SMP (1<<2) 3654 #define TAINT_URL "http://www.tux.org/lkml/#export-tainted" 3655 3656 static void set_tainted(struct obj_file *f, int fd, char *m_name, 3657 int kernel_has_tainted, int taint, const char *text1, const char *text2) 3658 { 3659 static smallint printed_info; 3660 3661 char buf[80]; 3662 int oldval; 3663 3664 if (fd < 0 && !kernel_has_tainted) 3665 return; /* New modutils on old kernel */ 3666 printf("Warning: loading %s will taint the kernel: %s%s\n", 3667 m_name, text1, text2); 3668 if (!printed_info) { 3669 printf(" See %s for information about tainted modules\n", TAINT_URL); 3670 printed_info = 1; 3671 } 3672 if (fd >= 0) { 3673 read(fd, buf, sizeof(buf)-1); 3674 buf[sizeof(buf)-1] = '\0'; 3675 oldval = strtoul(buf, NULL, 10); 3676 sprintf(buf, "%d\n", oldval | taint); 3677 write(fd, buf, strlen(buf)); 3678 } 3679 } 3680 3681 /* Check if loading this module will taint the kernel. */ 3682 static void check_tainted_module(struct obj_file *f, char *m_name) 3683 { 3684 static const char tainted_file[] ALIGN1 = TAINT_FILENAME; 3685 3686 int fd, kernel_has_tainted; 3687 const char *ptr; 3688 3689 kernel_has_tainted = 1; 3690 fd = open(tainted_file, O_RDWR); 3691 if (fd < 0) { 3692 if (errno == ENOENT) 3693 kernel_has_tainted = 0; 3694 else if (errno == EACCES) 3695 kernel_has_tainted = 1; 3696 else { 3697 perror(tainted_file); 3698 kernel_has_tainted = 0; 3699 } 3700 } 3701 3702 switch (obj_gpl_license(f, &ptr)) { 3703 case 0: 3704 break; 3705 case 1: 3706 set_tainted(f, fd, m_name, kernel_has_tainted, TAINT_PROPRIETORY_MODULE, "no license", ""); 3707 break; 3708 case 2: 3709 /* 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 3711 * kernels without the proc flag. 3712 */ 3713 set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "non-GPL license - ", ptr); 3714 break; 3715 default: 3716 set_tainted(f, fd, m_name, 1, TAINT_PROPRIETORY_MODULE, "Unexpected return from obj_gpl_license", ""); 3717 break; 3718 } 3719 3720 if (flag_force_load) 3721 set_tainted(f, fd, m_name, 1, TAINT_FORCED_MODULE, "forced load", ""); 3722 3723 if (fd >= 0) 3724 close(fd); 3725 } 3726 #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 3731 /* add module source, timestamp, kernel version and a symbol for the 3732 * start of some sections. this info is used by ksymoops to do better 3733 * debugging. 3734 */ 3735 static int 3736 get_module_version(struct obj_file *f, char str[STRVERSIONLEN]) 3737 { 3738 #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 3739 return new_get_module_version(f, str); 3740 #else /* FEATURE_INSMOD_VERSION_CHECKING */ 3741 strncpy(str, "???", sizeof(str)); 3742 return -1; 3743 #endif /* FEATURE_INSMOD_VERSION_CHECKING */ 3744 } 3745 3746 /* add module source, timestamp, kernel version and a symbol for the 3747 * start of some sections. this info is used by ksymoops to do better 3748 * debugging. 3749 */ 3750 static void 3751 add_ksymoops_symbols(struct obj_file *f, const char *filename, 3752 const char *m_name) 3753 { 3754 static const char symprefix[] ALIGN1 = "__insmod_"; 3755 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", 3765 ".rodata", 3766 ".data", 3767 ".bss", 3768 ".sbss" 3769 }; 3770 3771 if (realpath(filename, real)) { 3772 absolute_filename = xstrdup(real); 3773 } else { 3774 bb_perror_msg("cannot get realpath for %s", filename); 3775 absolute_filename = xstrdup(filename); 3776 } 3777 3778 lm_name = strlen(m_name); 3779 lfilename = strlen(absolute_filename); 3780 3781 /* add to ksymtab if it already exists or there is no ksymtab and other symbols 3782 * are not to be exported. otherwise leave ksymtab alone for now, the 3783 * "export all symbols" compatibility code will export these symbols later. 3784 */ 3785 use_ksymtab = obj_find_section(f, "__ksymtab") || flag_noexport; 3786 3787 sec = obj_find_section(f, ".this"); 3788 if (sec) { 3789 /* tag the module header with the object name, last modified 3790 * timestamp and module version. worst case for module version 3791 * is 0xffffff, decimal 16777215. putting all three fields in 3792 * one symbol is less readable but saves kernel space. 3793 */ 3794 l = sizeof(symprefix)+ /* "__insmod_" */ 3795 lm_name+ /* module name */ 3796 2+ /* "_O" */ 3797 lfilename+ /* object filename */ 3798 2+ /* "_M" */ 3799 2*sizeof(statbuf.st_mtime)+ /* mtime in hex */ 3800 2+ /* "_V" */ 3801 8+ /* version in dec */ 3802 1; /* nul */ 3803 name = xmalloc(l); 3804 if (stat(absolute_filename, &statbuf) != 0) 3805 statbuf.st_mtime = 0; 3806 version = get_module_version(f, str); /* -1 if not found */ 3807 snprintf(name, l, "%s%s_O%s_M%0*lX_V%d", 3808 symprefix, m_name, absolute_filename, 3809 (int)(2*sizeof(statbuf.st_mtime)), statbuf.st_mtime, 3810 version); 3811 sym = obj_add_symbol(f, name, -1, 3812 ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE), 3813 sec->idx, sec->header.sh_addr, 0); 3814 if (use_ksymtab) 3815 new_add_ksymtab(f, sym); 3816 } 3817 free(absolute_filename); 3818 #ifdef _NOT_SUPPORTED_ 3819 /* record where the persistent data is going, same address as previous symbol */ 3820 3821 if (f->persist) { 3822 l = sizeof(symprefix)+ /* "__insmod_" */ 3823 lm_name+ /* module name */ 3824 2+ /* "_P" */ 3825 strlen(f->persist)+ /* data store */ 3826 1; /* nul */ 3827 name = xmalloc(l); 3828 snprintf(name, l, "%s%s_P%s", 3829 symprefix, m_name, f->persist); 3830 sym = obj_add_symbol(f, name, -1, ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE), 3831 sec->idx, sec->header.sh_addr, 0); 3832 if (use_ksymtab) 3833 new_add_ksymtab(f, sym); 3834 } 3835 #endif /* _NOT_SUPPORTED_ */ 3836 /* tag the desired sections if size is non-zero */ 3837 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) { 3841 l = sizeof(symprefix)+ /* "__insmod_" */ 3842 lm_name+ /* module name */ 3843 2+ /* "_S" */ 3844 strlen(sec->name)+ /* section name */ 3845 2+ /* "_L" */ 3846 8+ /* length in dec */ 3847 1; /* nul */ 3848 name = xmalloc(l); 3849 snprintf(name, l, "%s%s_S%s_L%ld", 3850 symprefix, m_name, sec->name, 3851 (long)sec->header.sh_size); 3852 sym = obj_add_symbol(f, name, -1, ELF_ST_INFO(STB_GLOBAL, STT_NOTYPE), 3853 sec->idx, sec->header.sh_addr, 0); 3854 if (use_ksymtab) 3855 new_add_ksymtab(f, sym); 3856 } 3857 } 3858 } 3859 #endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */ 3860 3861 #if ENABLE_FEATURE_INSMOD_LOAD_MAP 3862 static void print_load_map(struct obj_file *f) 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; 3868 struct obj_symbol *sym; 3869 #endif 3870 /* Report on the section layout. */ 3871 3872 printf("Sections: Size %-*s Align\n", 3873 (int) (2 * sizeof(void *)), "Address"); 3874 3875 for (sec = f->load_order; sec; sec = sec->load_next) { 3876 int a; 3877 unsigned long tmp; 3878 3879 for (a = -1, tmp = sec->header.sh_addralign; tmp; ++a) 3880 tmp >>= 1; 3881 if (a == -1) 3882 a = 0; 3883 3884 printf("%-15s %08lx %0*lx 2**%d\n", 3885 sec->name, 3886 (long)sec->header.sh_size, 3887 (int) (2 * sizeof(void *)), 3888 (long)sec->header.sh_addr, 3889 a); 3890 } 3891 #if ENABLE_FEATURE_INSMOD_LOAD_MAP_FULL 3892 /* Quick reference which section indicies are loaded. */ 3893 3894 loaded = alloca(sizeof(int) * (i = f->header.e_shnum)); 3895 while (--i >= 0) 3896 loaded[i] = (f->sections[i]->header.sh_flags & SHF_ALLOC) != 0; 3897 3898 /* Collect the symbols we'll be listing. */ 3899 3900 for (nsyms = i = 0; i < HASH_BUCKETS; ++i) 3901 for (sym = f->symtab[i]; sym; sym = sym->next) 3902 if (sym->secidx <= SHN_HIRESERVE 3903 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])) 3904 ++nsyms; 3905 3906 all = alloca(nsyms * sizeof(struct obj_symbol *)); 3907 3908 for (i = 0, p = all; i < HASH_BUCKETS; ++i) 3909 for (sym = f->symtab[i]; sym; sym = sym->next) 3910 if (sym->secidx <= SHN_HIRESERVE 3911 && (sym->secidx >= SHN_LORESERVE || loaded[sym->secidx])) 3912 *p++ = sym; 3913 3914 /* And list them. */ 3915 printf("\nSymbols:\n"); 3916 for (p = all; p < all + nsyms; ++p) { 3917 char type = '?'; 3918 unsigned long value; 3919 3920 sym = *p; 3921 if (sym->secidx == SHN_ABS) { 3922 type = 'A'; 3923 value = sym->value; 3924 } else if (sym->secidx == SHN_UNDEF) { 3925 type = 'U'; 3926 value = 0; 3927 } else { 3928 sec = f->sections[sym->secidx]; 3929 3930 if (sec->header.sh_type == SHT_NOBITS) 3931 type = 'B'; 3932 else if (sec->header.sh_flags & SHF_ALLOC) { 3933 if (sec->header.sh_flags & SHF_EXECINSTR) 3934 type = 'T'; 3935 else if (sec->header.sh_flags & SHF_WRITE) 3936 type = 'D'; 3937 else 3938 type = 'R'; 3939 } 3940 value = sym->value + sec->header.sh_addr; 3941 } 3942 3943 if (ELF_ST_BIND(sym->info) == STB_LOCAL) 3944 type = tolower(type); 3945 3946 printf("%0*lx %c %s\n", (int) (2 * sizeof(void *)), value, 3947 type, sym->name); 3948 } 3949 #endif 3950 } 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); 3956 int insmod_main( int argc, char **argv) 3957 { 3958 char *opt_o, *arg1; 3959 int len; 3960 int k_crcs; 3961 char *tmp, *tmp1; 3962 unsigned long m_size; 3963 ElfW(Addr) m_addr; 3964 struct obj_file *f; 3965 struct stat st; 3966 char *m_name = 0; 3967 int exit_status = EXIT_FAILURE; 3968 int m_has_modinfo; 3969 #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 3970 struct utsname uts_info; 3971 char m_strversion[STRVERSIONLEN]; 3972 int m_version, m_crcs; 3973 #endif 3974 #if ENABLE_FEATURE_CLEAN_UP 3975 FILE *fp = 0; 3976 #else 3977 FILE *fp; 3978 #endif 3979 int k_version = 0; 3980 struct utsname myuname; 3981 3982 /* Parse any options */ 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) { 3991 bb_show_usage(); 3992 } 3993 3994 /* Grab the module name */ 3995 tmp1 = xstrdup(arg1); 3996 tmp = basename(tmp1); 3997 len = strlen(tmp); 3998 3999 if (uname(&myuname) == 0) { 4000 if (myuname.release[0] == '2') { 4001 k_version = myuname.release[2] - '0'; 4002 } 4003 } 4004 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; 4010 tmp[len] = '\0'; 4011 } else 4012 #endif 4013 if (len > 2 && tmp[len - 2] == '.' && tmp[len - 1] == 'o') { 4014 len -= 2; 4015 tmp[len] = '\0'; 4016 } 4017 4018 4019 #if ENABLE_FEATURE_2_6_MODULES 4020 if (k_version > 4) 4021 m_fullName = xasprintf("%s.ko", tmp); 4022 else 4023 #endif 4024 m_fullName = xasprintf("%s.o", tmp); 4025 4026 if (!m_name) { 4027 m_name = tmp; 4028 } else { 4029 free(tmp1); 4030 tmp1 = 0; /* flag for free(m_name) before exit() */ 4031 } 4032 4033 /* Get a filedesc for the module. Check we we have a complete path */ 4034 if (stat(arg1, &st) < 0 || !S_ISREG(st.st_mode) 4035 || (fp = fopen(arg1, "r")) == NULL 4036 ) { 4037 /* Hmm. Could not open it. First search under /lib/modules/`uname -r`, 4038 * but do not error out yet if we fail to find it... */ 4039 if (k_version) { /* uname succeedd */ 4040 char *module_dir; 4041 char *tmdn; 4042 char real_module_dir[FILENAME_MAX]; 4043 4044 tmdn = concat_path_file(_PATH_MODULES, myuname.release); 4045 /* Jump through hoops in case /lib/modules/`uname -r` 4046 * is a symlink. We do not want recursive_action to 4047 * follow symlinks, but we do want to follow the 4048 * /lib/modules/`uname -r` dir, So resolve it ourselves 4049 * if it is a link... */ 4050 if (realpath(tmdn, real_module_dir) == NULL) 4051 module_dir = tmdn; 4052 else 4053 module_dir = real_module_dir; 4054 recursive_action(module_dir, ACTION_RECURSE, 4055 check_module_name_match, 0, m_fullName, 0); 4056 free(tmdn); 4057 } 4058 4059 /* Check if we have found anything yet */ 4060 if (m_filename == 0 || ((fp = fopen(m_filename, "r")) == NULL)) { 4061 char module_dir[FILENAME_MAX]; 4062 4063 free(m_filename); 4064 m_filename = 0; 4065 if (realpath (_PATH_MODULES, module_dir) == NULL) 4066 strcpy(module_dir, _PATH_MODULES); 4067 /* No module found under /lib/modules/`uname -r`, this 4068 * time cast the net a bit wider. Search /lib/modules/ */ 4069 if (!recursive_action(module_dir, ACTION_RECURSE, 4070 check_module_name_match, 0, m_fullName, 0) 4071 ) { 4072 if (m_filename == 0 4073 || ((fp = fopen(m_filename, "r")) == NULL) 4074 ) { 4075 bb_error_msg("%s: no module by that name found", m_fullName); 4076 goto out; 4077 } 4078 } else 4079 bb_error_msg_and_die("%s: no module by that name found", m_fullName); 4080 } 4081 } else 4082 m_filename = xstrdup(arg1); 4083 4084 if (flag_verbose) 4085 printf("Using %s\n", m_filename); 4086 4087 #if ENABLE_FEATURE_2_6_MODULES 4088 if (k_version > 4) { 4089 argv[optind] = m_filename; 4090 optind--; 4091 return insmod_ng_main(argc - optind, argv + optind); 4092 } 4093 #endif 4094 4095 f = obj_load(fp, LOADBITS); 4096 if (f == NULL) 4097 bb_perror_msg_and_die("cannot load the module"); 4098 4099 if (get_modinfo_value(f, "kernel_version") == NULL) 4100 m_has_modinfo = 0; 4101 else 4102 m_has_modinfo = 1; 4103 4104 #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 4105 /* Version correspondence? */ 4106 if (!flag_quiet) { 4107 if (uname(&uts_info) < 0) 4108 uts_info.release[0] = '\0'; 4109 if (m_has_modinfo) { 4110 m_version = new_get_module_version(f, m_strversion); 4111 if (m_version == -1) { 4112 bb_error_msg("cannot find the kernel version the module was " 4113 "compiled for"); 4114 goto out; 4115 } 4116 } 4117 4118 if (strncmp(uts_info.release, m_strversion, STRVERSIONLEN) != 0) { 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) 4125 goto out; 4126 } 4127 } 4128 k_crcs = 0; 4129 #endif /* FEATURE_INSMOD_VERSION_CHECKING */ 4130 4131 if (!query_module(NULL, 0, NULL, 0, NULL)) { 4132 if (!new_get_kernel_symbols()) 4133 goto out; 4134 k_crcs = new_is_kernel_checksummed(); 4135 } else { 4136 bb_error_msg("not configured to support old kernels"); 4137 goto out; 4138 } 4139 4140 #if ENABLE_FEATURE_INSMOD_VERSION_CHECKING 4141 m_crcs = 0; 4142 if (m_has_modinfo) 4143 m_crcs = new_is_module_checksummed(f); 4144 4145 if (m_crcs != k_crcs) 4146 obj_set_symbol_compare(f, ncv_strcmp, ncv_symbol_hash); 4147 #endif /* FEATURE_INSMOD_VERSION_CHECKING */ 4148 4149 /* Let the module know about the kernel symbols. */ 4150 add_kernel_symbols(f); 4151 4152 /* Allocate common symbols, symbol tables, and string tables. */ 4153 4154 if (!new_create_this_module(f, m_name)) { 4155 goto out; 4156 } 4157 4158 if (!obj_check_undefineds(f)) { 4159 goto out; 4160 } 4161 obj_allocate_commons(f); 4162 check_tainted_module(f, m_name); 4163 4164 /* done with the module name, on to the optional var=value arguments */ 4165 ++optind; 4166 if (optind < argc) { 4167 if (!new_process_module_arguments(f, argc - optind, argv + optind)) { 4168 goto out; 4169 } 4170 } 4171 4172 arch_create_got(f); 4173 hide_special_symbols(f); 4174 4175 #if ENABLE_FEATURE_INSMOD_KSYMOOPS_SYMBOLS 4176 add_ksymoops_symbols(f, m_filename, m_name); 4177 #endif /* FEATURE_INSMOD_KSYMOOPS_SYMBOLS */ 4178 4179 new_create_module_ksymtab(f); 4180 4181 /* Find current size of the module */ 4182 m_size = obj_load_size(f); 4183 4184 4185 m_addr = create_module(m_name, m_size); 4186 if (m_addr == -1) switch (errno) { 4187 case EEXIST: 4188 bb_error_msg("a module named %s already exists", m_name); 4189 goto out; 4190 case ENOMEM: 4191 bb_error_msg("can't allocate kernel memory for module; needed %lu bytes", 4192 m_size); 4193 goto out; 4194 default: 4195 bb_perror_msg("create_module: %s", m_name); 4196 goto out; 4197 } 4198 4199 #if !LOADBITS 4200 /* 4201 * the PROGBITS section was not loaded by the obj_load 4202 * now we can load them directly into the kernel memory 4203 */ 4204 if (!obj_load_progbits(fp, f, (char*)m_addr)) { 4205 delete_module(m_name); 4206 goto out; 4207 } 4208 #endif 4209 4210 if (!obj_relocate(f, m_addr)) { 4211 delete_module(m_name); 4212 goto out; 4213 } 4214 4215 if (!new_init_module(m_name, f, m_size)) { 4216 delete_module(m_name); 4217 goto out; 4218 } 4219 4220 if (flag_print_load_map) 4221 print_load_map(f); 4222 4223 exit_status = EXIT_SUCCESS; 4224 4225 out: 4226 #if ENABLE_FEATURE_CLEAN_UP 4227 if (fp) 4228 fclose(fp); 4229 free(tmp1); 4230 if (!tmp1) 4231 free(m_name); 4232 free(m_filename); 4233 #endif 4234 return exit_status; 4235 } 4236 4237 4238 #endif 4239 4240 4241 #if ENABLE_FEATURE_2_6_MODULES 4242 4243 #include <sys/mman.h> 4244 #include <asm/unistd.h> 4245 #include <sys/syscall.h> 4246 4247 /* We use error numbers in a loose translation... */ 4248 static const char *moderror(int err) 4249 { 4250 switch (err) { 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; 53 IF_FEATURE_2_4_MODULES( 54 getopt32(argv, INSMOD_OPTS INSMOD_ARGS); 55 argv += optind - 1; 56 ); 4272 57 4273 58 filename = *++argv; … … 4275 60 bb_show_usage(); 4276 61 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 } 62 rc = bb_init_module(filename, parse_cmdline_module_options(argv)); 63 if (rc) 64 bb_error_msg("can't insert '%s': %s", filename, moderror(rc)); 4285 65 4286 #if 0 4287 /* Any special reason why mmap? It isn't performace critical... */ 4288 int fd; 4289 struct stat st; 4290 unsigned long len; 4291 fd = xopen(filename, O_RDONLY); 4292 fstat(fd, &st); 4293 len = st.st_size; 4294 map = mmap(NULL, len, PROT_READ, MAP_PRIVATE, fd, 0); 4295 if (map == MAP_FAILED) { 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 4308 4309 ret = syscall(__NR_init_module, map, len, options); 4310 if (ret != 0) { 4311 bb_perror_msg_and_die("cannot insert '%s': %s (%li)", 4312 filename, moderror(errno), ret); 4313 } 4314 4315 return 0; 66 return rc; 4316 67 } 4317 4318 #endif -
branches/2.2.9/mindi-busybox/modutils/lsmod.c
r1765 r2725 4 4 * 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 * Copyright (C) 2008 by Vladimir Dronnikov <dronnikov@gmail.com> 6 7 * 7 * Modified by Alcove, Julien Gaulmin <julien.gaulmin@alcove.fr> and 8 * Nicolas Ferre <nicolas.ferre@alcove.fr> to support pre 2.1 kernels 9 * (which lack the query_module() interface). 10 * 11 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 8 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 12 9 */ 13 10 11 //applet:IF_LSMOD(APPLET(lsmod, _BB_DIR_SBIN, _BB_SUID_DROP)) 12 13 //usage:#if !ENABLE_MODPROBE_SMALL 14 //usage:#define lsmod_trivial_usage 15 //usage: "" 16 //usage:#define lsmod_full_usage "\n\n" 17 //usage: "List the currently loaded kernel modules" 18 //usage:#endif 19 14 20 #include "libbb.h" 21 #include "unicode.h" 15 22 16 17 #if !ENABLE_FEATURE_CHECK_TAINTED_MODULE 18 static void check_tainted(void) { puts(""); } 19 #else 20 #define TAINT_FILENAME "/proc/sys/kernel/tainted" 21 #define TAINT_PROPRIETORY_MODULE (1<<0) 22 #define TAINT_FORCED_MODULE (1<<1) 23 #define TAINT_UNSAFE_SMP (1<<2) 23 #if ENABLE_FEATURE_CHECK_TAINTED_MODULE 24 enum { 25 TAINT_PROPRIETORY_MODULE = (1 << 0), 26 TAINT_FORCED_MODULE = (1 << 1), 27 TAINT_UNSAFE_SMP = (1 << 2), 28 }; 24 29 25 30 static void check_tainted(void) 26 31 { 27 int tainted; 28 FILE *f; 32 int tainted = 0; 33 char *buf = xmalloc_open_read_close("/proc/sys/kernel/tainted", NULL); 34 if (buf) { 35 tainted = atoi(buf); 36 if (ENABLE_FEATURE_CLEAN_UP) 37 free(buf); 38 } 29 39 30 tainted = 0; 31 if ((f = fopen(TAINT_FILENAME, "r"))) { 32 fscanf(f, "%d", &tainted); 33 fclose(f); 34 } 35 if (f && tainted) { 40 if (tainted) { 36 41 printf(" Tainted: %c%c%c\n", 37 42 tainted & TAINT_PROPRIETORY_MODULE ? 'P' : 'G', 38 43 tainted & TAINT_FORCED_MODULE ? 'F' : ' ', 39 44 tainted & TAINT_UNSAFE_SMP ? 'S' : ' '); 40 } 41 else { 42 printf(" Not tainted\n"); 45 } else { 46 puts(" Not tainted"); 43 47 } 44 48 } 49 #else 50 static void check_tainted(void) { putchar('\n'); } 45 51 #endif 46 52 47 #if ENABLE_FEATURE_QUERY_MODULE_INTERFACE 53 int lsmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 54 int lsmod_main(int argc UNUSED_PARAM, char **argv UNUSED_PARAM) 55 { 56 #if ENABLE_FEATURE_LSMOD_PRETTY_2_6_OUTPUT 57 char *token[4]; 58 parser_t *parser = config_open("/proc/modules"); 59 init_unicode(); 48 60 49 struct module_info 50 { 51 unsigned long addr; 52 unsigned long size; 53 unsigned long flags; 54 long usecount; 55 }; 56 57 58 int query_module(const char *name, int which, void *buf, size_t bufsize, size_t *ret); 59 60 enum { 61 /* Values for query_module's which. */ 62 QM_MODULES = 1, 63 QM_DEPS = 2, 64 QM_REFS = 3, 65 QM_SYMBOLS = 4, 66 QM_INFO = 5, 67 68 /* Bits of module.flags. */ 69 NEW_MOD_RUNNING = 1, 70 NEW_MOD_DELETED = 2, 71 NEW_MOD_AUTOCLEAN = 4, 72 NEW_MOD_VISITED = 8, 73 NEW_MOD_USED_ONCE = 16, 74 NEW_MOD_INITIALIZING = 64 75 }; 76 77 int lsmod_main(int argc, char **argv); 78 int lsmod_main(int argc, char **argv) 79 { 80 struct module_info info; 81 char *module_names, *mn, *deps, *dn; 82 size_t bufsize, depsize, nmod, count, i, j; 83 84 module_names = deps = NULL; 85 bufsize = depsize = 0; 86 while (query_module(NULL, QM_MODULES, module_names, bufsize, &nmod)) { 87 if (errno != ENOSPC) bb_perror_msg_and_die("QM_MODULES"); 88 module_names = xmalloc(bufsize = nmod); 89 } 90 91 deps = xmalloc(depsize = 256); 92 printf("Module\t\t\tSize Used by"); 61 printf("%-24sSize Used by", "Module"); 93 62 check_tainted(); 94 63 95 for (i = 0, mn = module_names; i < nmod; mn += strlen(mn) + 1, i++) { 96 if (query_module(mn, QM_INFO, &info, sizeof(info), &count)) { 97 if (errno == ENOENT) { 98 /* The module was removed out from underneath us. */ 99 continue; 64 if (ENABLE_FEATURE_2_4_MODULES 65 && get_linux_version_code() < KERNEL_VERSION(2,6,0) 66 ) { 67 while (config_read(parser, token, 4, 3, "# \t", PARSE_NORMAL)) { 68 if (token[3] != NULL && token[3][0] == '[') { 69 token[3]++; 70 token[3][strlen(token[3])-1] = '\0'; 71 } else 72 token[3] = (char *) ""; 73 # if ENABLE_UNICODE_SUPPORT 74 { 75 uni_stat_t uni_stat; 76 char *uni_name = unicode_conv_to_printable(&uni_stat, token[0]); 77 unsigned pad_len = (uni_stat.unicode_width > 19) ? 0 : 19 - uni_stat.unicode_width; 78 printf("%s%*s %8s %2s %s\n", uni_name, pad_len, "", token[1], token[2], token[3]); 79 free(uni_name); 100 80 } 101 /* else choke */ 102 bb_perror_msg_and_die("module %s: QM_INFO", mn); 81 # else 82 printf("%-19s %8s %2s %s\n", token[0], token[1], token[2], token[3]); 83 # endif 103 84 } 104 while (query_module(mn, QM_REFS, deps, depsize, &count)) { 105 if (errno == ENOENT) { 106 /* The module was removed out from underneath us. */ 107 continue; 108 } else if (errno != ENOSPC) 109 bb_perror_msg_and_die("module %s: QM_REFS", mn); 110 deps = xrealloc(deps, count); 85 } else { 86 while (config_read(parser, token, 4, 4, "# \t", PARSE_NORMAL & ~PARSE_GREEDY)) { 87 // N.B. token[3] is either '-' (module is not used by others) 88 // or comma-separated list ended by comma 89 // so trimming the trailing char is just what we need! 90 token[3][strlen(token[3])-1] = '\0'; 91 # if ENABLE_UNICODE_SUPPORT 92 { 93 uni_stat_t uni_stat; 94 char *uni_name = unicode_conv_to_printable(&uni_stat, token[0]); 95 unsigned pad_len = (uni_stat.unicode_width > 19) ? 0 : 19 - uni_stat.unicode_width; 96 printf("%s%*s %8s %2s %s\n", uni_name, pad_len, "", token[1], token[2], token[3]); 97 free(uni_name); 98 } 99 # else 100 printf("%-19s %8s %2s %s\n", token[0], token[1], token[2], token[3]); 101 # endif 111 102 } 112 printf("%-20s%8lu%4ld", mn, info.size, info.usecount);113 if (info.flags & NEW_MOD_DELETED)114 printf(" (deleted)");115 else if (info.flags & NEW_MOD_INITIALIZING)116 printf(" (initializing)");117 else if (!(info.flags & NEW_MOD_RUNNING))118 printf(" (uninitialized)");119 else {120 if (info.flags & NEW_MOD_AUTOCLEAN)121 printf(" (autoclean) ");122 if (!(info.flags & NEW_MOD_USED_ONCE))123 printf(" (unused)");124 }125 if (count) printf(" [");126 for (j = 0, dn = deps; j < count; dn += strlen(dn) + 1, j++) {127 printf("%s%s", dn, (j==count-1)? "":" ");128 }129 if (count) printf("]");130 131 puts("");132 103 } 133 134 #if ENABLE_FEATURE_CLEAN_UP 135 free(module_names); 104 if (ENABLE_FEATURE_CLEAN_UP) 105 config_close(parser); 106 #else 107 check_tainted(); 108 xprint_and_close_file(xfopen_for_read("/proc/modules")); 136 109 #endif 137 138 return 0;139 }140 141 #else /* CONFIG_FEATURE_QUERY_MODULE_INTERFACE */142 143 int lsmod_main(int argc, char **argv);144 int lsmod_main(int argc, char **argv)145 {146 FILE *file = xfopen("/proc/modules", "r");147 148 printf("Module Size Used by");149 check_tainted();150 #if defined(CONFIG_FEATURE_LSMOD_PRETTY_2_6_OUTPUT)151 {152 char *line;153 while ((line = xmalloc_fgets(file)) != NULL) {154 char *tok;155 156 tok = strtok(line, " \t");157 printf("%-19s", tok);158 tok = strtok(NULL, " \t\n");159 printf(" %8s", tok);160 tok = strtok(NULL, " \t\n");161 /* Null if no module unloading support. */162 if (tok) {163 printf(" %s", tok);164 tok = strtok(NULL, "\n");165 if (!tok)166 tok = (char*)"";167 /* New-style has commas, or -. If so,168 truncate (other fields might follow). */169 else if (strchr(tok, ',')) {170 tok = strtok(tok, "\t ");171 /* Strip trailing comma. */172 if (tok[strlen(tok)-1] == ',')173 tok[strlen(tok)-1] = '\0';174 } else if (tok[0] == '-'175 && (tok[1] == '\0' || isspace(tok[1]))176 ) {177 tok = (char*)"";178 }179 printf(" %s", tok);180 }181 puts("");182 free(line);183 }184 fclose(file);185 }186 #else187 xprint_and_close_file(file);188 #endif /* CONFIG_FEATURE_2_6_MODULES */189 110 return EXIT_SUCCESS; 190 111 } 191 192 #endif /* CONFIG_FEATURE_QUERY_MODULE_INTERFACE */ -
branches/2.2.9/mindi-busybox/modutils/modprobe.c
r1765 r2725 3 3 * Modprobe written from scratch for BusyBox 4 4 * 5 * Copyright (c) 2002 by Robert Griebl, griebl@gmx.de 6 * Copyright (c) 2003 by Andrew Dennison, andrew.dennison@motec.com.au 7 * Copyright (c) 2005 by Jim Bauer, jfbauer@nfr.com 5 * Copyright (c) 2008 Timo Teras <timo.teras@iki.fi> 6 * Copyright (c) 2008 Vladimir Dronnikov 8 7 * 9 * Portions Copyright (c) 2005 by Yann E. MORIN, yann.morin.1998@anciens.enib.fr 10 * 11 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. 12 */ 8 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 9 */ 10 11 //applet:IF_MODPROBE(APPLET(modprobe, _BB_DIR_SBIN, _BB_SUID_DROP)) 12 13 //usage:#if !ENABLE_MODPROBE_SMALL 14 //usage:#define modprobe_notes_usage 15 //usage: "modprobe can (un)load a stack of modules, passing each module options (when\n" 16 //usage: "loading). modprobe uses a configuration file to determine what option(s) to\n" 17 //usage: "pass each module it loads.\n" 18 //usage: "\n" 19 //usage: "The configuration file is searched (in this order):\n" 20 //usage: "\n" 21 //usage: " /etc/modprobe.conf (2.6 only)\n" 22 //usage: " /etc/modules.conf\n" 23 //usage: " /etc/conf.modules (deprecated)\n" 24 //usage: "\n" 25 //usage: "They all have the same syntax (see below). If none is present, it is\n" 26 //usage: "_not_ an error; each loaded module is then expected to load without\n" 27 //usage: "options. Once a file is found, the others are tested for.\n" 28 //usage: "\n" 29 //usage: "/etc/modules.conf entry format:\n" 30 //usage: "\n" 31 //usage: " alias <alias_name> <mod_name>\n" 32 //usage: " Makes it possible to modprobe alias_name, when there is no such module.\n" 33 //usage: " It makes sense if your mod_name is long, or you want a more representative\n" 34 //usage: " name for that module (eg. 'scsi' in place of 'aha7xxx').\n" 35 //usage: " This makes it also possible to use a different set of options (below) for\n" 36 //usage: " the module and the alias.\n" 37 //usage: " A module can be aliased more than once.\n" 38 //usage: "\n" 39 //usage: " options <mod_name|alias_name> <symbol=value...>\n" 40 //usage: " When loading module mod_name (or the module aliased by alias_name), pass\n" 41 //usage: " the \"symbol=value\" pairs as option to that module.\n" 42 //usage: "\n" 43 //usage: "Sample /etc/modules.conf file:\n" 44 //usage: "\n" 45 //usage: " options tulip irq=3\n" 46 //usage: " alias tulip tulip2\n" 47 //usage: " options tulip2 irq=4 io=0x308\n" 48 //usage: "\n" 49 //usage: "Other functionality offered by 'classic' modprobe is not available in\n" 50 //usage: "this implementation.\n" 51 //usage: "\n" 52 //usage: "If module options are present both in the config file, and on the command line,\n" 53 //usage: "then the options from the command line will be passed to the module _after_\n" 54 //usage: "the options from the config file. That way, you can have defaults in the config\n" 55 //usage: "file, and override them for a specific usage from the command line.\n" 56 //usage:#define modprobe_example_usage 57 //usage: "(with the above /etc/modules.conf):\n\n" 58 //usage: "$ modprobe tulip\n" 59 //usage: " will load the module 'tulip' with default option 'irq=3'\n\n" 60 //usage: "$ modprobe tulip irq=5\n" 61 //usage: " will load the module 'tulip' with option 'irq=5', thus overriding the default\n\n" 62 //usage: "$ modprobe tulip2\n" 63 //usage: " will load the module 'tulip' with default options 'irq=4 io=0x308',\n" 64 //usage: " which are the default for alias 'tulip2'\n\n" 65 //usage: "$ modprobe tulip2 irq=8\n" 66 //usage: " will load the module 'tulip' with default options 'irq=4 io=0x308 irq=8',\n" 67 //usage: " which are the default for alias 'tulip2' overridden by the option 'irq=8'\n\n" 68 //usage: " from the command line\n\n" 69 //usage: "$ modprobe tulip2 irq=2 io=0x210\n" 70 //usage: " will load the module 'tulip' with default options 'irq=4 io=0x308 irq=4 io=0x210',\n" 71 //usage: " which are the default for alias 'tulip2' overridden by the options 'irq=2 io=0x210'\n\n" 72 //usage: " from the command line\n" 73 //usage: 74 //usage:#define modprobe_trivial_usage 75 //usage: "[-alrqvs" 76 //usage: IF_FEATURE_MODPROBE_BLACKLIST("b") 77 //usage: "] MODULE [symbol=value]..." 78 //usage:#define modprobe_full_usage "\n\n" 79 //usage: "Options:" 80 //usage: "\n -a Load multiple MODULEs" 81 //usage: "\n -l List (MODULE is a pattern)" 82 //usage: "\n -r Remove MODULE (stacks) or do autoclean" 83 //usage: "\n -q Quiet" 84 //usage: "\n -v Verbose" 85 //usage: "\n -s Log to syslog" 86 //usage: IF_FEATURE_MODPROBE_BLACKLIST( 87 //usage: "\n -b Apply blacklist to module names too" 88 //usage: ) 89 //usage:#endif /* !ENABLE_MODPROBE_SMALL */ 13 90 14 91 #include "libbb.h" 92 #include "modutils.h" 15 93 #include <sys/utsname.h> 16 94 #include <fnmatch.h> 17 95 18 struct mod_opt_t { /* one-way list of options to pass to a module */ 19 char * m_opt_val; 20 struct mod_opt_t * m_next; 96 //#define DBG(fmt, ...) bb_error_msg("%s: " fmt, __func__, ## __VA_ARGS__) 97 #define DBG(...) ((void)0) 98 99 /* Note that unlike older versions of modules.dep/depmod (busybox and m-i-t), 100 * we expect the full dependency list to be specified in modules.dep. 101 * Older versions would only export the direct dependency list. 102 */ 103 104 /* Note that usage text doesn't document various 2.4 options 105 * we pull in through INSMOD_OPTS define */ 106 107 #define MODPROBE_COMPLEMENTARY "q-v:v-q:l--ar:a--lr:r--al" 108 #define MODPROBE_OPTS "alr" IF_FEATURE_MODPROBE_BLACKLIST("b") 109 //#define MODPROBE_COMPLEMENTARY "q-v:v-q:l--acr:a--lr:r--al" 110 //#define MODPROBE_OPTS "acd:lnrt:C:" IF_FEATURE_MODPROBE_BLACKLIST("b") 111 enum { 112 MODPROBE_OPT_INSERT_ALL = (INSMOD_OPT_UNUSED << 0), /* a */ 113 //MODPROBE_OPT_DUMP_ONLY= (INSMOD_OPT_UNUSED << x), /* c */ 114 //MODPROBE_OPT_DIRNAME = (INSMOD_OPT_UNUSED << x), /* d */ 115 MODPROBE_OPT_LIST_ONLY = (INSMOD_OPT_UNUSED << 1), /* l */ 116 //MODPROBE_OPT_SHOW_ONLY= (INSMOD_OPT_UNUSED << x), /* n */ 117 MODPROBE_OPT_REMOVE = (INSMOD_OPT_UNUSED << 2), /* r */ 118 //MODPROBE_OPT_RESTRICT = (INSMOD_OPT_UNUSED << x), /* t */ 119 //MODPROBE_OPT_VERONLY = (INSMOD_OPT_UNUSED << x), /* V */ 120 //MODPROBE_OPT_CONFIGFILE=(INSMOD_OPT_UNUSED << x), /* C */ 121 MODPROBE_OPT_BLACKLIST = (INSMOD_OPT_UNUSED << 3) * ENABLE_FEATURE_MODPROBE_BLACKLIST, 21 122 }; 22 123 23 struct dep_t { /* one-way list of dependency rules */ 24 /* a dependency rule */ 25 char * m_name; /* the module name*/ 26 char * m_path; /* the module file path */ 27 struct mod_opt_t * m_options; /* the module options */ 28 29 int m_isalias : 1; /* the module is an alias */ 30 int m_reserved : 15; /* stuffin' */ 31 32 int m_depcnt : 16; /* the number of dependable module(s) */ 33 char ** m_deparr; /* the list of dependable module(s) */ 34 35 struct dep_t * m_next; /* the next dependency rule */ 124 #define MODULE_FLAG_LOADED 0x0001 125 #define MODULE_FLAG_NEED_DEPS 0x0002 126 /* "was seen in modules.dep": */ 127 #define MODULE_FLAG_FOUND_IN_MODDEP 0x0004 128 #define MODULE_FLAG_BLACKLISTED 0x0008 129 130 struct module_entry { /* I'll call it ME. */ 131 unsigned flags; 132 char *modname; /* stripped of /path/, .ext and s/-/_/g */ 133 const char *probed_name; /* verbatim as seen on cmdline */ 134 char *options; /* options from config files */ 135 llist_t *realnames; /* strings. if this module is an alias, */ 136 /* real module name is one of these. */ 137 //Can there really be more than one? Example from real kernel? 138 llist_t *deps; /* strings. modules we depend on */ 36 139 }; 37 140 38 struct mod_list_t { /* two-way list of modules to process */ 39 /* a module description */ 40 const char * m_name; 41 char * m_path; 42 struct mod_opt_t * m_options; 43 44 struct mod_list_t * m_prev; 45 struct mod_list_t * m_next; 46 }; 47 48 49 static struct dep_t *depend; 50 51 #define main_options "acdklnqrst:vVC:" 52 #define INSERT_ALL 1 /* a */ 53 #define DUMP_CONF_EXIT 2 /* c */ 54 #define D_OPT_IGNORED 4 /* d */ 55 #define AUTOCLEAN_FLG 8 /* k */ 56 #define LIST_ALL 16 /* l */ 57 #define SHOW_ONLY 32 /* n */ 58 #define QUIET 64 /* q */ 59 #define REMOVE_OPT 128 /* r */ 60 #define DO_SYSLOG 256 /* s */ 61 #define RESTRICT_DIR 512 /* t */ 62 #define VERBOSE 1024 /* v */ 63 #define VERSION_ONLY 2048 /* V */ 64 #define CONFIG_FILE 4096 /* C */ 65 66 #define autoclean (main_opts & AUTOCLEAN_FLG) 67 #define show_only (main_opts & SHOW_ONLY) 68 #define quiet (main_opts & QUIET) 69 #define remove_opt (main_opts & REMOVE_OPT) 70 #define do_syslog (main_opts & DO_SYSLOG) 71 #define verbose (main_opts & VERBOSE) 72 73 static int main_opts; 74 75 static int parse_tag_value(char *buffer, char **ptag, char **pvalue) 76 { 77 char *tag, *value; 78 79 buffer = skip_whitespace(buffer); 80 tag = value = buffer; 81 while (!isspace(*value)) 82 if (!*value) return 0; 83 else value++; 84 *value++ = 0; 85 value = skip_whitespace(value); 86 if (!*value) return 0; 87 88 *ptag = tag; 89 *pvalue = value; 90 91 return 1; 92 } 93 94 /* 95 * This function appends an option to a list 96 */ 97 static struct mod_opt_t *append_option(struct mod_opt_t *opt_list, char *opt) 98 { 99 struct mod_opt_t *ol = opt_list; 100 101 if (ol) { 102 while (ol->m_next) { 103 ol = ol->m_next; 104 } 105 ol->m_next = xmalloc(sizeof(struct mod_opt_t)); 106 ol = ol->m_next; 107 } else { 108 ol = opt_list = xmalloc(sizeof(struct mod_opt_t)); 109 } 110 111 ol->m_opt_val = xstrdup(opt); 112 ol->m_next = NULL; 113 114 return opt_list; 115 } 116 117 #if ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS 118 /* static char* parse_command_string(char* src, char **dst); 119 * src: pointer to string containing argument 120 * dst: pointer to where to store the parsed argument 121 * return value: the pointer to the first char after the parsed argument, 122 * NULL if there was no argument parsed (only trailing spaces). 123 * Note that memory is allocated with xstrdup when a new argument was 124 * parsed. Don't forget to free it! 125 */ 126 #define ARG_EMPTY 0x00 127 #define ARG_IN_DQUOTES 0x01 128 #define ARG_IN_SQUOTES 0x02 129 static char *parse_command_string(char *src, char **dst) 130 { 131 int opt_status = ARG_EMPTY; 132 char* tmp_str; 133 134 /* Dumb you, I have nothing to do... */ 135 if (src == NULL) return src; 136 137 /* Skip leading spaces */ 138 while (*src == ' ') { 139 src++; 140 } 141 /* Is the end of string reached? */ 142 if (*src == '\0') { 141 struct globals { 142 llist_t *db; /* MEs of all modules ever seen (caching for speed) */ 143 llist_t *probes; /* MEs of module(s) requested on cmdline */ 144 char *cmdline_mopts; /* module options from cmdline */ 145 int num_unresolved_deps; 146 /* bool. "Did we have 'symbol:FOO' requested on cmdline?" */ 147 smallint need_symbols; 148 } FIX_ALIASING; 149 #define G (*(struct globals*)&bb_common_bufsiz1) 150 #define INIT_G() do { } while (0) 151 152 153 static int read_config(const char *path); 154 155 static char *gather_options_str(char *opts, const char *append) 156 { 157 /* Speed-optimized. We call gather_options_str many times. */ 158 if (append) { 159 if (opts == NULL) { 160 opts = xstrdup(append); 161 } else { 162 int optlen = strlen(opts); 163 opts = xrealloc(opts, optlen + strlen(append) + 2); 164 sprintf(opts + optlen, " %s", append); 165 } 166 } 167 return opts; 168 } 169 170 static struct module_entry *helper_get_module(const char *module, int create) 171 { 172 char modname[MODULE_NAME_LEN]; 173 struct module_entry *e; 174 llist_t *l; 175 176 filename2modname(module, modname); 177 for (l = G.db; l != NULL; l = l->link) { 178 e = (struct module_entry *) l->data; 179 if (strcmp(e->modname, modname) == 0) 180 return e; 181 } 182 if (!create) 143 183 return NULL; 144 } 145 /* Reached the start of an argument 146 * By the way, we duplicate a little too much 147 * here but what is too much is freed later. */ 148 *dst = tmp_str = xstrdup(src); 149 /* Get to the end of that argument */ 150 while (*tmp_str != '\0' 151 && (*tmp_str != ' ' || (opt_status & (ARG_IN_DQUOTES | ARG_IN_SQUOTES))) 184 185 e = xzalloc(sizeof(*e)); 186 e->modname = xstrdup(modname); 187 llist_add_to(&G.db, e); 188 189 return e; 190 } 191 static struct module_entry *get_or_add_modentry(const char *module) 192 { 193 return helper_get_module(module, 1); 194 } 195 static struct module_entry *get_modentry(const char *module) 196 { 197 return helper_get_module(module, 0); 198 } 199 200 static void add_probe(const char *name) 201 { 202 struct module_entry *m; 203 204 m = get_or_add_modentry(name); 205 if (!(option_mask32 & MODPROBE_OPT_REMOVE) 206 && (m->flags & MODULE_FLAG_LOADED) 152 207 ) { 153 switch (*tmp_str) { 154 case '\'': 155 if (opt_status & ARG_IN_DQUOTES) { 156 /* Already in double quotes, keep current char as is */ 157 } else { 158 /* shift left 1 char, until end of string: get rid of the opening/closing quotes */ 159 memmove(tmp_str, tmp_str + 1, strlen(tmp_str)); 160 /* mark me: we enter or leave single quotes */ 161 opt_status ^= ARG_IN_SQUOTES; 162 /* Back one char, as we need to re-scan the new char there. */ 163 tmp_str--; 164 } 165 break; 166 case '"': 167 if (opt_status & ARG_IN_SQUOTES) { 168 /* Already in single quotes, keep current char as is */ 169 } else { 170 /* shift left 1 char, until end of string: get rid of the opening/closing quotes */ 171 memmove(tmp_str, tmp_str + 1, strlen(tmp_str)); 172 /* mark me: we enter or leave double quotes */ 173 opt_status ^= ARG_IN_DQUOTES; 174 /* Back one char, as we need to re-scan the new char there. */ 175 tmp_str--; 176 } 177 break; 178 case '\\': 179 if (opt_status & ARG_IN_SQUOTES) { 180 /* Between single quotes: keep as is. */ 181 } else { 182 switch (*(tmp_str+1)) { 183 case 'a': 184 case 'b': 185 case 't': 186 case 'n': 187 case 'v': 188 case 'f': 189 case 'r': 190 case '0': 191 /* We escaped a special character. For now, keep 192 * both the back-slash and the following char. */ 193 tmp_str++; src++; 194 break; 195 default: 196 /* We escaped a space or a single or double quote, 197 * or a back-slash, or a non-escapable char. Remove 198 * the '\' and keep the new current char as is. */ 199 memmove(tmp_str, tmp_str + 1, strlen(tmp_str)); 200 break; 208 DBG("skipping %s, it is already loaded", name); 209 return; 210 } 211 212 DBG("queuing %s", name); 213 m->probed_name = name; 214 m->flags |= MODULE_FLAG_NEED_DEPS; 215 llist_add_to_end(&G.probes, m); 216 G.num_unresolved_deps++; 217 if (ENABLE_FEATURE_MODUTILS_SYMBOLS 218 && strncmp(m->modname, "symbol:", 7) == 0 219 ) { 220 G.need_symbols = 1; 221 } 222 } 223 224 static int FAST_FUNC config_file_action(const char *filename, 225 struct stat *statbuf UNUSED_PARAM, 226 void *userdata UNUSED_PARAM, 227 int depth UNUSED_PARAM) 228 { 229 char *tokens[3]; 230 parser_t *p; 231 struct module_entry *m; 232 int rc = TRUE; 233 234 if (bb_basename(filename)[0] == '.') 235 goto error; 236 237 p = config_open2(filename, fopen_for_read); 238 if (p == NULL) { 239 rc = FALSE; 240 goto error; 241 } 242 243 while (config_read(p, tokens, 3, 2, "# \t", PARSE_NORMAL)) { 244 //Use index_in_strings? 245 if (strcmp(tokens[0], "alias") == 0) { 246 /* alias <wildcard> <modulename> */ 247 llist_t *l; 248 char wildcard[MODULE_NAME_LEN]; 249 char *rmod; 250 251 if (tokens[2] == NULL) 252 continue; 253 filename2modname(tokens[1], wildcard); 254 255 for (l = G.probes; l != NULL; l = l->link) { 256 m = (struct module_entry *) l->data; 257 if (fnmatch(wildcard, m->modname, 0) != 0) 258 continue; 259 rmod = filename2modname(tokens[2], NULL); 260 llist_add_to(&m->realnames, rmod); 261 262 if (m->flags & MODULE_FLAG_NEED_DEPS) { 263 m->flags &= ~MODULE_FLAG_NEED_DEPS; 264 G.num_unresolved_deps--; 265 } 266 267 m = get_or_add_modentry(rmod); 268 if (!(m->flags & MODULE_FLAG_NEED_DEPS)) { 269 m->flags |= MODULE_FLAG_NEED_DEPS; 270 G.num_unresolved_deps++; 201 271 } 202 272 } 273 } else if (strcmp(tokens[0], "options") == 0) { 274 /* options <modulename> <option...> */ 275 if (tokens[2] == NULL) 276 continue; 277 m = get_or_add_modentry(tokens[1]); 278 m->options = gather_options_str(m->options, tokens[2]); 279 } else if (strcmp(tokens[0], "include") == 0) { 280 /* include <filename> */ 281 read_config(tokens[1]); 282 } else if (ENABLE_FEATURE_MODPROBE_BLACKLIST 283 && strcmp(tokens[0], "blacklist") == 0 284 ) { 285 /* blacklist <modulename> */ 286 get_or_add_modentry(tokens[1])->flags |= MODULE_FLAG_BLACKLISTED; 287 } 288 } 289 config_close(p); 290 error: 291 return rc; 292 } 293 294 static int read_config(const char *path) 295 { 296 return recursive_action(path, ACTION_RECURSE | ACTION_QUIET, 297 config_file_action, NULL, NULL, 1); 298 } 299 300 static const char *humanly_readable_name(struct module_entry *m) 301 { 302 /* probed_name may be NULL. modname always exists. */ 303 return m->probed_name ? m->probed_name : m->modname; 304 } 305 306 static char *parse_and_add_kcmdline_module_options(char *options, const char *modulename) 307 { 308 char *kcmdline_buf; 309 char *kcmdline; 310 char *kptr; 311 int len; 312 313 kcmdline_buf = xmalloc_open_read_close("/proc/cmdline", NULL); 314 if (!kcmdline_buf) 315 return options; 316 317 kcmdline = kcmdline_buf; 318 len = strlen(modulename); 319 while ((kptr = strsep(&kcmdline, "\n\t ")) != NULL) { 320 if (strncmp(modulename, kptr, len) != 0) 321 continue; 322 kptr += len; 323 if (*kptr != '.') 324 continue; 325 /* It is "modulename.xxxx" */ 326 kptr++; 327 if (strchr(kptr, '=') != NULL) { 328 /* It is "modulename.opt=[val]" */ 329 options = gather_options_str(options, kptr); 330 } 331 } 332 free(kcmdline_buf); 333 334 return options; 335 } 336 337 /* Return: similar to bb_init_module: 338 * 0 on success, 339 * -errno on open/read error, 340 * errno on init_module() error 341 */ 342 /* NB: INSMOD_OPT_SILENT bit suppresses ONLY non-existent modules, 343 * not deleted ones (those are still listed in modules.dep). 344 * module-init-tools version 3.4: 345 * # modprobe bogus 346 * FATAL: Module bogus not found. [exitcode 1] 347 * # modprobe -q bogus [silent, exitcode still 1] 348 * but: 349 * # rm kernel/drivers/net/dummy.ko 350 * # modprobe -q dummy 351 * FATAL: Could not open '/lib/modules/xxx/kernel/drivers/net/dummy.ko': No such file or directory 352 * [exitcode 1] 353 */ 354 static int do_modprobe(struct module_entry *m) 355 { 356 struct module_entry *m2 = m2; /* for compiler */ 357 char *fn, *options; 358 int rc, first; 359 llist_t *l; 360 361 if (!(m->flags & MODULE_FLAG_FOUND_IN_MODDEP)) { 362 if (!(option_mask32 & INSMOD_OPT_SILENT)) 363 bb_error_msg("module %s not found in modules.dep", 364 humanly_readable_name(m)); 365 return -ENOENT; 366 } 367 DBG("do_modprob'ing %s", m->modname); 368 369 if (!(option_mask32 & MODPROBE_OPT_REMOVE)) 370 m->deps = llist_rev(m->deps); 371 372 for (l = m->deps; l != NULL; l = l->link) 373 DBG("dep: %s", l->data); 374 375 first = 1; 376 rc = 0; 377 while (m->deps) { 378 rc = 0; 379 fn = llist_pop(&m->deps); /* we leak it */ 380 m2 = get_or_add_modentry(fn); 381 382 if (option_mask32 & MODPROBE_OPT_REMOVE) { 383 /* modprobe -r */ 384 if (m2->flags & MODULE_FLAG_LOADED) { 385 rc = bb_delete_module(m2->modname, O_EXCL); 386 if (rc) { 387 if (first) { 388 bb_error_msg("can't unload module %s: %s", 389 humanly_readable_name(m2), 390 moderror(rc)); 391 break; 392 } 393 } else { 394 m2->flags &= ~MODULE_FLAG_LOADED; 395 } 396 } 397 /* do not error out if *deps* fail to unload */ 398 first = 0; 399 continue; 400 } 401 402 if (m2->flags & MODULE_FLAG_LOADED) { 403 DBG("%s is already loaded, skipping", fn); 404 continue; 405 } 406 407 options = m2->options; 408 m2->options = NULL; 409 options = parse_and_add_kcmdline_module_options(options, m2->modname); 410 if (m == m2) 411 options = gather_options_str(options, G.cmdline_mopts); 412 rc = bb_init_module(fn, options); 413 DBG("loaded %s '%s', rc:%d", fn, options, rc); 414 if (rc == EEXIST) 415 rc = 0; 416 free(options); 417 if (rc) { 418 bb_error_msg("can't load module %s (%s): %s", 419 humanly_readable_name(m2), 420 fn, 421 moderror(rc) 422 ); 203 423 break; 204 /* Any other char that is special shall appear here. 205 * Example: $ starts a variable 206 case '$': 207 do_variable_expansion(); 208 break; 209 * */ 210 default: 211 /* any other char is kept as is. */ 212 break; 213 } 214 tmp_str++; /* Go to next char */ 215 src++; /* Go to next char to find the end of the argument. */ 216 } 217 /* End of string, but still no ending quote */ 218 if (opt_status & (ARG_IN_DQUOTES | ARG_IN_SQUOTES)) { 219 bb_error_msg_and_die("unterminated (single or double) quote in options list: %s", src); 220 } 221 *tmp_str++ = '\0'; 222 *dst = xrealloc(*dst, (tmp_str - *dst)); 223 return src; 224 } 225 #else 226 #define parse_command_string(src, dst) (0) 227 #endif /* ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS */ 228 229 /* 230 * This function reads aliases and default module options from a configuration file 231 * (/etc/modprobe.conf syntax). It supports includes (only files, no directories). 232 */ 233 static void include_conf(struct dep_t **first, struct dep_t **current, char *buffer, int buflen, int fd) 234 { 235 int continuation_line = 0; 236 237 // alias parsing is not 100% correct (no correct handling of continuation lines within an alias)! 238 239 while (reads(fd, buffer, buflen)) { 240 int l; 241 char *p; 242 243 p = strchr(buffer, '#'); 244 if (p) 245 *p = 0; 246 247 l = strlen(buffer); 248 249 while (l && isspace(buffer[l-1])) { 250 buffer[l-1] = 0; 251 l--; 252 } 253 254 if (l == 0) { 255 continuation_line = 0; 256 continue; 257 } 258 259 if (!continuation_line) { 260 if ((strncmp(buffer, "alias", 5) == 0) && isspace(buffer[5])) { 261 char *alias, *mod; 262 263 if (parse_tag_value(buffer + 6, &alias, &mod)) { 264 /* handle alias as a module dependent on the aliased module */ 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 274 if ((strcmp(mod, "off") == 0) || (strcmp(mod, "null") == 0)) { 275 (*current)->m_depcnt = 0; 276 (*current)->m_deparr = 0; 277 } else { 278 (*current)->m_depcnt = 1; 279 (*current)->m_deparr = xmalloc(1 * sizeof(char *)); 280 (*current)->m_deparr[0] = xstrdup(mod); 281 } 282 (*current)->m_next = 0; 283 } 284 } else if ((strncmp(buffer, "options", 7) == 0) && isspace(buffer[7])) { 285 char *mod, *opt; 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 291 /* find the corresponding module */ 292 for (dt = *first; dt; dt = dt->m_next) { 293 if (strcmp(dt->m_name, mod) == 0) 294 break; 295 } 296 if (dt) { 297 if (ENABLE_FEATURE_MODPROBE_MULTIPLE_OPTIONS) { 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 } 424 } 425 m2->flags |= MODULE_FLAG_LOADED; 426 } 427 428 return rc; 429 } 430 431 static void load_modules_dep(void) 432 { 433 struct module_entry *m; 434 char *colon, *tokens[2]; 435 parser_t *p; 436 437 /* Modprobe does not work at all without modules.dep, 438 * even if the full module name is given. Returning error here 439 * was making us later confuse user with this message: 440 * "module /full/path/to/existing/file/module.ko not found". 441 * It's better to die immediately, with good message. 442 * xfopen_for_read provides that. */ 443 p = config_open2(CONFIG_DEFAULT_DEPMOD_FILE, xfopen_for_read); 444 445 while (G.num_unresolved_deps 446 && config_read(p, tokens, 2, 1, "# \t", PARSE_NORMAL) 447 ) { 448 colon = last_char_is(tokens[0], ':'); 449 if (colon == NULL) 450 continue; 451 *colon = 0; 452 453 m = get_modentry(tokens[0]); 454 if (m == NULL) 455 continue; 456 457 /* Optimization... */ 458 if ((m->flags & MODULE_FLAG_LOADED) 459 && !(option_mask32 & MODPROBE_OPT_REMOVE) 460 ) { 461 DBG("skip deps of %s, it's already loaded", tokens[0]); 462 continue; 463 } 464 465 m->flags |= MODULE_FLAG_FOUND_IN_MODDEP; 466 if ((m->flags & MODULE_FLAG_NEED_DEPS) && (m->deps == NULL)) { 467 G.num_unresolved_deps--; 468 llist_add_to(&m->deps, xstrdup(tokens[0])); 469 if (tokens[1]) 470 string_to_llist(tokens[1], &m->deps, " \t"); 471 } else 472 DBG("skipping dep line"); 473 } 474 config_close(p); 475 } 476 477 int modprobe_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 478 int modprobe_main(int argc UNUSED_PARAM, char **argv) 479 { 480 struct utsname uts; 481 int rc; 482 unsigned opt; 483 struct module_entry *me; 484 485 opt_complementary = MODPROBE_COMPLEMENTARY; 486 opt = getopt32(argv, INSMOD_OPTS MODPROBE_OPTS INSMOD_ARGS); 487 argv += optind; 488 489 /* Goto modules location */ 490 xchdir(CONFIG_DEFAULT_MODULES_DIR); 491 uname(&uts); 492 xchdir(uts.release); 493 494 if (opt & MODPROBE_OPT_LIST_ONLY) { 495 char name[MODULE_NAME_LEN]; 496 char *colon, *tokens[2]; 497 parser_t *p = config_open2(CONFIG_DEFAULT_DEPMOD_FILE, xfopen_for_read); 498 499 while (config_read(p, tokens, 2, 1, "# \t", PARSE_NORMAL)) { 500 colon = last_char_is(tokens[0], ':'); 501 if (!colon) 502 continue; 503 *colon = '\0'; 504 filename2modname(tokens[0], name); 505 if (!argv[0]) 506 puts(tokens[0]); 507 else { 508 int i; 509 for (i = 0; argv[i]; i++) { 510 if (fnmatch(argv[i], name, 0) == 0) { 511 puts(tokens[0]); 305 512 } 306 513 } 307 } else if ((strncmp(buffer, "include", 7) == 0) && isspace(buffer[7])) {308 int fdi; char *filename;309 310 filename = skip_whitespace(buffer + 8);311 312 if ((fdi = open(filename, O_RDONLY)) >= 0) {313 include_conf(first, current, buffer, buflen, fdi);314 close(fdi);315 }316 514 } 317 515 } 318 } 319 } 320 321 /* 322 * This function builds a list of dependency rules from /lib/modules/`uname -r`/modules.dep. 323 * It then fills every modules and aliases with their default options, found by parsing 324 * modprobe.conf (or modules.conf, or conf.modules). 325 */ 326 static struct dep_t *build_dep(void) 327 { 328 int fd; 329 struct utsname un; 330 struct dep_t *first = 0; 331 struct dep_t *current = 0; 332 char buffer[2048]; 333 char *filename; 334 int continuation_line = 0; 335 int k_version; 336 337 if (uname(&un)) 338 bb_error_msg_and_die("can't determine kernel version"); 339 340 k_version = 0; 341 if (un.release[0] == '2') { 342 k_version = un.release[2] - '0'; 343 } 344 345 filename = xasprintf("/lib/modules/%s/modules.dep", un.release); 346 fd = open(filename, O_RDONLY); 347 if (ENABLE_FEATURE_CLEAN_UP) 348 free(filename); 349 if (fd < 0) { 350 /* Ok, that didn't work. Fall back to looking in /lib/modules */ 351 fd = open("/lib/modules/modules.dep", O_RDONLY); 352 if (fd < 0) { 353 return 0; 354 } 355 } 356 357 while (reads(fd, buffer, sizeof(buffer))) { 358 int l = strlen(buffer); 359 char *p = 0; 360 361 while (l > 0 && isspace(buffer[l-1])) { 362 buffer[l-1] = 0; 363 l--; 364 } 365 366 if (l == 0) { 367 continuation_line = 0; 368 continue; 369 } 370 371 /* Is this a new module dep description? */ 372 if (!continuation_line) { 373 /* find the dep beginning */ 374 char *col = strchr(buffer, ':'); 375 char *dot = col; 376 377 if (col) { 378 /* This line is a dep description */ 379 const char *mods; 380 char *modpath; 381 char *mod; 382 383 /* Find the beginning of the module file name */ 384 *col = 0; 385 mods = bb_basename(buffer); 386 387 /* find the path of the module */ 388 modpath = strchr(buffer, '/'); /* ... and this is the path */ 389 if (!modpath) 390 modpath = buffer; /* module with no path */ 391 /* find the end of the module name in the file name */ 392 if (ENABLE_FEATURE_2_6_MODULES && 393 (k_version > 4) && (*(col-3) == '.') && 394 (*(col-2) == 'k') && (*(col-1) == 'o')) 395 dot = col - 3; 396 else 397 if ((*(col-2) == '.') && (*(col-1) == 'o')) 398 dot = col - 2; 399 400 mod = xstrndup(mods, dot - mods); 401 402 /* enqueue new module */ 403 if (!current) { 404 first = current = xmalloc(sizeof(struct dep_t)); 405 } else { 406 current->m_next = xmalloc(sizeof(struct dep_t)); 407 current = current->m_next; 408 } 409 current->m_name = mod; 410 current->m_path = xstrdup(modpath); 411 current->m_options = NULL; 412 current->m_isalias = 0; 413 current->m_depcnt = 0; 414 current->m_deparr = 0; 415 current->m_next = 0; 416 417 p = col + 1; 418 } else 419 /* this line is not a dep description */ 420 p = 0; 421 } else 422 /* It's a dep description continuation */ 423 p = buffer; 424 425 while (p && *p && isblank(*p)) 426 p++; 427 428 /* p points to the first dependable module; if NULL, no dependable module */ 429 if (p && *p) { 430 char *end = &buffer[l-1]; 431 const char *deps; 432 char *dep; 433 char *next; 434 int ext = 0; 435 436 while (isblank(*end) || (*end == '\\')) 437 end--; 438 439 do { 440 /* search the end of the dependency */ 441 next = strchr(p, ' '); 442 if (next) { 443 *next = 0; 444 next--; 445 } else 446 next = end; 447 448 /* find the beginning of the module file name */ 449 deps = bb_basename(p); 450 if (deps == p) { 451 while (isblank(*deps)) 452 deps++; 453 } 454 455 /* find the end of the module name in the file name */ 456 if (ENABLE_FEATURE_2_6_MODULES 457 && (k_version > 4) && (*(next-2) == '.') 458 && (*(next-1) == 'k') && (*next == 'o')) 459 ext = 3; 460 else 461 if ((*(next-1) == '.') && (*next == 'o')) 462 ext = 2; 463 464 /* Cope with blank lines */ 465 if ((next-deps-ext+1) <= 0) 466 continue; 467 dep = xstrndup(deps, next - deps - ext + 1); 468 469 /* Add the new dependable module name */ 470 current->m_depcnt++; 471 current->m_deparr = xrealloc(current->m_deparr, 472 sizeof(char *) * current->m_depcnt); 473 current->m_deparr[current->m_depcnt - 1] = dep; 474 475 p = next + 2; 476 } while (next < end); 477 } 478 479 /* is there other dependable module(s) ? */ 480 if (buffer[l-1] == '\\') 481 continuation_line = 1; 482 else 483 continuation_line = 0; 484 } 485 close(fd); 486 487 /* 488 * First parse system-specific options and aliases 489 * as they take precedence over the kernel ones. 490 * >=2.6: we only care about modprobe.conf 491 * <=2.4: we care about modules.conf and conf.modules 492 */ 493 if (ENABLE_FEATURE_2_6_MODULES 494 && (fd = open("/etc/modprobe.conf", O_RDONLY)) < 0) 495 if (ENABLE_FEATURE_2_4_MODULES 496 && (fd = open("/etc/modules.conf", O_RDONLY)) < 0) 497 if (ENABLE_FEATURE_2_4_MODULES) 498 fd = open("/etc/conf.modules", O_RDONLY); 499 500 if (fd >= 0) { 501 include_conf(&first, ¤t, buffer, sizeof(buffer), fd); 502 close(fd); 503 } 504 505 /* Only 2.6 has a modules.alias file */ 506 if (ENABLE_FEATURE_2_6_MODULES) { 507 /* Parse kernel-declared module aliases */ 508 filename = xasprintf("/lib/modules/%s/modules.alias", un.release); 509 fd = open(filename, O_RDONLY); 510 if (fd < 0) { 511 /* Ok, that didn't work. Fall back to looking in /lib/modules */ 512 fd = open("/lib/modules/modules.alias", O_RDONLY); 513 } 514 if (ENABLE_FEATURE_CLEAN_UP) 515 free(filename); 516 517 if (fd >= 0) { 518 include_conf(&first, ¤t, buffer, sizeof(buffer), fd); 519 close(fd); 520 } 521 522 /* Parse kernel-declared symbol aliases */ 523 filename = xasprintf("/lib/modules/%s/modules.symbols", un.release); 524 fd = open(filename, O_RDONLY); 525 if (fd < 0) { 526 /* Ok, that didn't work. Fall back to looking in /lib/modules */ 527 fd = open("/lib/modules/modules.symbols", O_RDONLY); 528 } 529 if (ENABLE_FEATURE_CLEAN_UP) 530 free(filename); 531 532 if (fd >= 0) { 533 include_conf(&first, ¤t, buffer, sizeof(buffer), fd); 534 close(fd); 535 } 536 } 537 538 return first; 539 } 540 541 /* return 1 = loaded, 0 = not loaded, -1 = can't tell */ 542 static int already_loaded(const char *name) 543 { 544 int fd, ret = 0; 545 char buffer[4096]; 546 547 fd = open("/proc/modules", O_RDONLY); 548 if (fd < 0) 549 return -1; 550 551 while (reads(fd, buffer, sizeof(buffer))) { 552 char *p; 553 554 p = strchr (buffer, ' '); 555 if (p) { 556 const char *n; 557 558 // Truncate buffer at first space and check for matches, with 559 // the idiosyncrasy that _ and - are interchangeable because the 560 // 2.6 kernel does weird things. 561 562 *p = 0; 563 for (p = buffer, n = name; ; p++, n++) { 564 if (*p != *n) { 565 if ((*p == '_' || *p == '-') && (*n == '_' || *n == '-')) 566 continue; 567 break; 568 } 569 // If we made it to the end, that's a match. 570 if (!*p) { 571 ret = 1; 572 goto done; 573 } 516 return EXIT_SUCCESS; 517 } 518 519 /* Yes, for some reason -l ignores -s... */ 520 if (opt & INSMOD_OPT_SYSLOG) 521 logmode = LOGMODE_SYSLOG; 522 523 if (!argv[0]) { 524 if (opt & MODPROBE_OPT_REMOVE) { 525 /* "modprobe -r" (w/o params). 526 * "If name is NULL, all unused modules marked 527 * autoclean will be removed". 528 */ 529 if (bb_delete_module(NULL, O_NONBLOCK | O_EXCL) != 0) 530 bb_perror_msg_and_die("rmmod"); 531 } 532 return EXIT_SUCCESS; 533 } 534 535 /* Retrieve module names of already loaded modules */ 536 { 537 char *s; 538 parser_t *parser = config_open2("/proc/modules", fopen_for_read); 539 while (config_read(parser, &s, 1, 1, "# \t", PARSE_NORMAL & ~PARSE_GREEDY)) 540 get_or_add_modentry(s)->flags |= MODULE_FLAG_LOADED; 541 config_close(parser); 542 } 543 544 if (opt & (MODPROBE_OPT_INSERT_ALL | MODPROBE_OPT_REMOVE)) { 545 /* Each argument is a module name */ 546 do { 547 DBG("adding module %s", *argv); 548 add_probe(*argv++); 549 } while (*argv); 550 } else { 551 /* First argument is module name, rest are parameters */ 552 DBG("probing just module %s", *argv); 553 add_probe(argv[0]); 554 G.cmdline_mopts = parse_cmdline_module_options(argv); 555 } 556 557 /* Happens if all requested modules are already loaded */ 558 if (G.probes == NULL) 559 return EXIT_SUCCESS; 560 561 read_config("/etc/modprobe.conf"); 562 read_config("/etc/modprobe.d"); 563 if (ENABLE_FEATURE_MODUTILS_SYMBOLS && G.need_symbols) 564 read_config("modules.symbols"); 565 load_modules_dep(); 566 if (ENABLE_FEATURE_MODUTILS_ALIAS && G.num_unresolved_deps) { 567 read_config("modules.alias"); 568 load_modules_dep(); 569 } 570 571 rc = 0; 572 while ((me = llist_pop(&G.probes)) != NULL) { 573 if (me->realnames == NULL) { 574 DBG("probing by module name"); 575 /* This is not an alias. Literal names are blacklisted 576 * only if '-b' is given. 577 */ 578 if (!(opt & MODPROBE_OPT_BLACKLIST) 579 || !(me->flags & MODULE_FLAG_BLACKLISTED) 580 ) { 581 rc |= do_modprobe(me); 574 582 } 575 } 576 } 577 done: 578 close (fd); 579 return ret; 580 } 581 582 static int mod_process(const struct mod_list_t *list, int do_insert) 583 { 584 int rc = 0; 585 char **argv = NULL; 586 struct mod_opt_t *opts; 587 int argc_malloc; /* never used when CONFIG_FEATURE_CLEAN_UP not defined */ 588 int argc; 589 590 while (list) { 591 argc = 0; 592 if (ENABLE_FEATURE_CLEAN_UP) 593 argc_malloc = 0; 594 /* If CONFIG_FEATURE_CLEAN_UP is not defined, then we leak memory 595 * each time we allocate memory for argv. 596 * But it is (quite) small amounts of memory that leak each 597 * time a module is loaded, and it is reclaimed when modprobe 598 * exits anyway (even when standalone shell?). 599 * This could become a problem when loading a module with LOTS of 600 * dependencies, with LOTS of options for each dependencies, with 601 * very little memory on the target... But in that case, the module 602 * would not load because there is no more memory, so there's no 603 * problem. */ 604 /* enough for minimal insmod (5 args + NULL) or rmmod (3 args + NULL) */ 605 argv = xmalloc(6 * sizeof(char*)); 606 if (do_insert) { 607 if (already_loaded(list->m_name) != 1) { 608 argv[argc++] = (char*)"insmod"; 609 if (ENABLE_FEATURE_2_4_MODULES) { 610 if (do_syslog) 611 argv[argc++] = (char*)"-s"; 612 if (autoclean) 613 argv[argc++] = (char*)"-k"; 614 if (quiet) 615 argv[argc++] = (char*)"-q"; 616 else if (verbose) /* verbose and quiet are mutually exclusive */ 617 argv[argc++] = (char*)"-v"; 618 } 619 argv[argc++] = list->m_path; 620 if (ENABLE_FEATURE_CLEAN_UP) 621 argc_malloc = argc; 622 opts = list->m_options; 623 while (opts) { 624 /* Add one more option */ 625 argc++; 626 argv = xrealloc(argv,(argc + 1)* sizeof(char*)); 627 argv[argc-1] = opts->m_opt_val; 628 opts = opts->m_next; 629 } 583 continue; 584 } 585 586 /* Probe all real names for the alias */ 587 do { 588 char *realname = llist_pop(&me->realnames); 589 struct module_entry *m2; 590 591 DBG("probing alias %s by realname %s", me->modname, realname); 592 m2 = get_or_add_modentry(realname); 593 if (!(m2->flags & MODULE_FLAG_BLACKLISTED) 594 && (!(m2->flags & MODULE_FLAG_LOADED) 595 || (opt & MODPROBE_OPT_REMOVE)) 596 ) { 597 //TODO: we can pass "me" as 2nd param to do_modprobe, 598 //and make do_modprobe emit more meaningful error messages 599 //with alias name included, not just module name alias resolves to. 600 rc |= do_modprobe(m2); 630 601 } 631 } else { 632 /* modutils uses short name for removal */ 633 if (already_loaded(list->m_name) != 0) { 634 argv[argc++] = (char*)"rmmod"; 635 if (do_syslog) 636 argv[argc++] = (char*)"-s"; 637 argv[argc++] = (char*)list->m_name; 638 if (ENABLE_FEATURE_CLEAN_UP) 639 argc_malloc = argc; 640 } 641 } 642 argv[argc] = NULL; 643 644 if (argc) { 645 if (verbose) { 646 printf("%s module %s\n", do_insert?"Loading":"Unloading", list->m_name); 647 } 648 if (!show_only) { 649 int rc2 = wait4pid(spawn(argv)); 650 651 if (do_insert) { 652 rc = rc2; /* only last module matters */ 653 } else if (!rc2) { 654 rc = 0; /* success if remove any mod */ 655 } 656 } 657 if (ENABLE_FEATURE_CLEAN_UP) { 658 /* the last value in the array has index == argc, but 659 * it is the terminating NULL, so we must not free it. */ 660 while (argc_malloc < argc) { 661 free(argv[argc_malloc++]); 662 } 663 } 664 } 665 if (ENABLE_FEATURE_CLEAN_UP) { 666 free(argv); 667 argv = NULL; 668 } 669 list = do_insert ? list->m_prev : list->m_next; 670 } 671 return (show_only) ? 0 : rc; 672 } 673 674 /* 675 * Check the matching between a pattern and a module name. 676 * We need this as *_* is equivalent to *-*, even in pattern matching. 677 */ 678 static int check_pattern(const char* pat_src, const char* mod_src) 679 { 680 int ret; 681 682 if (ENABLE_FEATURE_MODPROBE_FANCY_ALIAS) { 683 char* pat; 684 char* mod; 685 char* p; 686 687 pat = xstrdup(pat_src); 688 mod = xstrdup(mod_src); 689 690 for (p = pat; (p = strchr(p, '-')); *p++ = '_'); 691 for (p = mod; (p = strchr(p, '-')); *p++ = '_'); 692 693 ret = fnmatch(pat, mod, 0); 694 695 if (ENABLE_FEATURE_CLEAN_UP) { 696 free(pat); 697 free(mod); 698 } 699 700 return ret; 701 } else { 702 return fnmatch(pat_src, mod_src, 0); 703 } 704 } 705 706 /* 707 * Builds the dependency list (aka stack) of a module. 708 * head: the highest module in the stack (last to insmod, first to rmmod) 709 * tail: the lowest module in the stack (first to insmod, last to rmmod) 710 */ 711 static void check_dep(char *mod, struct mod_list_t **head, struct mod_list_t **tail) 712 { 713 struct mod_list_t *find; 714 struct dep_t *dt; 715 struct mod_opt_t *opt = 0; 716 char *path = 0; 717 718 /* Search for the given module name amongst all dependency rules. 719 * The module name in a dependency rule can be a shell pattern, 720 * so try to match the given module name against such a pattern. 721 * Of course if the name in the dependency rule is a plain string, 722 * then we consider it a pattern, and matching will still work. */ 723 for (dt = depend; dt; dt = dt->m_next) { 724 if (check_pattern(dt->m_name, mod) == 0) { 725 break; 726 } 727 } 728 729 if (!dt) { 730 bb_error_msg("module %s not found", mod); 731 return; 732 } 733 734 // resolve alias names 735 while (dt->m_isalias) { 736 if (dt->m_depcnt == 1) { 737 struct dep_t *adt; 738 739 for (adt = depend; adt; adt = adt->m_next) { 740 if (check_pattern(adt->m_name, dt->m_deparr[0]) == 0) 741 break; 742 } 743 if (adt) { 744 /* This is the module we are aliased to */ 745 struct mod_opt_t *opts = dt->m_options; 746 /* Option of the alias are appended to the options of the module */ 747 while (opts) { 748 adt->m_options = append_option(adt->m_options, opts->m_opt_val); 749 opts = opts->m_next; 750 } 751 dt = adt; 752 } else { 753 bb_error_msg("module %s not found", mod); 754 return; 755 } 756 } else { 757 bb_error_msg("bad alias %s", dt->m_name); 758 return; 759 } 760 } 761 762 mod = dt->m_name; 763 path = dt->m_path; 764 opt = dt->m_options; 765 766 // search for duplicates 767 for (find = *head; find; find = find->m_next) { 768 if (!strcmp(mod, find->m_name)) { 769 // found ->dequeue it 770 771 if (find->m_prev) 772 find->m_prev->m_next = find->m_next; 773 else 774 *head = find->m_next; 775 776 if (find->m_next) 777 find->m_next->m_prev = find->m_prev; 778 else 779 *tail = find->m_prev; 780 781 break; // there can be only one duplicate 782 } 783 } 784 785 if (!find) { // did not find a duplicate 786 find = xmalloc(sizeof(struct mod_list_t)); 787 find->m_name = mod; 788 find->m_path = path; 789 find->m_options = opt; 790 } 791 792 // enqueue at tail 793 if (*tail) 794 (*tail)->m_next = find; 795 find->m_prev = *tail; 796 find->m_next = 0; 797 798 if (!*head) 799 *head = find; 800 *tail = find; 801 802 if (dt) { 803 int i; 804 805 /* Add all dependable module for that new module */ 806 for (i = 0; i < dt->m_depcnt; i++) 807 check_dep(dt->m_deparr[i], head, tail); 808 } 809 } 810 811 static int mod_insert(char *mod, int argc, char **argv) 812 { 813 struct mod_list_t *tail = NULL; 814 struct mod_list_t *head = NULL; 815 int rc; 816 817 // get dep list for module mod 818 check_dep(mod, &head, &tail); 819 820 rc = 1; 821 if (head && tail) { 822 if (argc) { 823 int i; 824 // append module args 825 for (i = 0; i < argc; i++) 826 head->m_options = append_option(head->m_options, argv[i]); 827 } 828 829 // process tail ---> head 830 rc = mod_process(tail, 1); 831 if (rc) { 832 /* 833 * In case of using udev, multiple instances of modprobe can be 834 * spawned to load the same module (think of two same usb devices, 835 * for example; or cold-plugging at boot time). Thus we shouldn't 836 * fail if the module was loaded, and not by us. 837 */ 838 if (already_loaded(mod)) 839 rc = 0; 840 } 841 } 842 return rc; 843 } 844 845 static int mod_remove(char *mod) 846 { 847 int rc; 848 static const struct mod_list_t rm_a_dummy = { "-a", NULL, NULL, NULL, NULL }; 849 850 struct mod_list_t *head = NULL; 851 struct mod_list_t *tail = NULL; 852 853 if (mod) 854 check_dep(mod, &head, &tail); 855 else // autoclean 856 head = tail = (struct mod_list_t*) &rm_a_dummy; 857 858 rc = 1; 859 if (head && tail) 860 rc = mod_process(head, 0); // process head ---> tail 861 return rc; 862 } 863 864 int modprobe_main(int argc, char** argv); 865 int modprobe_main(int argc, char** argv) 866 { 867 int rc = EXIT_SUCCESS; 868 char *unused; 869 870 opt_complementary = "?V-:q-v:v-q"; 871 main_opts = getopt32(argv, "acdklnqrst:vVC:", 872 &unused, &unused); 873 if (main_opts & (DUMP_CONF_EXIT | LIST_ALL)) 874 return EXIT_SUCCESS; 875 if (main_opts & (RESTRICT_DIR | CONFIG_FILE)) 876 bb_error_msg_and_die("-t and -C not supported"); 877 878 depend = build_dep(); 879 880 if (!depend) 881 bb_error_msg_and_die("cannot parse modules.dep"); 882 883 if (remove_opt) { 884 do { 885 if (mod_remove(optind < argc ? 886 argv[optind] : NULL)) { 887 bb_error_msg("failed to remove module %s", 888 argv[optind]); 889 rc = EXIT_FAILURE; 890 } 891 } while (++optind < argc); 892 } else { 893 if (optind >= argc) 894 bb_error_msg_and_die("no module or pattern provided"); 895 896 if (mod_insert(argv[optind], argc - optind - 1, argv + optind + 1)) 897 bb_error_msg_and_die("failed to load module %s", argv[optind]); 898 } 899 900 /* Here would be a good place to free up memory allocated during the dependencies build. */ 901 902 return rc; 903 } 602 free(realname); 603 } while (me->realnames != NULL); 604 } 605 606 return (rc != 0); 607 } -
branches/2.2.9/mindi-busybox/modutils/rmmod.c
r1765 r2725 4 4 * 5 5 * Copyright (C) 1999-2004 by Erik Andersen <andersen@codepoet.org> 6 * Copyright (C) 2008 Timo Teras <timo.teras@iki.fi> 6 7 * 7 * Licensed under GPLv2 or later, see file LICENSE in this tarball for details.8 * Licensed under GPLv2 or later, see file LICENSE in this source tree. 8 9 */ 9 10 11 //applet:IF_RMMOD(APPLET(rmmod, _BB_DIR_SBIN, _BB_SUID_DROP)) 12 13 //usage:#if !ENABLE_MODPROBE_SMALL 14 //usage:#define rmmod_trivial_usage 15 //usage: "[-wfa] [MODULE]..." 16 //usage:#define rmmod_full_usage "\n\n" 17 //usage: "Unload kernel modules\n" 18 //usage: "\nOptions:" 19 //usage: "\n -w Wait until the module is no longer used" 20 //usage: "\n -f Force unload" 21 //usage: "\n -a Remove all unused modules (recursively)" 22 //usage:#define rmmod_example_usage 23 //usage: "$ rmmod tulip\n" 24 //usage:#endif 25 10 26 #include "libbb.h" 11 #include <sys/syscall.h>27 #include "modutils.h" 12 28 13 #if ENABLE_FEATURE_2_6_MODULES 14 static inline void filename2modname(char *modname, const char *afterslash)29 int rmmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 30 int rmmod_main(int argc UNUSED_PARAM, char **argv) 15 31 { 16 unsigned int i; 17 int kr_chk = 1; 18 19 if (ENABLE_FEATURE_2_4_MODULES 20 && get_linux_version_code() <= KERNEL_VERSION(2,6,0)) 21 kr_chk = 0; 22 23 /* Convert to underscores, stop at first . */ 24 for (i = 0; afterslash[i] && afterslash[i] != '.'; i++) { 25 if (kr_chk && (afterslash[i] == '-')) 26 modname[i] = '_'; 27 else 28 modname[i] = afterslash[i]; 29 } 30 modname[i] = '\0'; 31 } 32 #else 33 void filename2modname(char *modname, const char *afterslash); 34 #endif 35 36 // There really should be a header file for this... 37 38 int query_module(const char *name, int which, void *buf, 39 size_t bufsize, size_t *ret); 40 41 int rmmod_main(int argc, char **argv); 42 int rmmod_main(int argc, char **argv) 43 { 44 int n, ret = EXIT_SUCCESS; 45 unsigned int flags = O_NONBLOCK|O_EXCL; 46 47 #define misc_buf bb_common_bufsiz1 32 int n; 33 unsigned flags = O_NONBLOCK | O_EXCL; 48 34 49 35 /* Parse command line. */ 50 n = getopt32(argv, "wfa"); 51 if (n & 1) // --wait 36 n = getopt32(argv, "wfas"); // -s ignored 37 argv += optind; 38 if (n & 1) // --wait 52 39 flags &= ~O_NONBLOCK; 53 if (n & 2) 40 if (n & 2) // --force 54 41 flags |= O_TRUNC; 55 42 if (n & 4) { 56 43 /* Unload _all_ unused modules via NULL delete_module() call */ 57 /* until the number of modules does not change */ 58 size_t nmod = 0; /* number of modules */ 59 size_t pnmod = -1; /* previous number of modules */ 60 61 while (nmod != pnmod) { 62 if (syscall(__NR_delete_module, NULL, flags) != 0) { 63 if (errno == EFAULT) 64 return ret; 65 bb_perror_msg_and_die("rmmod"); 66 } 67 pnmod = nmod; 68 // the 1 here is QM_MODULES. 69 if (ENABLE_FEATURE_QUERY_MODULE_INTERFACE && query_module(NULL, 70 1, misc_buf, sizeof(misc_buf), 71 &nmod)) 72 { 73 bb_perror_msg_and_die("QM_MODULES"); 74 } 75 } 44 if (bb_delete_module(NULL, flags) != 0 && errno != EFAULT) 45 bb_perror_msg_and_die("rmmod"); 76 46 return EXIT_SUCCESS; 77 47 } 78 48 79 if ( optind == argc)49 if (!*argv) 80 50 bb_show_usage(); 81 51 82 for (n = optind; n < argc; n++) {83 if (ENABLE_FEATURE_2_6_MODULES) {84 filename2modname(misc_buf, bb_basename(argv[n]));85 }52 n = ENABLE_FEATURE_2_4_MODULES && get_linux_version_code() < KERNEL_VERSION(2,6,0); 53 while (*argv) { 54 char modname[MODULE_NAME_LEN]; 55 const char *bname; 86 56 87 if (syscall(__NR_delete_module, ENABLE_FEATURE_2_6_MODULES ? misc_buf : argv[n], flags)) { 88 bb_perror_msg("%s", argv[n]); 89 ret = EXIT_FAILURE; 90 } 57 bname = bb_basename(*argv++); 58 if (n) 59 safe_strncpy(modname, bname, MODULE_NAME_LEN); 60 else 61 filename2modname(bname, modname); 62 if (bb_delete_module(modname, flags)) 63 bb_error_msg_and_die("can't unload '%s': %s", 64 modname, moderror(errno)); 91 65 } 92 66 93 return ret;67 return EXIT_SUCCESS; 94 68 }
Note:
See TracChangeset
for help on using the changeset viewer.