symbolicate-ppc.py 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. #!/usr/bin/python
  2. # This filter replace all occurences of JIT_PPC_${address} by a
  3. # corresponding function name JIT_PPC_${symbol} as defined by a .map file.
  4. # TODO, add an option to append the block address (JIT_PPC_${symbol}@${addr})
  5. # Example 1: guest function profiling (excluding host callees)
  6. #
  7. # $ perf record -t $tid
  8. # $ perf script | sed 's/.*cycles: *[0-9a-f]* *//' |
  9. # python Tools/symbolicate-ppc.py ~/.dolphin-emu/Maps/${map}.map |
  10. # rankor -r | head
  11. # 10.05% JIT_Loop (/tmp/perf-15936.map)
  12. # 3.73% [unknown] (/tmp/perf-15936.map)
  13. # 1.91% VideoBackendHardware::Video_GatherPipeBursted (/opt/dolphin-2015-05-06/bin/dolphin-emu)
  14. # 1.39% JIT_PPC_PSMTXConcat (/tmp/perf-15936.map)
  15. # 1.00% JIT_PPC_zz_051754c_ (/tmp/perf-15936.map)
  16. # 0.90% JIT_PPC_zz_051751c_ (/tmp/perf-15936.map)
  17. # 0.71% JIT_PPC_zz_04339d4_ (/tmp/perf-15936.map)
  18. # 0.59% JIT_PPC_zz_05173e0_ (/tmp/perf-15936.map)
  19. # 0.57% JIT_PPC_zz_044141c_ (/tmp/perf-15936.map)
  20. # 0.54% JIT_PPC_zz_01839cc_ (/tmp/perf-15936.map)
  21. # Example 2: guest function profiling (including host callees)
  22. #
  23. # $ perf record --call-graph dwarf -t $tid
  24. # $ perf script | stackcollapse-perf.pl | sed 's/^CPU;//' |
  25. # python Tools/symbolicate-ppc.py ~/.dolphin-emu/Maps/${map}.map |
  26. # perl -pe 's/^([^; ]*).*? ([0-9]+?)$/\1 \2/' | stackcollapse-recursive.pl |
  27. # awk '{printf "%s %s\n", $2, $1}' | sort -rn | head
  28. # 5811 JIT_Loop
  29. # 2396 [unknown]
  30. # 577 JIT_PPC_PSMTXConcat
  31. # 464 JIT_PPC___restore_gpr
  32. # 396 JIT_PPC_zz_0517514_
  33. # 313 JIT_PPC_zz_04339d4_
  34. # 290 JIT_PPC_zz_05173e0_
  35. # 285 JIT_PPC_zz_01839cc_
  36. # 277 JIT_PPC_zz_04335ac_
  37. # 269 JIT_PPC_zz_0420b58_
  38. import re
  39. import sys
  40. stdin = sys.stdin
  41. stdout = sys.stdout
  42. class Symbol:
  43. def __init__(self, start, size, name):
  44. self.start = start
  45. self.end = start + size
  46. self.name = name
  47. # Read a .map file: this is a line-oriented file containing mapping from
  48. # the (PowerPC) memory addresses to function names.
  49. # The format is: "%08x %08x %08x %i %s" (address, size, address, 0, name).
  50. # They should be already be sorted.
  51. def read_map(filename):
  52. reg = re.compile("^([0-9a-f]{8}) ([0-9a-f]{8}) ([0-9a-f]{8}) ([0-9]*) (.*)$")
  53. res = []
  54. with open(filename, "r") as f:
  55. for line in f:
  56. match = reg.match(line)
  57. if match:
  58. start = int(match.group(1), 16)
  59. size = int(match.group(2), 16)
  60. name = match.group(5)
  61. res.append(Symbol(start, size, name))
  62. return res
  63. map = read_map(sys.argv[1])
  64. # Do a binary each in the map file in order to find the symbol:
  65. def lookup(address):
  66. i = 0
  67. j = len(map)
  68. while(True):
  69. if (j < i):
  70. return "JIT_PPC_[unknown]"
  71. k = round((j + i) // 2)
  72. if (address < map[k].start):
  73. j = k - 1
  74. elif (address >= map[k].end):
  75. i = k + 1
  76. else:
  77. return "JIT_PPC_" + map[k].name
  78. # Function used to replace given match:
  79. def replace(match):
  80. return lookup(int(match.group(1), 16))
  81. # Process stdin and write to stdout:
  82. for line in stdin:
  83. modline = re.sub('JIT_PPC_([0-9a-f]*)', replace, line)
  84. stdout.write(modline)