Merge tag 'dm-3.8-fixes' of git://git.kernel.org/pub/scm/linux/kernel/git/agk/linux-dm
[cascardo/linux.git] / scripts / recordmcount.c
index 78054a4..ee52cb8 100644 (file)
@@ -24,6 +24,7 @@
 #include <sys/types.h>
 #include <sys/mman.h>
 #include <sys/stat.h>
+#include <getopt.h>
 #include <elf.h>
 #include <fcntl.h>
 #include <setjmp.h>
@@ -39,6 +40,7 @@ static char gpfx;     /* prefix for global symbol name (sometimes '_') */
 static struct stat sb; /* Remember .st_size, etc. */
 static jmp_buf jmpenv; /* setjmp/longjmp per-file error escape */
 static const char *altmcount;  /* alternate mcount symbol name */
+static int warn_on_notrace_sect; /* warn when section has mcount not being recorded */
 
 /* setjmp() return values */
 enum {
@@ -333,6 +335,7 @@ do_file(char const *const fname)
                reltype = R_386_32;
                make_nop = make_nop_x86;
                ideal_nop = ideal_nop5_x86_32;
+               mcount_adjust_32 = -1;
                break;
        case EM_ARM:     reltype = R_ARM_ABS32;
                         altmcount = "__gnu_mcount_nc";
@@ -348,6 +351,7 @@ do_file(char const *const fname)
                make_nop = make_nop_x86;
                ideal_nop = ideal_nop5_x86_64;
                reltype = R_X86_64_64;
+               mcount_adjust_64 = -1;
                break;
        }  /* end switch */
 
@@ -364,8 +368,10 @@ do_file(char const *const fname)
                                "unrecognized ET_REL file: %s\n", fname);
                        fail_file();
                }
-               if (w2(ehdr->e_machine) == EM_S390)
+               if (w2(ehdr->e_machine) == EM_S390) {
                        reltype = R_390_32;
+                       mcount_adjust_32 = -4;
+               }
                if (w2(ehdr->e_machine) == EM_MIPS) {
                        reltype = R_MIPS_32;
                        is_fake_mcount32 = MIPS32_is_fake_mcount;
@@ -380,8 +386,10 @@ do_file(char const *const fname)
                                "unrecognized ET_REL file: %s\n", fname);
                        fail_file();
                }
-               if (w2(ghdr->e_machine) == EM_S390)
+               if (w2(ghdr->e_machine) == EM_S390) {
                        reltype = R_390_64;
+                       mcount_adjust_64 = -8;
+               }
                if (w2(ghdr->e_machine) == EM_MIPS) {
                        reltype = R_MIPS_64;
                        Elf64_r_sym = MIPS64_r_sym;
@@ -397,19 +405,33 @@ do_file(char const *const fname)
 }
 
 int
-main(int argc, char const *argv[])
+main(int argc, char *argv[])
 {
        const char ftrace[] = "/ftrace.o";
        int ftrace_size = sizeof(ftrace) - 1;
        int n_error = 0;  /* gcc-4.3.0 false positive complaint */
+       int c;
+       int i;
+
+       while ((c = getopt(argc, argv, "w")) >= 0) {
+               switch (c) {
+               case 'w':
+                       warn_on_notrace_sect = 1;
+                       break;
+               default:
+                       fprintf(stderr, "usage: recordmcount [-w] file.o...\n");
+                       return 0;
+               }
+       }
 
-       if (argc <= 1) {
-               fprintf(stderr, "usage: recordmcount file.o...\n");
+       if ((argc - optind) < 1) {
+               fprintf(stderr, "usage: recordmcount [-w] file.o...\n");
                return 0;
        }
 
        /* Process each file in turn, allowing deep failure. */
-       for (--argc, ++argv; argc > 0; --argc, ++argv) {
+       for (i = optind; i < argc; i++) {
+               char *file = argv[i];
                int const sjval = setjmp(jmpenv);
                int len;
 
@@ -418,14 +440,14 @@ main(int argc, char const *argv[])
                 * function but does not call it. Since ftrace.o should
                 * not be traced anyway, we just skip it.
                 */
-               len = strlen(argv[0]);
+               len = strlen(file);
                if (len >= ftrace_size &&
-                   strcmp(argv[0] + (len - ftrace_size), ftrace) == 0)
+                   strcmp(file + (len - ftrace_size), ftrace) == 0)
                        continue;
 
                switch (sjval) {
                default:
-                       fprintf(stderr, "internal error: %s\n", argv[0]);
+                       fprintf(stderr, "internal error: %s\n", file);
                        exit(1);
                        break;
                case SJ_SETJMP:    /* normal sequence */
@@ -433,7 +455,7 @@ main(int argc, char const *argv[])
                        fd_map = -1;
                        ehdr_curr = NULL;
                        mmap_failed = 1;
-                       do_file(argv[0]);
+                       do_file(file);
                        break;
                case SJ_FAIL:    /* error in do_file or below */
                        ++n_error;