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))
        global failcount
        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 through 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)
