diff options
| author | Stephen Boyd <sboyd@codeaurora.org> | 2016-10-18 19:42:00 -0400 |
|---|---|---|
| committer | Steven Rostedt <rostedt@goodmis.org> | 2016-11-14 16:43:00 -0500 |
| commit | 9648dc15772d77b5431cd5c11675d90eee1a4c2f (patch) | |
| tree | 4bdfb2f6387d576da753982c5c27383fe419a2a6 /scripts | |
| parent | 8d414bd2f77ce858f6b9d119c63b9ce29cf0b75d (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.c | 65 |
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 | ||
| 216 | static unsigned char ideal_nop4_arm_le[4] = { 0x00, 0x00, 0xa0, 0xe1 }; /* mov r0, r0 */ | ||
| 217 | static unsigned char ideal_nop4_arm_be[4] = { 0xe1, 0xa0, 0x00, 0x00 }; /* mov r0, r0 */ | ||
| 218 | static unsigned char *ideal_nop4_arm; | ||
| 219 | |||
| 220 | static unsigned char bl_mcount_arm_le[4] = { 0xfe, 0xff, 0xff, 0xeb }; /* bl */ | ||
| 221 | static unsigned char bl_mcount_arm_be[4] = { 0xeb, 0xff, 0xff, 0xfe }; /* bl */ | ||
| 222 | static unsigned char *bl_mcount_arm; | ||
| 223 | |||
| 224 | static unsigned char push_arm_le[4] = { 0x04, 0xe0, 0x2d, 0xe5 }; /* push {lr} */ | ||
| 225 | static unsigned char push_arm_be[4] = { 0xe5, 0x2d, 0xe0, 0x04 }; /* push {lr} */ | ||
| 226 | static unsigned char *push_arm; | ||
| 227 | |||
| 228 | static unsigned char ideal_nop2_thumb_le[2] = { 0x00, 0xbf }; /* nop */ | ||
| 229 | static unsigned char ideal_nop2_thumb_be[2] = { 0xbf, 0x00 }; /* nop */ | ||
| 230 | static unsigned char *ideal_nop2_thumb; | ||
| 231 | |||
| 232 | static unsigned char push_bl_mcount_thumb_le[6] = { 0x00, 0xb5, 0xff, 0xf7, 0xfe, 0xff }; /* push {lr}, bl */ | ||
| 233 | static unsigned char push_bl_mcount_thumb_be[6] = { 0xb5, 0x00, 0xf7, 0xff, 0xff, 0xfe }; /* push {lr}, bl */ | ||
| 234 | static unsigned char *push_bl_mcount_thumb; | ||
| 235 | |||
| 236 | static 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 | |||
| 216 | static unsigned char ideal_nop4_arm64[4] = {0x1f, 0x20, 0x03, 0xd5}; | 269 | static unsigned char ideal_nop4_arm64[4] = {0x1f, 0x20, 0x03, 0xd5}; |
| 217 | static int make_nop_arm64(void *map, size_t const offset) | 270 | static 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; |
