from __future__ import print_function
#
# This script needs to be run on startup
# qemu -kernel ${KERNEL} -s -S
# and then:
# gdb ${KERNEL}.vmlinux -x ${QEMU_SRC}/tests/guest-debug/test-gdbstub.py

import gdb

failcount = 0


def report(cond, msg):
    "Report success/fail of test"
    if cond:
        print ("PASS: %s" % (msg))
    else:
        print ("FAIL: %s" % (msg))
        failcount += 1


def check_step():
    "Step an instruction, check it moved."
    start_pc = gdb.parse_and_eval('$pc')
    gdb.execute("si")
    end_pc = gdb.parse_and_eval('$pc')

    return not (start_pc == end_pc)


def check_break(sym_name):
    "Setup breakpoint, continue and check we stopped."
    sym, ok = gdb.lookup_symbol(sym_name)
    bp = gdb.Breakpoint(sym_name)

    gdb.execute("c")

    # hopefully we came back
    end_pc = gdb.parse_and_eval('$pc')
    print ("%s == %s %d" % (end_pc, sym.value(), bp.hit_count))
    bp.delete()

    # can we test we hit bp?
    return end_pc == sym.value()


# We need to do hbreak manually as the python interface doesn't export it
def check_hbreak(sym_name):
    "Setup hardware breakpoint, continue and check we stopped."
    sym, ok = gdb.lookup_symbol(sym_name)
    gdb.execute("hbreak %s" % (sym_name))
    gdb.execute("c")

    # hopefully we came back
    end_pc = gdb.parse_and_eval('$pc')
    print ("%s == %s" % (end_pc, sym.value()))

    if end_pc == sym.value():
        gdb.execute("d 1")
        return True
    else:
        return False


class WatchPoint(gdb.Breakpoint):

    def get_wpstr(self, sym_name):
        "Setup sym and wp_str for given symbol."
        self.sym, ok = gdb.lookup_symbol(sym_name)
        wp_addr = gdb.parse_and_eval(sym_name).address
        self.wp_str = '*(%(type)s)(&%(address)s)' % dict(
            type = wp_addr.type, address = sym_name)

        return(self.wp_str)

    def __init__(self, sym_name, type):
        wp_str = self.get_wpstr(sym_name)
        super(WatchPoint, self).__init__(wp_str, gdb.BP_WATCHPOINT, type)

    def stop(self):
        end_pc = gdb.parse_and_eval('$pc')
        print ("HIT WP @ %s" % (end_pc))
        return True


def do_one_watch(sym, wtype, text):

    wp = WatchPoint(sym, wtype)
    gdb.execute("c")
    report_str = "%s for %s (%s)" % (text, sym, wp.sym.value())

    if wp.hit_count > 0:
        report(True, report_str)
        wp.delete()
    else:
        report(False, report_str)


def check_watches(sym_name):
    "Watch a symbol for any access."

    # Should hit for any read
    do_one_watch(sym_name, gdb.WP_ACCESS, "awatch")

    # Again should hit for reads
    do_one_watch(sym_name, gdb.WP_READ, "rwatch")

    # Finally when it is written
    do_one_watch(sym_name, gdb.WP_WRITE, "watch")


class CatchBreakpoint(gdb.Breakpoint):
    def __init__(self, sym_name):
        super(CatchBreakpoint, self).__init__(sym_name)
        self.sym, ok = gdb.lookup_symbol(sym_name)

    def stop(self):
        end_pc = gdb.parse_and_eval('$pc')
        print ("CB: %s == %s" % (end_pc, self.sym.value()))
        if end_pc == self.sym.value():
            report(False, "Hit final catchpoint")


def run_test():
    "Run throught the tests one by one"

    print ("Checking we can step the first few instructions")
    step_ok = 0
    for i in range(3):
        if check_step():
            step_ok += 1

    report(step_ok == 3, "single step in boot code")

    print ("Checking HW breakpoint works")
    break_ok = check_hbreak("kernel_init")
    report(break_ok, "hbreak @ kernel_init")

    # Can't set this up until we are in the kernel proper
    # if we make it to run_init_process we've over-run and
    # one of the tests failed
    print ("Setup catch-all for run_init_process")
    cbp = CatchBreakpoint("run_init_process")
    cpb2 = CatchBreakpoint("try_to_run_init_process")

    print ("Checking Normal breakpoint works")
    break_ok = check_break("wait_for_completion")
    report(break_ok, "break @ wait_for_completion")

    print ("Checking watchpoint works")
    check_watches("system_state")

#
# This runs as the script it sourced (via -x)
#

try:
    print ("Connecting to remote")
    gdb.execute("target remote localhost:1234")

    # These are not very useful in scripts
    gdb.execute("set pagination off")
    gdb.execute("set confirm off")

    # Run the actual tests
    run_test()

except:
    print ("GDB Exception: %s" % (sys.exc_info()[0]))
    failcount += 1
    import code
    code.InteractiveConsole(locals=globals()).interact()
    raise

# Finally kill the inferior and exit gdb with a count of failures
gdb.execute("kill")
exit(failcount)
