xref: /openbsd-src/gnu/llvm/lldb/examples/python/disasm.py (revision be691f3bb6417f04a68938fadbcaee2d5795e764)
1*be691f3bSpatrick#!/usr/bin/env python
2061da546Spatrick
3061da546Spatrick#----------------------------------------------------------------------
4061da546Spatrick# Be sure to add the python path that points to the LLDB shared library.
5061da546Spatrick# On MacOSX csh, tcsh:
6061da546Spatrick#   setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
7061da546Spatrick# On MacOSX sh, bash:
8061da546Spatrick#   export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
9061da546Spatrick#----------------------------------------------------------------------
10061da546Spatrick
11061da546Spatrickimport lldb
12061da546Spatrickimport os
13061da546Spatrickimport sys
14061da546Spatrick
15061da546Spatrick
16061da546Spatrickdef disassemble_instructions(insts):
17061da546Spatrick    for i in insts:
18061da546Spatrick        print(i)
19061da546Spatrick
20061da546Spatrick
21061da546Spatrickdef usage():
22061da546Spatrick    print("Usage: disasm.py [-n name] executable-image")
23061da546Spatrick    print("       By default, it breaks at and disassembles the 'main' function.")
24061da546Spatrick    sys.exit(0)
25061da546Spatrick
26061da546Spatrickif len(sys.argv) == 2:
27061da546Spatrick    fname = 'main'
28061da546Spatrick    exe = sys.argv[1]
29061da546Spatrickelif len(sys.argv) == 4:
30061da546Spatrick    if sys.argv[1] != '-n':
31061da546Spatrick        usage()
32061da546Spatrick    else:
33061da546Spatrick        fname = sys.argv[2]
34061da546Spatrick        exe = sys.argv[3]
35061da546Spatrickelse:
36061da546Spatrick    usage()
37061da546Spatrick
38061da546Spatrick# Create a new debugger instance
39061da546Spatrickdebugger = lldb.SBDebugger.Create()
40061da546Spatrick
41061da546Spatrick# When we step or continue, don't return from the function until the process
42061da546Spatrick# stops. We do this by setting the async mode to false.
43061da546Spatrickdebugger.SetAsync(False)
44061da546Spatrick
45061da546Spatrick# Create a target from a file and arch
46061da546Spatrickprint("Creating a target for '%s'" % exe)
47061da546Spatrick
48061da546Spatricktarget = debugger.CreateTargetWithFileAndArch(exe, lldb.LLDB_ARCH_DEFAULT)
49061da546Spatrick
50061da546Spatrickif target:
51061da546Spatrick    # If the target is valid set a breakpoint at main
52061da546Spatrick    main_bp = target.BreakpointCreateByName(
53061da546Spatrick        fname, target.GetExecutable().GetFilename())
54061da546Spatrick
55061da546Spatrick    print(main_bp)
56061da546Spatrick
57061da546Spatrick    # Launch the process. Since we specified synchronous mode, we won't return
58061da546Spatrick    # from this function until we hit the breakpoint at main
59061da546Spatrick    process = target.LaunchSimple(None, None, os.getcwd())
60061da546Spatrick
61061da546Spatrick    # Make sure the launch went ok
62061da546Spatrick    if process:
63061da546Spatrick        # Print some simple process info
64061da546Spatrick        state = process.GetState()
65061da546Spatrick        print(process)
66061da546Spatrick        if state == lldb.eStateStopped:
67061da546Spatrick            # Get the first thread
68061da546Spatrick            thread = process.GetThreadAtIndex(0)
69061da546Spatrick            if thread:
70061da546Spatrick                # Print some simple thread info
71061da546Spatrick                print(thread)
72061da546Spatrick                # Get the first frame
73061da546Spatrick                frame = thread.GetFrameAtIndex(0)
74061da546Spatrick                if frame:
75061da546Spatrick                    # Print some simple frame info
76061da546Spatrick                    print(frame)
77061da546Spatrick                    function = frame.GetFunction()
78061da546Spatrick                    # See if we have debug info (a function)
79061da546Spatrick                    if function:
80061da546Spatrick                        # We do have a function, print some info for the
81061da546Spatrick                        # function
82061da546Spatrick                        print(function)
83061da546Spatrick                        # Now get all instructions for this function and print
84061da546Spatrick                        # them
85061da546Spatrick                        insts = function.GetInstructions(target)
86061da546Spatrick                        disassemble_instructions(insts)
87061da546Spatrick                    else:
88061da546Spatrick                        # See if we have a symbol in the symbol table for where
89061da546Spatrick                        # we stopped
90061da546Spatrick                        symbol = frame.GetSymbol()
91061da546Spatrick                        if symbol:
92061da546Spatrick                            # We do have a symbol, print some info for the
93061da546Spatrick                            # symbol
94061da546Spatrick                            print(symbol)
95061da546Spatrick                            # Now get all instructions for this symbol and
96061da546Spatrick                            # print them
97061da546Spatrick                            insts = symbol.GetInstructions(target)
98061da546Spatrick                            disassemble_instructions(insts)
99061da546Spatrick
100061da546Spatrick                    registerList = frame.GetRegisters()
101061da546Spatrick                    print("Frame registers (size of register set = %d):" % registerList.GetSize())
102061da546Spatrick                    for value in registerList:
103061da546Spatrick                        # print value
104061da546Spatrick                        print("%s (number of children = %d):" % (value.GetName(), value.GetNumChildren()))
105061da546Spatrick                        for child in value:
106061da546Spatrick                            print("Name: ", child.GetName(), " Value: ", child.GetValue())
107061da546Spatrick
108061da546Spatrick            print("Hit the breakpoint at main, enter to continue and wait for program to exit or 'Ctrl-D'/'quit' to terminate the program")
109061da546Spatrick            next = sys.stdin.readline()
110061da546Spatrick            if not next or next.rstrip('\n') == 'quit':
111061da546Spatrick                print("Terminating the inferior process...")
112061da546Spatrick                process.Kill()
113061da546Spatrick            else:
114061da546Spatrick                # Now continue to the program exit
115061da546Spatrick                process.Continue()
116061da546Spatrick                # When we return from the above function we will hopefully be at the
117061da546Spatrick                # program exit. Print out some process info
118061da546Spatrick                print(process)
119061da546Spatrick        elif state == lldb.eStateExited:
120061da546Spatrick            print("Didn't hit the breakpoint at main, program has exited...")
121061da546Spatrick        else:
122061da546Spatrick            print("Unexpected process state: %s, killing process..." % debugger.StateAsCString(state))
123061da546Spatrick            process.Kill()
124061da546Spatrick
125061da546Spatrick
126061da546Spatricklldb.SBDebugger.Terminate()
127