OSDN Git Service

gn build: Merge r366361.
[android-x86/external-llvm.git] / utils / indirect_calls.py
1 #!/usr/bin/env python
2
3 """A tool for looking for indirect jumps and calls in x86 binaries.
4
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).
8
9    Depends on llvm-objdump being in your path and is tied to the
10    dump format.
11 """
12
13 from __future__ import print_function
14
15 import os
16 import sys
17 import re
18 import subprocess
19 import optparse
20
21 # Look for indirect calls/jmps in a binary. re: (call|jmp).*\* 
22 def look_for_indirect(file):
23     args = ['llvm-objdump']
24     args.extend(["-d"])
25     args.extend([file])
26
27     p = subprocess.Popen(args=args, stdin=None, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
28     (stdout,stderr) = p.communicate()
29
30     function = ""
31     for line in stdout.splitlines():
32         if line.startswith(' ') == False:
33             function = line
34         result = re.search('(call|jmp).*\*', line)
35         if result != None:
36             # TODO: Perhaps use cxxfilt to demangle functions?
37             print(function)
38             print(line)
39     return
40
41 def main(args):
42     # No options currently other than the binary.
43     parser = optparse.OptionParser("%prog [options] <binary>")
44     (opts, args) = parser.parse_args(args)
45     if len(args) != 2:
46         parser.error("invalid number of arguments: %s" % len(args))
47     look_for_indirect(args[1])
48
49 if __name__ == '__main__':
50     main(sys.argv)