xref: /llvm-project/lldb/examples/python/disasm.py (revision 2238dcc39358353cac21df75c3c3286ab20b8f53)
1#!/usr/bin/env python
2
3# ----------------------------------------------------------------------
4# Be sure to add the python path that points to the LLDB shared library.
5# On MacOSX csh, tcsh:
6#   setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
7# On MacOSX sh, bash:
8#   export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
9# ----------------------------------------------------------------------
10
11import lldb
12import os
13import sys
14
15
16def disassemble_instructions(insts):
17    for i in insts:
18        print(i)
19
20
21def usage():
22    print("Usage: disasm.py [-n name] executable-image")
23    print("       By default, it breaks at and disassembles the 'main' function.")
24    sys.exit(0)
25
26
27if len(sys.argv) == 2:
28    fname = "main"
29    exe = sys.argv[1]
30elif len(sys.argv) == 4:
31    if sys.argv[1] != "-n":
32        usage()
33    else:
34        fname = sys.argv[2]
35        exe = sys.argv[3]
36else:
37    usage()
38
39# Create a new debugger instance
40debugger = lldb.SBDebugger.Create()
41
42# When we step or continue, don't return from the function until the process
43# stops. We do this by setting the async mode to false.
44debugger.SetAsync(False)
45
46# Create a target from a file and arch
47print("Creating a target for '%s'" % exe)
48
49target = debugger.CreateTargetWithFileAndArch(exe, lldb.LLDB_ARCH_DEFAULT)
50
51if target:
52    # If the target is valid set a breakpoint at main
53    main_bp = target.BreakpointCreateByName(fname, target.GetExecutable().GetFilename())
54
55    print(main_bp)
56
57    # Launch the process. Since we specified synchronous mode, we won't return
58    # from this function until we hit the breakpoint at main
59    process = target.LaunchSimple(None, None, os.getcwd())
60
61    # Make sure the launch went ok
62    if process:
63        # Print some simple process info
64        state = process.GetState()
65        print(process)
66        if state == lldb.eStateStopped:
67            # Get the first thread
68            thread = process.GetThreadAtIndex(0)
69            if thread:
70                # Print some simple thread info
71                print(thread)
72                # Get the first frame
73                frame = thread.GetFrameAtIndex(0)
74                if frame:
75                    # Print some simple frame info
76                    print(frame)
77                    function = frame.GetFunction()
78                    # See if we have debug info (a function)
79                    if function:
80                        # We do have a function, print some info for the
81                        # function
82                        print(function)
83                        # Now get all instructions for this function and print
84                        # them
85                        insts = function.GetInstructions(target)
86                        disassemble_instructions(insts)
87                    else:
88                        # See if we have a symbol in the symbol table for where
89                        # we stopped
90                        symbol = frame.GetSymbol()
91                        if symbol:
92                            # We do have a symbol, print some info for the
93                            # symbol
94                            print(symbol)
95                            # Now get all instructions for this symbol and
96                            # print them
97                            insts = symbol.GetInstructions(target)
98                            disassemble_instructions(insts)
99
100                    registerList = frame.GetRegisters()
101                    print(
102                        "Frame registers (size of register set = %d):"
103                        % registerList.GetSize()
104                    )
105                    for value in registerList:
106                        # print value
107                        print(
108                            "%s (number of children = %d):"
109                            % (value.GetName(), value.GetNumChildren())
110                        )
111                        for child in value:
112                            print(
113                                "Name: ", child.GetName(), " Value: ", child.GetValue()
114                            )
115
116            print(
117                "Hit the breakpoint at main, enter to continue and wait for program to exit or 'Ctrl-D'/'quit' to terminate the program"
118            )
119            next = sys.stdin.readline()
120            if not next or next.rstrip("\n") == "quit":
121                print("Terminating the inferior process...")
122                process.Kill()
123            else:
124                # Now continue to the program exit
125                process.Continue()
126                # When we return from the above function we will hopefully be at the
127                # program exit. Print out some process info
128                print(process)
129        elif state == lldb.eStateExited:
130            print("Didn't hit the breakpoint at main, program has exited...")
131        else:
132            print(
133                "Unexpected process state: %s, killing process..."
134                % debugger.StateAsCString(state)
135            )
136            process.Kill()
137
138
139lldb.SBDebugger.Terminate()
140