[llvm-exegesis][NFC] Pass Instruction instead of bare Opcode
[llvm-core.git] / utils / indirect_calls.py
blobb7349a6d884f87713c42738a7159d0e0d7727207
1 #!/usr/bin/env python
3 """A tool for looking for indirect jumps and calls in x86 binaries.
5 Helpful to verify whether or not retpoline mitigations are catching
6 all of the indirect branches in a binary and telling you which
7 functions the remaining ones are in (assembly, etc).
9 Depends on llvm-objdump being in your path and is tied to the
10 dump format.
11 """
13 import os
14 import sys
15 import re
16 import subprocess
17 import optparse
19 # Look for indirect calls/jmps in a binary. re: (call|jmp).*\*
20 def look_for_indirect(file):
21 args = ['llvm-objdump']
22 args.extend(["-d"])
23 args.extend([file])
25 p = subprocess.Popen(args=args, stdin=None, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
26 (stdout,stderr) = p.communicate()
28 function = ""
29 for line in stdout.splitlines():
30 if line.startswith(' ') == False:
31 function = line
32 result = re.search('(call|jmp).*\*', line)
33 if result != None:
34 # TODO: Perhaps use cxxfilt to demangle functions?
35 print function
36 print line
37 return
39 def main(args):
40 # No options currently other than the binary.
41 parser = optparse.OptionParser("%prog [options] <binary>")
42 (opts, args) = parser.parse_args(args)
43 if len(args) != 2:
44 parser.error("invalid number of arguments: %s" % len(args))
45 look_for_indirect(args[1])
47 if __name__ == '__main__':
48 main(sys.argv)