summaryrefslogtreecommitdiff
path: root/utils/test/disasm.py
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-08-20 18:01:57 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-08-20 18:01:57 +0000
commit88c643b6fec27eec436c8d138fee6346e92337d6 (patch)
tree82cd13b2f3cde1c9e5f79689ba4e6ba67694843f /utils/test/disasm.py
parent94994d372d014ce4c8758b9605d63fae651bd8aa (diff)
Notes
Diffstat (limited to 'utils/test/disasm.py')
-rwxr-xr-xutils/test/disasm.py236
1 files changed, 0 insertions, 236 deletions
diff --git a/utils/test/disasm.py b/utils/test/disasm.py
deleted file mode 100755
index e75c070e0117..000000000000
--- a/utils/test/disasm.py
+++ /dev/null
@@ -1,236 +0,0 @@
-#!/usr/bin/env python
-
-"""
-Run gdb to disassemble a function, feed the bytes to 'llvm-mc -disassemble' command,
-and display the disassembly result.
-
-"""
-
-import os
-import sys
-from optparse import OptionParser
-
-
-def is_exe(fpath):
- """Check whether fpath is an executable."""
- return os.path.isfile(fpath) and os.access(fpath, os.X_OK)
-
-
-def which(program):
- """Find the full path to a program, or return None."""
- fpath, fname = os.path.split(program)
- if fpath:
- if is_exe(program):
- return program
- else:
- for path in os.environ["PATH"].split(os.pathsep):
- exe_file = os.path.join(path, program)
- if is_exe(exe_file):
- return exe_file
- return None
-
-
-def do_llvm_mc_disassembly(
- gdb_commands,
- gdb_options,
- exe,
- func,
- mc,
- mc_options):
- from cStringIO import StringIO
- import pexpect
-
- gdb_prompt = "\r\n\(gdb\) "
- gdb = pexpect.spawn(('gdb %s' % gdb_options) if gdb_options else 'gdb')
- # Turn on logging for what gdb sends back.
- gdb.logfile_read = sys.stdout
- gdb.expect(gdb_prompt)
-
- # See if there any extra command(s) to execute before we issue the file
- # command.
- for cmd in gdb_commands:
- gdb.sendline(cmd)
- gdb.expect(gdb_prompt)
-
- # Now issue the file command.
- gdb.sendline('file %s' % exe)
- gdb.expect(gdb_prompt)
-
- # Send the disassemble command.
- gdb.sendline('disassemble %s' % func)
- gdb.expect(gdb_prompt)
-
- # Get the output from gdb.
- gdb_output = gdb.before
-
- # Use StringIO to record the memory dump as well as the gdb assembler code.
- mc_input = StringIO()
-
- # These keep track of the states of our simple gdb_output parser.
- prev_line = None
- prev_addr = None
- curr_addr = None
- addr_diff = 0
- looking = False
- for line in gdb_output.split(os.linesep):
- if line.startswith('Dump of assembler code'):
- looking = True
- continue
-
- if line.startswith('End of assembler dump.'):
- looking = False
- prev_addr = curr_addr
- if mc_options and mc_options.find('arm') != -1:
- addr_diff = 4
- if mc_options and mc_options.find('thumb') != -1:
- # It is obviously wrong to assume the last instruction of the
- # function has two bytes.
- # FIXME
- addr_diff = 2
-
- if looking and line.startswith('0x'):
- # It's an assembler code dump.
- prev_addr = curr_addr
- curr_addr = line.split(None, 1)[0]
- if prev_addr and curr_addr:
- addr_diff = int(curr_addr, 16) - int(prev_addr, 16)
-
- if prev_addr and addr_diff > 0:
- # Feed the examining memory command to gdb.
- gdb.sendline('x /%db %s' % (addr_diff, prev_addr))
- gdb.expect(gdb_prompt)
- x_output = gdb.before
- # Get the last output line from the gdb examine memory command,
- # split the string into a 3-tuple with separator '>:' to handle
- # objc method names.
- memory_dump = x_output.split(
- os.linesep)[-1].partition('>:')[2].strip()
- # print "\nbytes:", memory_dump
- disasm_str = prev_line.partition('>:')[2]
- print >> mc_input, '%s # %s' % (memory_dump, disasm_str)
-
- # We're done with the processing. Assign the current line to be
- # prev_line.
- prev_line = line
-
- # Close the gdb session now that we are done with it.
- gdb.sendline('quit')
- gdb.expect(pexpect.EOF)
- gdb.close()
-
- # Write the memory dump into a file.
- with open('disasm-input.txt', 'w') as f:
- f.write(mc_input.getvalue())
-
- mc_cmd = '%s -disassemble %s disasm-input.txt' % (mc, mc_options)
- print "\nExecuting command:", mc_cmd
- os.system(mc_cmd)
-
- # And invoke llvm-mc with the just recorded file.
- #mc = pexpect.spawn('%s -disassemble %s disasm-input.txt' % (mc, mc_options))
- #mc.logfile_read = sys.stdout
- # print "mc:", mc
- # mc.close()
-
-
-def main():
- # This is to set up the Python path to include the pexpect-2.4 dir.
- # Remember to update this when/if things change.
- scriptPath = sys.path[0]
- sys.path.append(
- os.path.join(
- scriptPath,
- os.pardir,
- os.pardir,
- 'test',
- 'pexpect-2.4'))
-
- parser = OptionParser(usage="""\
-Run gdb to disassemble a function, feed the bytes to 'llvm-mc -disassemble' command,
-and display the disassembly result.
-
-Usage: %prog [options]
-""")
- parser.add_option(
- '-C',
- '--gdb-command',
- type='string',
- action='append',
- metavar='COMMAND',
- default=[],
- dest='gdb_commands',
- help='Command(s) gdb executes after starting up (can be empty)')
- parser.add_option(
- '-O',
- '--gdb-options',
- type='string',
- action='store',
- dest='gdb_options',
- help="""The options passed to 'gdb' command if specified.""")
- parser.add_option('-e', '--executable',
- type='string', action='store',
- dest='executable',
- help="""The executable to do disassembly on.""")
- parser.add_option(
- '-f',
- '--function',
- type='string',
- action='store',
- dest='function',
- help="""The function name (could be an address to gdb) for disassembly.""")
- parser.add_option('-m', '--llvm-mc',
- type='string', action='store',
- dest='llvm_mc',
- help="""The llvm-mc executable full path, if specified.
- Otherwise, it must be present in your PATH environment.""")
-
- parser.add_option(
- '-o',
- '--options',
- type='string',
- action='store',
- dest='llvm_mc_options',
- help="""The options passed to 'llvm-mc -disassemble' command if specified.""")
-
- opts, args = parser.parse_args()
-
- gdb_commands = opts.gdb_commands
- gdb_options = opts.gdb_options
-
- if not opts.executable:
- parser.print_help()
- sys.exit(1)
- executable = opts.executable
-
- if not opts.function:
- parser.print_help()
- sys.exit(1)
- function = opts.function
-
- llvm_mc = opts.llvm_mc if opts.llvm_mc else which('llvm-mc')
- if not llvm_mc:
- parser.print_help()
- sys.exit(1)
-
- # This is optional. For example:
- # --options='-triple=arm-apple-darwin -debug-only=arm-disassembler'
- llvm_mc_options = opts.llvm_mc_options
-
- # We have parsed the options.
- print "gdb commands:", gdb_commands
- print "gdb options:", gdb_options
- print "executable:", executable
- print "function:", function
- print "llvm-mc:", llvm_mc
- print "llvm-mc options:", llvm_mc_options
-
- do_llvm_mc_disassembly(
- gdb_commands,
- gdb_options,
- executable,
- function,
- llvm_mc,
- llvm_mc_options)
-
-if __name__ == '__main__':
- main()