#!/usr/bin/env python3

# ----------------------------------------------------------------------
# Be sure to add the python path that points to the LLDB shared library.
# On MacOSX csh, tcsh:
#   setenv PYTHONPATH /Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
# On MacOSX sh, bash:
#   export PYTHONPATH=/Developer/Library/PrivateFrameworks/LLDB.framework/Resources/Python
# ----------------------------------------------------------------------

import lldb
import os
import sys


def disassemble_instructions(insts):
    for i in insts:
        print(i)


def usage():
    print("Usage: disasm.py [-n name] executable-image")
    print("       By default, it breaks at and disassembles the 'main' function.")
    sys.exit(0)


if len(sys.argv) == 2:
    fname = "main"
    exe = sys.argv[1]
elif len(sys.argv) == 4:
    if sys.argv[1] != "-n":
        usage()
    else:
        fname = sys.argv[2]
        exe = sys.argv[3]
else:
    usage()

# Create a new debugger instance
debugger = lldb.SBDebugger.Create()

# When we step or continue, don't return from the function until the process
# stops. We do this by setting the async mode to false.
debugger.SetAsync(False)

# Create a target from a file and arch
print("Creating a target for '%s'" % exe)

target = debugger.CreateTargetWithFileAndArch(exe, lldb.LLDB_ARCH_DEFAULT)

if target:
    # If the target is valid set a breakpoint at main
    main_bp = target.BreakpointCreateByName(fname, target.GetExecutable().GetFilename())

    print(main_bp)

    # Launch the process. Since we specified synchronous mode, we won't return
    # from this function until we hit the breakpoint at main
    process = target.LaunchSimple(None, None, os.getcwd())

    # Make sure the launch went ok
    if process:
        # Print some simple process info
        state = process.GetState()
        print(process)
        if state == lldb.eStateStopped:
            # Get the first thread
            thread = process.GetThreadAtIndex(0)
            if thread:
                # Print some simple thread info
                print(thread)
                # Get the first frame
                frame = thread.GetFrameAtIndex(0)
                if frame:
                    # Print some simple frame info
                    print(frame)
                    function = frame.GetFunction()
                    # See if we have debug info (a function)
                    if function:
                        # We do have a function, print some info for the
                        # function
                        print(function)
                        # Now get all instructions for this function and print
                        # them
                        insts = function.GetInstructions(target)
                        disassemble_instructions(insts)
                    else:
                        # See if we have a symbol in the symbol table for where
                        # we stopped
                        symbol = frame.GetSymbol()
                        if symbol:
                            # We do have a symbol, print some info for the
                            # symbol
                            print(symbol)
                            # Now get all instructions for this symbol and
                            # print them
                            insts = symbol.GetInstructions(target)
                            disassemble_instructions(insts)

                    registerList = frame.GetRegisters()
                    print(
                        "Frame registers (size of register set = %d):"
                        % registerList.GetSize()
                    )
                    for value in registerList:
                        # print value
                        print(
                            "%s (number of children = %d):"
                            % (value.GetName(), value.GetNumChildren())
                        )
                        for child in value:
                            print(
                                "Name: ", child.GetName(), " Value: ", child.GetValue()
                            )

            print(
                "Hit the breakpoint at main, enter to continue and wait for program to exit or 'Ctrl-D'/'quit' to terminate the program"
            )
            next = sys.stdin.readline()
            if not next or next.rstrip("\n") == "quit":
                print("Terminating the inferior process...")
                process.Kill()
            else:
                # Now continue to the program exit
                process.Continue()
                # When we return from the above function we will hopefully be at the
                # program exit. Print out some process info
                print(process)
        elif state == lldb.eStateExited:
            print("Didn't hit the breakpoint at main, program has exited...")
        else:
            print(
                "Unexpected process state: %s, killing process..."
                % debugger.StateAsCString(state)
            )
            process.Kill()


lldb.SBDebugger.Terminate()
