diff options
Diffstat (limited to 'scripts/recordmcount.pl')
| -rwxr-xr-x | scripts/recordmcount.pl | 61 |
1 files changed, 58 insertions, 3 deletions
diff --git a/scripts/recordmcount.pl b/scripts/recordmcount.pl index f0d14452632b..92f09fe9639e 100755 --- a/scripts/recordmcount.pl +++ b/scripts/recordmcount.pl | |||
| @@ -113,13 +113,13 @@ $P =~ s@.*/@@g; | |||
| 113 | 113 | ||
| 114 | my $V = '0.1'; | 114 | my $V = '0.1'; |
| 115 | 115 | ||
| 116 | if ($#ARGV != 10) { | 116 | if ($#ARGV != 11) { |
| 117 | print "usage: $P arch bits objdump objcopy cc ld nm rm mv is_module inputfile\n"; | 117 | print "usage: $P arch endian bits objdump objcopy cc ld nm rm mv is_module inputfile\n"; |
| 118 | print "version: $V\n"; | 118 | print "version: $V\n"; |
| 119 | exit(1); | 119 | exit(1); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | my ($arch, $bits, $objdump, $objcopy, $cc, | 122 | my ($arch, $endian, $bits, $objdump, $objcopy, $cc, |
| 123 | $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV; | 123 | $ld, $nm, $rm, $mv, $is_module, $inputfile) = @ARGV; |
| 124 | 124 | ||
| 125 | # This file refers to mcount and shouldn't be ftraced, so lets' ignore it | 125 | # This file refers to mcount and shouldn't be ftraced, so lets' ignore it |
| @@ -295,6 +295,61 @@ if ($arch eq "x86_64") { | |||
| 295 | $ld .= " -m elf64_sparc"; | 295 | $ld .= " -m elf64_sparc"; |
| 296 | $cc .= " -m64"; | 296 | $cc .= " -m64"; |
| 297 | $objcopy .= " -O elf64-sparc"; | 297 | $objcopy .= " -O elf64-sparc"; |
| 298 | } elsif ($arch eq "mips") { | ||
| 299 | # To enable module support, we need to enable the -mlong-calls option | ||
| 300 | # of gcc for module, after using this option, we can not get the real | ||
| 301 | # offset of the calling to _mcount, but the offset of the lui | ||
| 302 | # instruction or the addiu one. herein, we record the address of the | ||
| 303 | # first one, and then we can replace this instruction by a branch | ||
| 304 | # instruction to jump over the profiling function to filter the | ||
| 305 | # indicated functions, or swith back to the lui instruction to trace | ||
| 306 | # them, which means dynamic tracing. | ||
| 307 | # | ||
| 308 | # c: 3c030000 lui v1,0x0 | ||
| 309 | # c: R_MIPS_HI16 _mcount | ||
| 310 | # c: R_MIPS_NONE *ABS* | ||
| 311 | # c: R_MIPS_NONE *ABS* | ||
| 312 | # 10: 64630000 daddiu v1,v1,0 | ||
| 313 | # 10: R_MIPS_LO16 _mcount | ||
| 314 | # 10: R_MIPS_NONE *ABS* | ||
| 315 | # 10: R_MIPS_NONE *ABS* | ||
| 316 | # 14: 03e0082d move at,ra | ||
| 317 | # 18: 0060f809 jalr v1 | ||
| 318 | # | ||
| 319 | # for the kernel: | ||
| 320 | # | ||
| 321 | # 10: 03e0082d move at,ra | ||
| 322 | # 14: 0c000000 jal 0 <loongson_halt> | ||
| 323 | # 14: R_MIPS_26 _mcount | ||
| 324 | # 14: R_MIPS_NONE *ABS* | ||
| 325 | # 14: R_MIPS_NONE *ABS* | ||
| 326 | # 18: 00020021 nop | ||
| 327 | if ($is_module eq "0") { | ||
| 328 | $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; | ||
| 329 | } else { | ||
| 330 | $mcount_regex = "^\\s*([0-9a-fA-F]+): R_MIPS_HI16\\s+_mcount\$"; | ||
| 331 | } | ||
| 332 | $objdump .= " -Melf-trad".$endian."mips "; | ||
| 333 | |||
| 334 | if ($endian eq "big") { | ||
| 335 | $endian = " -EB "; | ||
| 336 | $ld .= " -melf".$bits."btsmip"; | ||
| 337 | } else { | ||
| 338 | $endian = " -EL "; | ||
| 339 | $ld .= " -melf".$bits."ltsmip"; | ||
| 340 | } | ||
| 341 | |||
| 342 | $cc .= " -mno-abicalls -fno-pic -mabi=" . $bits . $endian; | ||
| 343 | $ld .= $endian; | ||
| 344 | |||
| 345 | if ($bits == 64) { | ||
| 346 | $function_regex = | ||
| 347 | "^([0-9a-fA-F]+)\\s+<(.|[^\$]L.*?|\$[^L].*?|[^\$][^L].*?)>:"; | ||
| 348 | $type = ".dword"; | ||
| 349 | } | ||
| 350 | } elsif ($arch eq "microblaze") { | ||
| 351 | # Microblaze calls '_mcount' instead of plain 'mcount'. | ||
| 352 | $mcount_regex = "^\\s*([0-9a-fA-F]+):.*\\s_mcount\$"; | ||
| 298 | } else { | 353 | } else { |
| 299 | die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; | 354 | die "Arch $arch is not supported with CONFIG_FTRACE_MCOUNT_RECORD"; |
| 300 | } | 355 | } |
