aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--scripts/recordmcount.c32
-rw-r--r--scripts/recordmcount.h22
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 '_') */
39static struct stat sb; /* Remember .st_size, etc. */ 40static struct stat sb; /* Remember .st_size, etc. */
40static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */ 41static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */
41static const char *altmcount; /* alternate mcount symbol name */ 42static const char *altmcount; /* alternate mcount symbol name */
43static int warn_on_notrace_sect; /* warn when section has mcount not being recorded */
42 44
43/* setjmp() return values */ 45/* setjmp() return values */
44enum { 46enum {
@@ -397,19 +399,33 @@ do_file(char const *const fname)
397} 399}
398 400
399int 401int
400main(int argc, char const *argv[]) 402main(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 */
315static void nop_mcount(Elf_Shdr const *const relhdr, 315static 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) {