diff options
Diffstat (limited to 'scripts')
| -rw-r--r-- | scripts/recordmcount.c | 32 | ||||
| -rw-r--r-- | scripts/recordmcount.h | 22 |
2 files changed, 41 insertions, 13 deletions
diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c index 78054a41d134..0e18975824f7 100644 --- a/scripts/recordmcount.c +++ b/scripts/recordmcount.c | |||
| @@ -24,6 +24,7 @@ | |||
| 24 | #include <sys/types.h> | 24 | #include <sys/types.h> |
| 25 | #include <sys/mman.h> | 25 | #include <sys/mman.h> |
| 26 | #include <sys/stat.h> | 26 | #include <sys/stat.h> |
| 27 | #include <getopt.h> | ||
| 27 | #include <elf.h> | 28 | #include <elf.h> |
| 28 | #include <fcntl.h> | 29 | #include <fcntl.h> |
| 29 | #include <setjmp.h> | 30 | #include <setjmp.h> |
| @@ -39,6 +40,7 @@ static char gpfx; /* prefix for global symbol name (sometimes '_') */ | |||
| 39 | static struct stat sb; /* Remember .st_size, etc. */ | 40 | static struct stat sb; /* Remember .st_size, etc. */ |
| 40 | static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */ | 41 | static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */ |
| 41 | static const char *altmcount; /* alternate mcount symbol name */ | 42 | static const char *altmcount; /* alternate mcount symbol name */ |
| 43 | static int warn_on_notrace_sect; /* warn when section has mcount not being recorded */ | ||
| 42 | 44 | ||
| 43 | /* setjmp() return values */ | 45 | /* setjmp() return values */ |
| 44 | enum { | 46 | enum { |
| @@ -397,19 +399,33 @@ do_file(char const *const fname) | |||
| 397 | } | 399 | } |
| 398 | 400 | ||
| 399 | int | 401 | int |
| 400 | main(int argc, char const *argv[]) | 402 | main(int argc, char *argv[]) |
| 401 | { | 403 | { |
| 402 | const char ftrace[] = "/ftrace.o"; | 404 | const char ftrace[] = "/ftrace.o"; |
| 403 | int ftrace_size = sizeof(ftrace) - 1; | 405 | int ftrace_size = sizeof(ftrace) - 1; |
| 404 | int n_error = 0; /* gcc-4.3.0 false positive complaint */ | 406 | int n_error = 0; /* gcc-4.3.0 false positive complaint */ |
| 407 | int c; | ||
| 408 | int i; | ||
| 405 | 409 | ||
| 406 | if (argc <= 1) { | 410 | while ((c = getopt(argc, argv, "w")) >= 0) { |
| 407 | fprintf(stderr, "usage: recordmcount file.o...\n"); | 411 | switch (c) { |
| 412 | case 'w': | ||
| 413 | warn_on_notrace_sect = 1; | ||
| 414 | break; | ||
| 415 | default: | ||
| 416 | fprintf(stderr, "usage: recordmcount [-w] file.o...\n"); | ||
| 417 | return 0; | ||
| 418 | } | ||
| 419 | } | ||
| 420 | |||
| 421 | if ((argc - optind) < 1) { | ||
| 422 | fprintf(stderr, "usage: recordmcount [-w] file.o...\n"); | ||
| 408 | return 0; | 423 | return 0; |
| 409 | } | 424 | } |
| 410 | 425 | ||
| 411 | /* Process each file in turn, allowing deep failure. */ | 426 | /* Process each file in turn, allowing deep failure. */ |
| 412 | for (--argc, ++argv; argc > 0; --argc, ++argv) { | 427 | for (i = optind; i < argc; i++) { |
| 428 | char *file = argv[i]; | ||
| 413 | int const sjval = setjmp(jmpenv); | 429 | int const sjval = setjmp(jmpenv); |
| 414 | int len; | 430 | int len; |
| 415 | 431 | ||
| @@ -418,14 +434,14 @@ main(int argc, char const *argv[]) | |||
| 418 | * function but does not call it. Since ftrace.o should | 434 | * function but does not call it. Since ftrace.o should |
| 419 | * not be traced anyway, we just skip it. | 435 | * not be traced anyway, we just skip it. |
| 420 | */ | 436 | */ |
| 421 | len = strlen(argv[0]); | 437 | len = strlen(file); |
| 422 | if (len >= ftrace_size && | 438 | if (len >= ftrace_size && |
| 423 | strcmp(argv[0] + (len - ftrace_size), ftrace) == 0) | 439 | strcmp(file + (len - ftrace_size), ftrace) == 0) |
| 424 | continue; | 440 | continue; |
| 425 | 441 | ||
| 426 | switch (sjval) { | 442 | switch (sjval) { |
| 427 | default: | 443 | default: |
| 428 | fprintf(stderr, "internal error: %s\n", argv[0]); | 444 | fprintf(stderr, "internal error: %s\n", file); |
| 429 | exit(1); | 445 | exit(1); |
| 430 | break; | 446 | break; |
| 431 | case SJ_SETJMP: /* normal sequence */ | 447 | case SJ_SETJMP: /* normal sequence */ |
| @@ -433,7 +449,7 @@ main(int argc, char const *argv[]) | |||
| 433 | fd_map = -1; | 449 | fd_map = -1; |
| 434 | ehdr_curr = NULL; | 450 | ehdr_curr = NULL; |
| 435 | mmap_failed = 1; | 451 | mmap_failed = 1; |
| 436 | do_file(argv[0]); | 452 | do_file(file); |
| 437 | break; | 453 | break; |
| 438 | case SJ_FAIL: /* error in do_file or below */ | 454 | case SJ_FAIL: /* error in do_file or below */ |
| 439 | ++n_error; | 455 | ++n_error; |
diff --git a/scripts/recordmcount.h b/scripts/recordmcount.h index 657dbedd1c7f..22033d563bcd 100644 --- a/scripts/recordmcount.h +++ b/scripts/recordmcount.h | |||
| @@ -313,7 +313,8 @@ static uint_t *sift_rel_mcount(uint_t *mlocp, | |||
| 313 | * into nops. | 313 | * into nops. |
| 314 | */ | 314 | */ |
| 315 | static void nop_mcount(Elf_Shdr const *const relhdr, | 315 | static void nop_mcount(Elf_Shdr const *const relhdr, |
| 316 | Elf_Ehdr const *const ehdr) | 316 | Elf_Ehdr const *const ehdr, |
| 317 | const char *const txtname) | ||
| 317 | { | 318 | { |
| 318 | Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff) | 319 | Elf_Shdr *const shdr0 = (Elf_Shdr *)(_w(ehdr->e_shoff) |
| 319 | + (void *)ehdr); | 320 | + (void *)ehdr); |
| @@ -336,6 +337,7 @@ static void nop_mcount(Elf_Shdr const *const relhdr, | |||
| 336 | 337 | ||
| 337 | unsigned mcountsym = 0; | 338 | unsigned mcountsym = 0; |
| 338 | unsigned t; | 339 | unsigned t; |
| 340 | int once = 0; | ||
| 339 | 341 | ||
| 340 | for (t = nrel; t; --t) { | 342 | for (t = nrel; t; --t) { |
| 341 | int ret = -1; | 343 | int ret = -1; |
| @@ -353,8 +355,18 @@ static void nop_mcount(Elf_Shdr const *const relhdr, | |||
| 353 | mcountsym = Elf_r_sym(relp); | 355 | mcountsym = Elf_r_sym(relp); |
| 354 | } | 356 | } |
| 355 | 357 | ||
| 356 | if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) | 358 | if (mcountsym == Elf_r_sym(relp) && !is_fake_mcount(relp)) { |
| 357 | ret = make_nop((void *)ehdr, shdr->sh_offset + relp->r_offset); | 359 | if (make_nop) |
| 360 | ret = make_nop((void *)ehdr, shdr->sh_offset + relp->r_offset); | ||
| 361 | if (warn_on_notrace_sect && !once) { | ||
| 362 | printf("Section %s has mcount callers being ignored\n", | ||
| 363 | txtname); | ||
| 364 | once = 1; | ||
| 365 | /* just warn? */ | ||
| 366 | if (!make_nop) | ||
| 367 | return; | ||
| 368 | } | ||
| 369 | } | ||
| 358 | 370 | ||
| 359 | /* | 371 | /* |
| 360 | * If we successfully removed the mcount, mark the relocation | 372 | * If we successfully removed the mcount, mark the relocation |
| @@ -501,12 +513,12 @@ do_func(Elf_Ehdr *const ehdr, char const *const fname, unsigned const reltype) | |||
| 501 | mlocp = sift_rel_mcount(mlocp, | 513 | mlocp = sift_rel_mcount(mlocp, |
| 502 | (void *)mlocp - (void *)mloc0, &mrelp, | 514 | (void *)mlocp - (void *)mloc0, &mrelp, |
| 503 | relhdr, ehdr, recsym, recval, reltype); | 515 | relhdr, ehdr, recsym, recval, reltype); |
| 504 | } else if (make_nop && txtname) { | 516 | } else if (txtname && (warn_on_notrace_sect || make_nop)) { |
| 505 | /* | 517 | /* |
| 506 | * This section is ignored by ftrace, but still | 518 | * This section is ignored by ftrace, but still |
| 507 | * has mcount calls. Convert them to nops now. | 519 | * has mcount calls. Convert them to nops now. |
| 508 | */ | 520 | */ |
| 509 | nop_mcount(relhdr, ehdr); | 521 | nop_mcount(relhdr, ehdr, txtname); |
| 510 | } | 522 | } |
| 511 | } | 523 | } |
| 512 | if (mloc0 != mlocp) { | 524 | if (mloc0 != mlocp) { |
