1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25#include "libbb.h"
26#include "modutils.h"
27#include <sys/utsname.h>
28
29
30
31
32
33
34
35
36static int FAST_FUNC parse_module(const char *fname, struct stat *sb UNUSED_PARAM,
37 void *data, int depth UNUSED_PARAM)
38{
39 module_db *modules = data;
40 char *image, *ptr;
41 module_entry *e;
42
43
44 size_t len = (64*1024*1024 - 4096);
45
46 if (strrstr(fname, ".ko") == NULL)
47 return TRUE;
48
49 image = xmalloc_open_zipped_read_close(fname, &len);
50
51 e = moddb_get_or_create(modules, bb_get_last_path_component_nostrip(fname));
52 e->name = xstrdup(fname + 2);
53
54 for (ptr = image; ptr < image + len - 10; ptr++) {
55 if (is_prefixed_with(ptr, "depends=")) {
56 char *u;
57
58 ptr += 8;
59 for (u = ptr; *u; u++)
60 if (*u == '-')
61 *u = '_';
62 ptr += string_to_llist(ptr, &e->deps, ",");
63 } else if (ENABLE_FEATURE_MODUTILS_ALIAS
64 && is_prefixed_with(ptr, "alias=")
65 ) {
66 llist_add_to(&e->aliases, xstrdup(ptr + 6));
67 ptr += strlen(ptr);
68 } else if (ENABLE_FEATURE_MODUTILS_SYMBOLS
69 && is_prefixed_with(ptr, "__ksymtab_")
70 ) {
71 ptr += 10;
72 if (is_prefixed_with(ptr, "gpl")
73 || strcmp(ptr, "strings") == 0
74 ) {
75 continue;
76 }
77 llist_add_to(&e->symbols, xstrdup(ptr));
78 ptr += strlen(ptr);
79 }
80 }
81 free(image);
82
83 return TRUE;
84}
85
86static void order_dep_list(module_db *modules, module_entry *start, llist_t *add)
87{
88 module_entry *m;
89 llist_t *n;
90
91 for (n = add; n != NULL; n = n->link) {
92 m = moddb_get(modules, n->data);
93 if (m == NULL)
94 continue;
95
96
97 m->dnext->dprev = m->dprev;
98 m->dprev->dnext = m->dnext;
99
100
101 m->dnext = start;
102 m->dprev = start->dprev;
103 start->dprev->dnext = m;
104 start->dprev = m;
105
106
107 order_dep_list(modules, start, m->deps);
108 }
109}
110
111static void xfreopen_write(const char *file, FILE *f)
112{
113 if (freopen(file, "w", f) == NULL)
114 bb_perror_msg_and_die("can't open '%s'", file);
115}
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157enum {
158
159
160 OPT_b = (1 << 2),
161
162
163 OPT_n = (1 << 5),
164 OPT_r = (1 << 6),
165 OPT_u = (1 << 7),
166 OPT_q = (1 << 8),
167 OPT_C = (1 << 9),
168};
169
170int depmod_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
171int depmod_main(int argc UNUSED_PARAM, char **argv)
172{
173 module_db modules;
174 module_entry *m, *dep;
175 const char *moddir_base = "/";
176 char *moddir, *version;
177 struct utsname uts;
178 unsigned i;
179 int tmp;
180
181 getopt32(argv, "aAb:eF:nruqC:", &moddir_base, NULL, NULL);
182 argv += optind;
183
184
185 xchdir(moddir_base);
186
187
188
189
190 if (*argv && sscanf(*argv, "%u.%u.%u", &tmp, &tmp, &tmp) == 3) {
191 version = *argv++;
192 } else {
193 uname(&uts);
194 version = uts.release;
195 }
196 moddir = concat_path_file(&CONFIG_DEFAULT_MODULES_DIR[1], version);
197 xchdir(moddir);
198 if (ENABLE_FEATURE_CLEAN_UP)
199 free(moddir);
200
201
202 memset(&modules, 0, sizeof(modules));
203 if (*argv) {
204 do {
205 parse_module(*argv, NULL, &modules, 0);
206 } while (*++argv);
207 } else {
208 recursive_action(".", ACTION_RECURSE,
209 parse_module, NULL, &modules, 0);
210 }
211
212
213 if (!(option_mask32 & OPT_n))
214 xfreopen_write(CONFIG_DEFAULT_DEPMOD_FILE, stdout);
215
216 moddb_foreach_module(&modules, m, i) {
217 printf("%s:", m->name);
218
219 order_dep_list(&modules, m, m->deps);
220 while (m->dnext != m) {
221 dep = m->dnext;
222 printf(" %s", dep->name);
223
224
225 dep->dnext->dprev = dep->dprev;
226 dep->dprev->dnext = dep->dnext;
227 dep->dnext = dep->dprev = dep;
228 }
229 bb_putchar('\n');
230 }
231
232#if ENABLE_FEATURE_MODUTILS_ALIAS
233 if (!(option_mask32 & OPT_n))
234 xfreopen_write("modules.alias", stdout);
235 moddb_foreach_module(&modules, m, i) {
236 while (m->aliases) {
237
238
239
240
241
242
243 printf("alias %s %s\n",
244 (char*)llist_pop(&m->aliases),
245 m->modname);
246 }
247 }
248#endif
249#if ENABLE_FEATURE_MODUTILS_SYMBOLS
250 if (!(option_mask32 & OPT_n))
251 xfreopen_write("modules.symbols", stdout);
252 moddb_foreach_module(&modules, m, i) {
253 while (m->symbols) {
254 printf("alias symbol:%s %s\n",
255 (char*)llist_pop(&m->symbols),
256 m->modname);
257 }
258 }
259#endif
260
261 if (ENABLE_FEATURE_CLEAN_UP)
262 moddb_free(&modules);
263
264 return EXIT_SUCCESS;
265}
266