10 |
|
|
11 |
#undef _GNU_SOURCE |
#undef _GNU_SOURCE |
12 |
#define _GNU_SOURCE |
#define _GNU_SOURCE |
13 |
#include <libbb.h> |
#include "libbb.h" |
|
#include <sys/utsname.h> /* uname() */ |
|
14 |
#include "modutils.h" |
#include "modutils.h" |
15 |
|
#include <sys/utsname.h> /* uname() */ |
16 |
|
|
17 |
/* |
/* |
18 |
* Theory of operation: |
* Theory of operation: |
36 |
ARG_b = (1<<2), /* base directory when modules are in staging area */ |
ARG_b = (1<<2), /* base directory when modules are in staging area */ |
37 |
ARG_e = (1<<3), /* with -F, print unresolved symbols */ |
ARG_e = (1<<3), /* with -F, print unresolved symbols */ |
38 |
ARG_F = (1<<4), /* System.map that contains the symbols */ |
ARG_F = (1<<4), /* System.map that contains the symbols */ |
39 |
ARG_n = (1<<5) /* dry-run, print to stdout only */ |
ARG_n = (1<<5), /* dry-run, print to stdout only */ |
40 |
|
ARG_r = (1<<6) /* Compat dummy. Linux Makefile uses it */ |
41 |
}; |
}; |
42 |
|
|
43 |
static int FAST_FUNC parse_module(const char *fname, struct stat *sb, |
static int FAST_FUNC parse_module(const char *fname, struct stat *sb UNUSED_PARAM, |
44 |
void *data, int UNUSED_PARAM depth) |
void *data, int depth UNUSED_PARAM) |
45 |
{ |
{ |
46 |
|
char modname[MODULE_NAME_LEN]; |
47 |
module_info **first = (module_info **) data; |
module_info **first = (module_info **) data; |
48 |
char *image, *ptr; |
char *image, *ptr; |
49 |
module_info *info; |
module_info *info; |
50 |
size_t len = sb->st_size; |
/* Arbitrary. Was sb->st_size, but that breaks .gz etc */ |
51 |
|
size_t len = (64*1024*1024 - 4096); |
52 |
|
|
53 |
if (strrstr(fname, ".ko") == NULL) |
if (strrstr(fname, ".ko") == NULL) |
54 |
return TRUE; |
return TRUE; |
55 |
|
|
56 |
image = xmalloc_open_zipped_read_close(fname, &len); |
image = xmalloc_open_zipped_read_close(fname, &len); |
57 |
info = xzalloc(sizeof(module_info)); |
info = xzalloc(sizeof(*info)); |
58 |
|
|
59 |
info->next = *first; |
info->next = *first; |
60 |
*first = info; |
*first = info; |
61 |
|
|
62 |
info->dnext = info->dprev = info; |
info->dnext = info->dprev = info; |
63 |
info->name = xasprintf("/%s", fname); |
info->name = xasprintf("/%s", fname); |
64 |
info->modname = filename2modname(fname, NULL); |
info->modname = xstrdup(filename2modname(fname, modname)); |
65 |
for (ptr = image; ptr < image + len - 10; ptr++) { |
for (ptr = image; ptr < image + len - 10; ptr++) { |
66 |
if (strncmp(ptr, "depends=", 8) == 0) { |
if (strncmp(ptr, "depends=", 8) == 0) { |
67 |
char *u; |
char *u; |
71 |
if (*u == '-') |
if (*u == '-') |
72 |
*u = '_'; |
*u = '_'; |
73 |
ptr += string_to_llist(ptr, &info->dependencies, ","); |
ptr += string_to_llist(ptr, &info->dependencies, ","); |
74 |
} else if (ENABLE_FEATURE_MODUTILS_ALIAS && |
} else if (ENABLE_FEATURE_MODUTILS_ALIAS |
75 |
strncmp(ptr, "alias=", 6) == 0) { |
&& strncmp(ptr, "alias=", 6) == 0 |
76 |
|
) { |
77 |
llist_add_to(&info->aliases, xstrdup(ptr + 6)); |
llist_add_to(&info->aliases, xstrdup(ptr + 6)); |
78 |
ptr += strlen(ptr); |
ptr += strlen(ptr); |
79 |
} else if (ENABLE_FEATURE_MODUTILS_SYMBOLS && |
} else if (ENABLE_FEATURE_MODUTILS_SYMBOLS |
80 |
strncmp(ptr, "__ksymtab_", 10) == 0) { |
&& strncmp(ptr, "__ksymtab_", 10) == 0 |
81 |
|
) { |
82 |
ptr += 10; |
ptr += 10; |
83 |
if (strncmp(ptr, "gpl", 3) == 0 || |
if (strncmp(ptr, "gpl", 3) == 0 || |
84 |
strcmp(ptr, "strings") == 0) |
strcmp(ptr, "strings") == 0) |
143 |
struct utsname uts; |
struct utsname uts; |
144 |
int tmp; |
int tmp; |
145 |
|
|
146 |
getopt32(argv, "aAb:eF:n", &moddir_base, NULL); |
getopt32(argv, "aAb:eF:nr", &moddir_base, NULL); |
147 |
argv += optind; |
argv += optind; |
148 |
|
|
149 |
/* goto modules location */ |
/* goto modules location */ |
203 |
if (!(option_mask32 & ARG_n)) |
if (!(option_mask32 & ARG_n)) |
204 |
xfreopen_write("modules.alias", stdout); |
xfreopen_write("modules.alias", stdout); |
205 |
for (m = modules; m != NULL; m = m->next) { |
for (m = modules; m != NULL; m = m->next) { |
206 |
|
const char *fname = bb_basename(m->name); |
207 |
|
int fnlen = strchrnul(fname, '.') - fname; |
208 |
while (m->aliases) { |
while (m->aliases) { |
209 |
printf("alias %s %s\n", |
/* Last word can well be m->modname instead, |
210 |
|
* but depmod from module-init-tools 3.4 |
211 |
|
* uses module basename, i.e., no s/-/_/g. |
212 |
|
* (pathname and .ko.* are still stripped) |
213 |
|
* Mimicking that... */ |
214 |
|
printf("alias %s %.*s\n", |
215 |
(char*)llist_pop(&m->aliases), |
(char*)llist_pop(&m->aliases), |
216 |
m->modname); |
fnlen, fname); |
217 |
} |
} |
218 |
} |
} |
219 |
#endif |
#endif |
221 |
if (!(option_mask32 & ARG_n)) |
if (!(option_mask32 & ARG_n)) |
222 |
xfreopen_write("modules.symbols", stdout); |
xfreopen_write("modules.symbols", stdout); |
223 |
for (m = modules; m != NULL; m = m->next) { |
for (m = modules; m != NULL; m = m->next) { |
224 |
|
const char *fname = bb_basename(m->name); |
225 |
|
int fnlen = strchrnul(fname, '.') - fname; |
226 |
while (m->symbols) { |
while (m->symbols) { |
227 |
printf("alias symbol:%s %s\n", |
printf("alias symbol:%s %.*s\n", |
228 |
(char*)llist_pop(&m->symbols), |
(char*)llist_pop(&m->symbols), |
229 |
m->modname); |
fnlen, fname); |
230 |
} |
} |
231 |
} |
} |
232 |
#endif |
#endif |