diff options
-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) { |