1*515bc8c1Sserge-sans-paille#!/usr/bin/env python
25d5028b5SGreg Clayton
35d5028b5SGreg Clayton#----------------------------------------------------------------------
45d5028b5SGreg Clayton# Be sure to add the python path that points to the LLDB shared library.
55d5028b5SGreg Clayton# On MacOSX csh, tcsh:
65d5028b5SGreg Clayton#   setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
75d5028b5SGreg Clayton# On MacOSX sh, bash:
85d5028b5SGreg Clayton#   export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
95d5028b5SGreg Clayton#----------------------------------------------------------------------
105d5028b5SGreg Clayton
115d5028b5SGreg Claytonimport lldb
125d5028b5SGreg Claytonimport os
135d5028b5SGreg Claytonimport sys
145d5028b5SGreg Clayton
15b9c1b51eSKate Stone
165d5028b5SGreg Claytondef disassemble_instructions(insts):
17e25799b9SJohnny Chen    for i in insts:
18525cd59fSSerge Guelton        print(i)
195d5028b5SGreg Clayton
20b9c1b51eSKate Stone
21b0b8853aSJohnny Chendef usage():
22525cd59fSSerge Guelton    print("Usage: disasm.py [-n name] executable-image")
23525cd59fSSerge Guelton    print("       By default, it breaks at and disassembles the 'main' function.")
24b0b8853aSJohnny Chen    sys.exit(0)
25b0b8853aSJohnny Chen
26b0b8853aSJohnny Chenif len(sys.argv) == 2:
27b0b8853aSJohnny Chen    fname = 'main'
28b0b8853aSJohnny Chen    exe = sys.argv[1]
29b0b8853aSJohnny Chenelif len(sys.argv) == 4:
30b0b8853aSJohnny Chen    if sys.argv[1] != '-n':
31b0b8853aSJohnny Chen        usage()
32b0b8853aSJohnny Chen    else:
33b0b8853aSJohnny Chen        fname = sys.argv[2]
34b0b8853aSJohnny Chen        exe = sys.argv[3]
35b0b8853aSJohnny Chenelse:
36b0b8853aSJohnny Chen    usage()
37b0b8853aSJohnny Chen
385d5028b5SGreg Clayton# Create a new debugger instance
395d5028b5SGreg Claytondebugger = lldb.SBDebugger.Create()
405d5028b5SGreg Clayton
415d5028b5SGreg Clayton# When we step or continue, don't return from the function until the process
425d5028b5SGreg Clayton# stops. We do this by setting the async mode to false.
435d5028b5SGreg Claytondebugger.SetAsync(False)
445d5028b5SGreg Clayton
455d5028b5SGreg Clayton# Create a target from a file and arch
46525cd59fSSerge Gueltonprint("Creating a target for '%s'" % exe)
4705faeb71SGreg Clayton
48b0b8853aSJohnny Chentarget = debugger.CreateTargetWithFileAndArch(exe, lldb.LLDB_ARCH_DEFAULT)
495d5028b5SGreg Clayton
509a26f0f2SJohnny Chenif target:
515d5028b5SGreg Clayton    # If the target is valid set a breakpoint at main
52b9c1b51eSKate Stone    main_bp = target.BreakpointCreateByName(
53b9c1b51eSKate Stone        fname, target.GetExecutable().GetFilename())
545d5028b5SGreg Clayton
55525cd59fSSerge Guelton    print(main_bp)
5605faeb71SGreg Clayton
575d5028b5SGreg Clayton    # Launch the process. Since we specified synchronous mode, we won't return
585d5028b5SGreg Clayton    # from this function until we hit the breakpoint at main
592cf62497SJohnny Chen    process = target.LaunchSimple(None, None, os.getcwd())
605d5028b5SGreg Clayton
615d5028b5SGreg Clayton    # Make sure the launch went ok
629a26f0f2SJohnny Chen    if process:
635d5028b5SGreg Clayton        # Print some simple process info
6405faeb71SGreg Clayton        state = process.GetState()
65525cd59fSSerge Guelton        print(process)
6605faeb71SGreg Clayton        if state == lldb.eStateStopped:
675d5028b5SGreg Clayton            # Get the first thread
685d5028b5SGreg Clayton            thread = process.GetThreadAtIndex(0)
699a26f0f2SJohnny Chen            if thread:
705d5028b5SGreg Clayton                # Print some simple thread info
71525cd59fSSerge Guelton                print(thread)
725d5028b5SGreg Clayton                # Get the first frame
735d5028b5SGreg Clayton                frame = thread.GetFrameAtIndex(0)
749a26f0f2SJohnny Chen                if frame:
755d5028b5SGreg Clayton                    # Print some simple frame info
76525cd59fSSerge Guelton                    print(frame)
775d5028b5SGreg Clayton                    function = frame.GetFunction()
785d5028b5SGreg Clayton                    # See if we have debug info (a function)
799a26f0f2SJohnny Chen                    if function:
80b9c1b51eSKate Stone                        # We do have a function, print some info for the
81b9c1b51eSKate Stone                        # function
82525cd59fSSerge Guelton                        print(function)
83b9c1b51eSKate Stone                        # Now get all instructions for this function and print
84b9c1b51eSKate Stone                        # them
855d5028b5SGreg Clayton                        insts = function.GetInstructions(target)
865d5028b5SGreg Clayton                        disassemble_instructions(insts)
875d5028b5SGreg Clayton                    else:
88b9c1b51eSKate Stone                        # See if we have a symbol in the symbol table for where
89b9c1b51eSKate Stone                        # we stopped
90b9c1b51eSKate Stone                        symbol = frame.GetSymbol()
919a26f0f2SJohnny Chen                        if symbol:
92b9c1b51eSKate Stone                            # We do have a symbol, print some info for the
93b9c1b51eSKate Stone                            # symbol
94525cd59fSSerge Guelton                            print(symbol)
95b9c1b51eSKate Stone                            # Now get all instructions for this symbol and
96b9c1b51eSKate Stone                            # print them
975d5028b5SGreg Clayton                            insts = symbol.GetInstructions(target)
985d5028b5SGreg Clayton                            disassemble_instructions(insts)
99406ef962SJim Ingham
100406ef962SJim Ingham                    registerList = frame.GetRegisters()
101525cd59fSSerge Guelton                    print("Frame registers (size of register set = %d):" % registerList.GetSize())
102e25799b9SJohnny Chen                    for value in registerList:
103e25799b9SJohnny Chen                        # print value
104525cd59fSSerge Guelton                        print("%s (number of children = %d):" % (value.GetName(), value.GetNumChildren()))
105e25799b9SJohnny Chen                        for child in value:
106525cd59fSSerge Guelton                            print("Name: ", child.GetName(), " Value: ", child.GetValue())
107406ef962SJim Ingham
108525cd59fSSerge Guelton            print("Hit the breakpoint at main, enter to continue and wait for program to exit or 'Ctrl-D'/'quit' to terminate the program")
1092dda9169SJohnny Chen            next = sys.stdin.readline()
1102dda9169SJohnny Chen            if not next or next.rstrip('\n') == 'quit':
111525cd59fSSerge Guelton                print("Terminating the inferior process...")
1122dda9169SJohnny Chen                process.Kill()
1132dda9169SJohnny Chen            else:
1145d5028b5SGreg Clayton                # Now continue to the program exit
1155d5028b5SGreg Clayton                process.Continue()
1165d5028b5SGreg Clayton                # When we return from the above function we will hopefully be at the
1175d5028b5SGreg Clayton                # program exit. Print out some process info
118525cd59fSSerge Guelton                print(process)
11905faeb71SGreg Clayton        elif state == lldb.eStateExited:
120525cd59fSSerge Guelton            print("Didn't hit the breakpoint at main, program has exited...")
12105faeb71SGreg Clayton        else:
122525cd59fSSerge Guelton            print("Unexpected process state: %s, killing process..." % debugger.StateAsCString(state))
12305faeb71SGreg Clayton            process.Kill()
12405faeb71SGreg Clayton
1255d5028b5SGreg Clayton
1265d5028b5SGreg Claytonlldb.SBDebugger.Terminate()
127