diff options
| author | Mike Galbraith <efault@gmx.de> | 2009-09-24 04:07:08 -0400 |
|---|---|---|
| committer | Ingo Molnar <mingo@elte.hu> | 2009-09-24 05:40:35 -0400 |
| commit | dd906a0fe8d78b925702cd3916a65f34dfdfc011 (patch) | |
| tree | 2f4b5c3505d4ad3b6b92c4e5e30cf16f82e2bd48 /tools/perf/util/module.c | |
| parent | 508c4d0874acf8584787bbab7e4a3798e2834c1a (diff) | |
perf tools: Handle relative paths while loading module symbols
Inform util/module.c::mod_dso__load_module_paths() that relative
paths do exist in some modules.dep, and make it fail noisily should
it encounter a path that it doesn't understand, or a module it
cannot open.
Reported-by: Avi Kivity <avi@redhat.com>
Signed-off-by: Mike Galbraith <efault@gmx.de>
Cc: Arnaldo Carvalho de Melo <acme@redhat.com>
Cc: rostedt@goodmis.org
Cc: Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca>
Cc: Peter Zijlstra <a.p.zijlstra@chello.nl>
Cc: Frederic Weisbecker <fweisbec@gmail.com>
Cc: Masami Hiramatsu <mhiramat@redhat.com>
LKML-Reference: <1253779628.10513.8.camel@marge.simson.net>
Signed-off-by: Ingo Molnar <mingo@elte.hu>
Diffstat (limited to 'tools/perf/util/module.c')
| -rw-r--r-- | tools/perf/util/module.c | 96 |
1 files changed, 66 insertions, 30 deletions
diff --git a/tools/perf/util/module.c b/tools/perf/util/module.c index 3d567fe59c79..8f81622073e1 100644 --- a/tools/perf/util/module.c +++ b/tools/perf/util/module.c | |||
| @@ -4,6 +4,7 @@ | |||
| 4 | #include "module.h" | 4 | #include "module.h" |
| 5 | 5 | ||
| 6 | #include <libelf.h> | 6 | #include <libelf.h> |
| 7 | #include <libgen.h> | ||
| 7 | #include <gelf.h> | 8 | #include <gelf.h> |
| 8 | #include <elf.h> | 9 | #include <elf.h> |
| 9 | #include <dirent.h> | 10 | #include <dirent.h> |
| @@ -409,35 +410,40 @@ out_failure: | |||
| 409 | static int mod_dso__load_module_paths(struct mod_dso *self) | 410 | static int mod_dso__load_module_paths(struct mod_dso *self) |
| 410 | { | 411 | { |
| 411 | struct utsname uts; | 412 | struct utsname uts; |
| 412 | int count = 0, len; | 413 | int count = 0, len, err = -1; |
| 413 | char *line = NULL; | 414 | char *line = NULL; |
| 414 | FILE *file; | 415 | FILE *file; |
| 415 | char *path; | 416 | char *dpath, *dir; |
| 416 | size_t n; | 417 | size_t n; |
| 417 | 418 | ||
| 418 | if (uname(&uts) < 0) | 419 | if (uname(&uts) < 0) |
| 419 | goto out_failure; | 420 | return err; |
| 420 | 421 | ||
| 421 | len = strlen("/lib/modules/"); | 422 | len = strlen("/lib/modules/"); |
| 422 | len += strlen(uts.release); | 423 | len += strlen(uts.release); |
| 423 | len += strlen("/modules.dep"); | 424 | len += strlen("/modules.dep"); |
| 424 | 425 | ||
| 425 | path = calloc(1, len); | 426 | dpath = calloc(1, len); |
| 426 | if (path == NULL) | 427 | if (dpath == NULL) |
| 427 | goto out_failure; | 428 | return err; |
| 428 | 429 | ||
| 429 | strcat(path, "/lib/modules/"); | 430 | strcat(dpath, "/lib/modules/"); |
| 430 | strcat(path, uts.release); | 431 | strcat(dpath, uts.release); |
| 431 | strcat(path, "/modules.dep"); | 432 | strcat(dpath, "/modules.dep"); |
| 432 | 433 | ||
| 433 | file = fopen(path, "r"); | 434 | file = fopen(dpath, "r"); |
| 434 | free(path); | ||
| 435 | if (file == NULL) | 435 | if (file == NULL) |
| 436 | goto out_failure; | 436 | goto out_failure; |
| 437 | 437 | ||
| 438 | dir = dirname(dpath); | ||
| 439 | if (!dir) | ||
| 440 | goto out_failure; | ||
| 441 | strcat(dir, "/"); | ||
| 442 | |||
| 438 | while (!feof(file)) { | 443 | while (!feof(file)) { |
| 439 | char *name, *tmp; | ||
| 440 | struct module *module; | 444 | struct module *module; |
| 445 | char *name, *path, *tmp; | ||
| 446 | FILE *modfile; | ||
| 441 | int line_len; | 447 | int line_len; |
| 442 | 448 | ||
| 443 | line_len = getline(&line, &n, file); | 449 | line_len = getline(&line, &n, file); |
| @@ -445,17 +451,41 @@ static int mod_dso__load_module_paths(struct mod_dso *self) | |||
| 445 | break; | 451 | break; |
| 446 | 452 | ||
| 447 | if (!line) | 453 | if (!line) |
| 448 | goto out_failure; | 454 | break; |
| 449 | 455 | ||
| 450 | line[--line_len] = '\0'; /* \n */ | 456 | line[--line_len] = '\0'; /* \n */ |
| 451 | 457 | ||
| 452 | path = strtok(line, ":"); | 458 | path = strchr(line, ':'); |
| 459 | if (!path) | ||
| 460 | break; | ||
| 461 | *path = '\0'; | ||
| 462 | |||
| 463 | path = strdup(line); | ||
| 453 | if (!path) | 464 | if (!path) |
| 454 | goto out_failure; | 465 | break; |
| 466 | |||
| 467 | if (!strstr(path, dir)) { | ||
| 468 | if (strncmp(path, "kernel/", 7)) | ||
| 469 | break; | ||
| 470 | |||
| 471 | free(path); | ||
| 472 | path = calloc(1, strlen(dir) + strlen(line) + 1); | ||
| 473 | if (!path) | ||
| 474 | break; | ||
| 475 | strcat(path, dir); | ||
| 476 | strcat(path, line); | ||
| 477 | } | ||
| 478 | |||
| 479 | modfile = fopen(path, "r"); | ||
| 480 | if (modfile == NULL) | ||
| 481 | break; | ||
| 482 | fclose(modfile); | ||
| 455 | 483 | ||
| 456 | name = strdup(path); | 484 | name = strdup(path); |
| 457 | name = strtok(name, "/"); | 485 | if (!name) |
| 486 | break; | ||
| 458 | 487 | ||
| 488 | name = strtok(name, "/"); | ||
| 459 | tmp = name; | 489 | tmp = name; |
| 460 | 490 | ||
| 461 | while (tmp) { | 491 | while (tmp) { |
| @@ -463,26 +493,25 @@ static int mod_dso__load_module_paths(struct mod_dso *self) | |||
| 463 | if (tmp) | 493 | if (tmp) |
| 464 | name = tmp; | 494 | name = tmp; |
| 465 | } | 495 | } |
| 496 | |||
| 466 | name = strsep(&name, "."); | 497 | name = strsep(&name, "."); |
| 498 | if (!name) | ||
| 499 | break; | ||
| 467 | 500 | ||
| 468 | /* Quirk: replace '-' with '_' in sound modules */ | 501 | /* Quirk: replace '-' with '_' in all modules */ |
| 469 | for (len = strlen(name); len; len--) { | 502 | for (len = strlen(name); len; len--) { |
| 470 | if (*(name+len) == '-') | 503 | if (*(name+len) == '-') |
| 471 | *(name+len) = '_'; | 504 | *(name+len) = '_'; |
| 472 | } | 505 | } |
| 473 | 506 | ||
| 474 | module = module__new(name, path); | 507 | module = module__new(name, path); |
| 475 | if (!module) { | 508 | if (!module) |
| 476 | fprintf(stderr, "load_module_paths: allocation error\n"); | 509 | break; |
| 477 | goto out_failure; | ||
| 478 | } | ||
| 479 | mod_dso__insert_module(self, module); | 510 | mod_dso__insert_module(self, module); |
| 480 | 511 | ||
| 481 | module->sections = sec_dso__new_dso("sections"); | 512 | module->sections = sec_dso__new_dso("sections"); |
| 482 | if (!module->sections) { | 513 | if (!module->sections) |
| 483 | fprintf(stderr, "load_module_paths: allocation error\n"); | 514 | break; |
| 484 | goto out_failure; | ||
| 485 | } | ||
| 486 | 515 | ||
| 487 | module->active = mod_dso__load_sections(module); | 516 | module->active = mod_dso__load_sections(module); |
| 488 | 517 | ||
| @@ -490,13 +519,20 @@ static int mod_dso__load_module_paths(struct mod_dso *self) | |||
| 490 | count++; | 519 | count++; |
| 491 | } | 520 | } |
| 492 | 521 | ||
| 493 | free(line); | 522 | if (feof(file)) |
| 494 | fclose(file); | 523 | err = count; |
| 495 | 524 | else | |
| 496 | return count; | 525 | fprintf(stderr, "load_module_paths: modules.dep parsing failure!\n"); |
| 497 | 526 | ||
| 498 | out_failure: | 527 | out_failure: |
| 499 | return -1; | 528 | if (dpath) |
| 529 | free(dpath); | ||
| 530 | if (file) | ||
| 531 | fclose(file); | ||
| 532 | if (line) | ||
| 533 | free(line); | ||
| 534 | |||
| 535 | return err; | ||
| 500 | } | 536 | } |
| 501 | 537 | ||
| 502 | int mod_dso__load_modules(struct mod_dso *dso) | 538 | int mod_dso__load_modules(struct mod_dso *dso) |
