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