mirror of
https://github.com/AuxXxilium/kmod.git
synced 2024-11-24 07:20:52 +07:00
kmod-depmod: implement -F and -E options.
Read System.map and Module.symvers from kernel built, then be able to report unknown symbols.
This commit is contained in:
parent
009ed664d7
commit
4a0e46dac2
@ -2688,6 +2688,112 @@ static int depmod_output(struct depmod *depmod, FILE *out)
|
|||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void depmod_add_fake_syms(struct depmod *depmod)
|
||||||
|
{
|
||||||
|
/* __this_module is magic inserted by kernel loader. */
|
||||||
|
depmod_symbol_add(depmod, "__this_module", 0, NULL);
|
||||||
|
/* On S390, this is faked up too */
|
||||||
|
depmod_symbol_add(depmod, "_GLOBAL_OFFSET_TABLE_", 0, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int depmod_load_symvers(struct depmod *depmod, const char *filename)
|
||||||
|
{
|
||||||
|
char line[10240];
|
||||||
|
FILE *fp;
|
||||||
|
unsigned int linenum = 0;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
fp = fopen(filename, "r");
|
||||||
|
err = -errno;
|
||||||
|
DBG("load symvers: %s: %s\n", filename, strerror(-err));
|
||||||
|
if (fp == NULL)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
/* eg. "0xb352177e\tfind_first_bit\tvmlinux\tEXPORT_SYMBOL" */
|
||||||
|
while (fgets(line, sizeof(line), fp) != NULL) {
|
||||||
|
const char *ver, *sym, *where;
|
||||||
|
char *verend;
|
||||||
|
uint64_t crc;
|
||||||
|
|
||||||
|
linenum++;
|
||||||
|
|
||||||
|
ver = strtok(line, " \t");
|
||||||
|
sym = strtok(NULL, " \t");
|
||||||
|
where = strtok(NULL, " \t");
|
||||||
|
if (!ver || !sym || !where)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (!streq(where, "vmlinux"))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
crc = strtoull(ver, &verend, 16);
|
||||||
|
if (verend[0] != '\0') {
|
||||||
|
ERR("%s:%u Invalid symbol version %s: %m\n",
|
||||||
|
filename, linenum, ver);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
depmod_symbol_add(depmod, sym, crc, NULL);
|
||||||
|
}
|
||||||
|
depmod_add_fake_syms(depmod);
|
||||||
|
|
||||||
|
DBG("loaded symvers: %s: %s\n", filename, strerror(-err));
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int depmod_load_system_map(struct depmod *depmod, const char *filename)
|
||||||
|
{
|
||||||
|
const char ksymstr[] = "__ksymtab_";
|
||||||
|
const size_t ksymstr_len = sizeof(ksymstr) - 1;
|
||||||
|
char line[10240];
|
||||||
|
FILE *fp;
|
||||||
|
unsigned int linenum = 0;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
fp = fopen(filename, "r");
|
||||||
|
err = -errno;
|
||||||
|
DBG("load System.map: %s: %s\n", filename, strerror(-err));
|
||||||
|
if (fp == NULL)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
/* eg. c0294200 R __ksymtab_devfs_alloc_devnum */
|
||||||
|
while (fgets(line, sizeof(line), fp) != NULL) {
|
||||||
|
char *p, *end;
|
||||||
|
|
||||||
|
linenum++;
|
||||||
|
|
||||||
|
p = strchr(line, ' ');
|
||||||
|
if (p == NULL)
|
||||||
|
goto invalid_syntax;
|
||||||
|
p++;
|
||||||
|
p = strchr(p, ' ');
|
||||||
|
if (p == NULL)
|
||||||
|
goto invalid_syntax;
|
||||||
|
p++;
|
||||||
|
|
||||||
|
/* Covers gpl-only and normal symbols. */
|
||||||
|
if (strncmp(p, ksymstr, ksymstr_len) != 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
end = strchr(p, '\n');
|
||||||
|
if (end != NULL)
|
||||||
|
*end = '\0';
|
||||||
|
|
||||||
|
depmod_symbol_add(depmod, p + ksymstr_len, 0, NULL);
|
||||||
|
continue;
|
||||||
|
|
||||||
|
invalid_syntax:
|
||||||
|
ERR("%s:%u: invalid line: %s\n", filename, linenum, line);
|
||||||
|
}
|
||||||
|
depmod_add_fake_syms(depmod);
|
||||||
|
|
||||||
|
DBG("loaded System.map: %s: %s\n", filename, strerror(-err));
|
||||||
|
|
||||||
|
fclose(fp);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
|
||||||
static int depfile_up_to_date(const char *dirname)
|
static int depfile_up_to_date(const char *dirname)
|
||||||
{
|
{
|
||||||
@ -2843,6 +2949,25 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
ctx = NULL; /* owned by depmod */
|
ctx = NULL; /* owned by depmod */
|
||||||
|
|
||||||
|
if (module_symvers != NULL) {
|
||||||
|
err = depmod_load_symvers(&depmod, module_symvers);
|
||||||
|
if (err < 0) {
|
||||||
|
CRIT("Could not load %s: %s\n", module_symvers,
|
||||||
|
strerror(-err));
|
||||||
|
goto cmdline_failed;
|
||||||
|
}
|
||||||
|
} else if (system_map != NULL) {
|
||||||
|
err = depmod_load_system_map(&depmod, system_map);
|
||||||
|
if (err < 0) {
|
||||||
|
CRIT("Could not load %s: %s\n", module_symvers,
|
||||||
|
strerror(-err));
|
||||||
|
goto cmdline_failed;
|
||||||
|
}
|
||||||
|
} else if (cfg.print_unknown) {
|
||||||
|
WRN("-e needs -E or -F\n");
|
||||||
|
cfg.print_unknown = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (all) {
|
if (all) {
|
||||||
err = cfg_load(&cfg, config_paths);
|
err = cfg_load(&cfg, config_paths);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
Loading…
Reference in New Issue
Block a user