aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/recordmcount.c
diff options
context:
space:
mode:
authorSteven Rostedt <srostedt@redhat.com>2011-04-08 03:58:48 -0400
committerSteven Rostedt <rostedt@goodmis.org>2011-05-17 10:41:42 -0400
commit68eb1d2e5370c6da4c871c80fdccbe315dc2f3c1 (patch)
tree04c5928123189727e1940aa3a0b090272aa9adff /scripts/recordmcount.c
parentdf2ccb69454d022ce99e3a3b7ee7f9fb4a4e9563 (diff)
ftrace/recordmcount: Make ignored mcount calls into nops at compile time
There are sections that are ignored by ftrace for the function tracing because the text is in a section that can be removed without notice. The mcount calls in these sections are ignored and ftrace never sees them. The downside of this is that the functions in these sections still call mcount. Although the mcount function is defined in assembly simply as a return, this added overhead is unnecessary. The solution is to convert these callers into nops at compile time. A better solution is to add 'notrace' to the section markers, but as new sections come up all the time, it would be nice that they are delt with when they are created. Later patches will deal with finding these sections and doing the proper solution. Thanks to H. Peter Anvin for giving me the right nops to use for x86. Cc: "H. Peter Anvin" <hpa@zytor.com> Cc: John Reiser <jreiser@bitwagon.com> Link: http://lkml.kernel.org/r/20110421023738.237101176@goodmis.org Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'scripts/recordmcount.c')
-rw-r--r--scripts/recordmcount.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c
index 37c59654c133..78054a41d134 100644
--- a/scripts/recordmcount.c
+++ b/scripts/recordmcount.c
@@ -118,6 +118,34 @@ umalloc(size_t size)
118 return addr; 118 return addr;
119} 119}
120 120
121static unsigned char ideal_nop5_x86_64[5] = { 0x0f, 0x1f, 0x44, 0x00, 0x00 };
122static unsigned char ideal_nop5_x86_32[5] = { 0x3e, 0x8d, 0x74, 0x26, 0x00 };
123static unsigned char *ideal_nop;
124
125static char rel_type_nop;
126
127static int (*make_nop)(void *map, size_t const offset);
128
129static int make_nop_x86(void *map, size_t const offset)
130{
131 uint32_t *ptr;
132 unsigned char *op;
133
134 /* Confirm we have 0xe8 0x0 0x0 0x0 0x0 */
135 ptr = map + offset;
136 if (*ptr != 0)
137 return -1;
138
139 op = map + offset - 1;
140 if (*op != 0xe8)
141 return -1;
142
143 /* convert to nop */
144 ulseek(fd_map, offset - 1, SEEK_SET);
145 uwrite(fd_map, ideal_nop, 5);
146 return 0;
147}
148
121/* 149/*
122 * Get the whole file as a programming convenience in order to avoid 150 * Get the whole file as a programming convenience in order to avoid
123 * malloc+lseek+read+free of many pieces. If successful, then mmap 151 * malloc+lseek+read+free of many pieces. If successful, then mmap
@@ -301,7 +329,11 @@ do_file(char const *const fname)
301 w2(ehdr->e_machine), fname); 329 w2(ehdr->e_machine), fname);
302 fail_file(); 330 fail_file();
303 break; 331 break;
304 case EM_386: reltype = R_386_32; break; 332 case EM_386:
333 reltype = R_386_32;
334 make_nop = make_nop_x86;
335 ideal_nop = ideal_nop5_x86_32;
336 break;
305 case EM_ARM: reltype = R_ARM_ABS32; 337 case EM_ARM: reltype = R_ARM_ABS32;
306 altmcount = "__gnu_mcount_nc"; 338 altmcount = "__gnu_mcount_nc";
307 break; 339 break;
@@ -312,7 +344,11 @@ do_file(char const *const fname)
312 case EM_S390: /* reltype: e_class */ gpfx = '_'; break; 344 case EM_S390: /* reltype: e_class */ gpfx = '_'; break;
313 case EM_SH: reltype = R_SH_DIR32; break; 345 case EM_SH: reltype = R_SH_DIR32; break;
314 case EM_SPARCV9: reltype = R_SPARC_64; gpfx = '_'; break; 346 case EM_SPARCV9: reltype = R_SPARC_64; gpfx = '_'; break;
315 case EM_X86_64: reltype = R_X86_64_64; break; 347 case EM_X86_64:
348 make_nop = make_nop_x86;
349 ideal_nop = ideal_nop5_x86_64;
350 reltype = R_X86_64_64;
351 break;
316 } /* end switch */ 352 } /* end switch */
317 353
318 switch (ehdr->e_ident[EI_CLASS]) { 354 switch (ehdr->e_ident[EI_CLASS]) {