1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "libbb.h"
25#include "modutils.h"
26#include <sys/utsname.h>
27
28
29
30
31
32
33
34
35static int FAST_FUNC parse_module(struct recursive_state *state,
36 const char *fname,
37 struct stat *sb UNUSED_PARAM)
38{
39 module_db *modules = state->userData;
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 recursive_action(*argv, 0 ,
206 parse_module, NULL, &modules);
207 } while (*++argv);
208 } else {
209 recursive_action(".", ACTION_RECURSE,
210 parse_module, NULL, &modules);
211 }
212
213
214 if (!(option_mask32 & OPT_n))
215 xfreopen_write(CONFIG_DEFAULT_DEPMOD_FILE, stdout);
216
217 moddb_foreach_module(&modules, m, i) {
218 printf("%s:", m->name);
219
220 order_dep_list(&modules, m, m->deps);
221 while (m->dnext != m) {
222 dep = m->dnext;
223 printf(" %s", dep->name);
224
225
226 dep->dnext->dprev = dep->dprev;
227 dep->dprev->dnext = dep->dnext;
228 dep->dnext = dep->dprev = dep;
229 }
230 bb_putchar('\n');
231 }
232
233#if ENABLE_FEATURE_MODUTILS_ALIAS
234 if (!(option_mask32 & OPT_n))
235 xfreopen_write("modules.alias", stdout);
236 moddb_foreach_module(&modules, m, i) {
237 while (m->aliases) {
238
239
240
241
242
243
244 printf("alias %s %s\n",
245 (char*)llist_pop(&m->aliases),
246 m->modname);
247 }
248 }
249#endif
250#if ENABLE_FEATURE_MODUTILS_SYMBOLS
251 if (!(option_mask32 & OPT_n))
252 xfreopen_write("modules.symbols", stdout);
253 moddb_foreach_module(&modules, m, i) {
254 while (m->symbols) {
255 printf("alias symbol:%s %s\n",
256 (char*)llist_pop(&m->symbols),
257 m->modname);
258 }
259 }
260#endif
261
262 if (ENABLE_FEATURE_CLEAN_UP)
263 moddb_free(&modules);
264
265 return EXIT_SUCCESS;
266}
267