aboutsummaryrefslogtreecommitdiffstats
path: root/scripts
diff options
context:
space:
mode:
authorStephen Boyd <sboyd@codeaurora.org>2016-10-18 19:42:00 -0400
committerSteven Rostedt <rostedt@goodmis.org>2016-11-14 16:43:00 -0500
commit9648dc15772d77b5431cd5c11675d90eee1a4c2f (patch)
tree4bdfb2f6387d576da753982c5c27383fe419a2a6 /scripts
parent8d414bd2f77ce858f6b9d119c63b9ce29cf0b75d (diff)
recordmcount: arm: Implement make_nop
In similar spirit to x86 and arm64 support, add a make_nop_arm() to replace calls to mcount with a nop in sections that aren't traced. Link: http://lkml.kernel.org/r/20161018234200.5804-1-sboyd@codeaurora.org Acked-by: Russell King <rmk+kernel@armlinux.org.uk> Acked-by: Rabin Vincent <rabin@rab.in> Signed-off-by: Stephen Boyd <sboyd@codeaurora.org> Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Diffstat (limited to 'scripts')
-rw-r--r--scripts/recordmcount.c65
1 files changed, 65 insertions, 0 deletions
diff --git a/scripts/recordmcount.c b/scripts/recordmcount.c
index 5423a58d1b06..aeb34223167c 100644
--- a/scripts/recordmcount.c
+++ b/scripts/recordmcount.c
@@ -213,6 +213,59 @@ static int make_nop_x86(void *map, size_t const offset)
213 return 0; 213 return 0;
214} 214}
215 215
216static unsigned char ideal_nop4_arm_le[4] = { 0x00, 0x00, 0xa0, 0xe1 }; /* mov r0, r0 */
217static unsigned char ideal_nop4_arm_be[4] = { 0xe1, 0xa0, 0x00, 0x00 }; /* mov r0, r0 */
218static unsigned char *ideal_nop4_arm;
219
220static unsigned char bl_mcount_arm_le[4] = { 0xfe, 0xff, 0xff, 0xeb }; /* bl */
221static unsigned char bl_mcount_arm_be[4] = { 0xeb, 0xff, 0xff, 0xfe }; /* bl */
222static unsigned char *bl_mcount_arm;
223
224static unsigned char push_arm_le[4] = { 0x04, 0xe0, 0x2d, 0xe5 }; /* push {lr} */
225static unsigned char push_arm_be[4] = { 0xe5, 0x2d, 0xe0, 0x04 }; /* push {lr} */
226static unsigned char *push_arm;
227
228static unsigned char ideal_nop2_thumb_le[2] = { 0x00, 0xbf }; /* nop */
229static unsigned char ideal_nop2_thumb_be[2] = { 0xbf, 0x00 }; /* nop */
230static unsigned char *ideal_nop2_thumb;
231
232static unsigned char push_bl_mcount_thumb_le[6] = { 0x00, 0xb5, 0xff, 0xf7, 0xfe, 0xff }; /* push {lr}, bl */
233static unsigned char push_bl_mcount_thumb_be[6] = { 0xb5, 0x00, 0xf7, 0xff, 0xff, 0xfe }; /* push {lr}, bl */
234static unsigned char *push_bl_mcount_thumb;
235
236static int make_nop_arm(void *map, size_t const offset)
237{
238 char *ptr;
239 int cnt = 1;
240 int nop_size;
241 size_t off = offset;
242
243 ptr = map + offset;
244 if (memcmp(ptr, bl_mcount_arm, 4) == 0) {
245 if (memcmp(ptr - 4, push_arm, 4) == 0) {
246 off -= 4;
247 cnt = 2;
248 }
249 ideal_nop = ideal_nop4_arm;
250 nop_size = 4;
251 } else if (memcmp(ptr - 2, push_bl_mcount_thumb, 6) == 0) {
252 cnt = 3;
253 nop_size = 2;
254 off -= 2;
255 ideal_nop = ideal_nop2_thumb;
256 } else
257 return -1;
258
259 /* Convert to nop */
260 ulseek(fd_map, off, SEEK_SET);
261
262 do {
263 uwrite(fd_map, ideal_nop, nop_size);
264 } while (--cnt > 0);
265
266 return 0;
267}
268
216static unsigned char ideal_nop4_arm64[4] = {0x1f, 0x20, 0x03, 0xd5}; 269static unsigned char ideal_nop4_arm64[4] = {0x1f, 0x20, 0x03, 0xd5};
217static int make_nop_arm64(void *map, size_t const offset) 270static int make_nop_arm64(void *map, size_t const offset)
218{ 271{
@@ -430,6 +483,11 @@ do_file(char const *const fname)
430 w2 = w2rev; 483 w2 = w2rev;
431 w8 = w8rev; 484 w8 = w8rev;
432 } 485 }
486 ideal_nop4_arm = ideal_nop4_arm_le;
487 bl_mcount_arm = bl_mcount_arm_le;
488 push_arm = push_arm_le;
489 ideal_nop2_thumb = ideal_nop2_thumb_le;
490 push_bl_mcount_thumb = push_bl_mcount_thumb_le;
433 break; 491 break;
434 case ELFDATA2MSB: 492 case ELFDATA2MSB:
435 if (*(unsigned char const *)&endian != 0) { 493 if (*(unsigned char const *)&endian != 0) {
@@ -438,6 +496,11 @@ do_file(char const *const fname)
438 w2 = w2rev; 496 w2 = w2rev;
439 w8 = w8rev; 497 w8 = w8rev;
440 } 498 }
499 ideal_nop4_arm = ideal_nop4_arm_be;
500 bl_mcount_arm = bl_mcount_arm_be;
501 push_arm = push_arm_be;
502 ideal_nop2_thumb = ideal_nop2_thumb_be;
503 push_bl_mcount_thumb = push_bl_mcount_thumb_be;
441 break; 504 break;
442 } /* end switch */ 505 } /* end switch */
443 if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0 506 if (memcmp(ELFMAG, ehdr->e_ident, SELFMAG) != 0
@@ -463,6 +526,8 @@ do_file(char const *const fname)
463 break; 526 break;
464 case EM_ARM: reltype = R_ARM_ABS32; 527 case EM_ARM: reltype = R_ARM_ABS32;
465 altmcount = "__gnu_mcount_nc"; 528 altmcount = "__gnu_mcount_nc";
529 make_nop = make_nop_arm;
530 rel_type_nop = R_ARM_NONE;
466 break; 531 break;
467 case EM_AARCH64: 532 case EM_AARCH64:
468 reltype = R_AARCH64_ABS64; 533 reltype = R_AARCH64_ABS64;