#!/usr/bin/env python3

import re
import subprocess
import sys
import traceback
import os

config = {}

# Subvert output buffering.
def puts(string):
    sys.stdout.write(string)
    sys.stdout.flush()

def pretty_print_stack(binary, line):
    addrs = line.split()[1:]
    # Addresses are return addresses unless preceded by a '@'. We want the
    # caller address so line numbers are more intuitive. Thus we subtract 1
    # from the address to get the call code.
    for i in range(len(addrs)):
        addr = addrs[i]
        if addr.startswith('@'):
            addrs[i] = addr[1:]
        else:
            addrs[i] = '%lx' % max((int(addrs[i], 16) - 1), 0)

    # Output like this:
    #        0x004002be: start64 at path/to/kvm-unit-tests-repo-worktree/x86/cstart64.S:208
    #         (inlined by) test_ept_violation at path/to/kvm-unit-tests-repo-worktree/x86/vmx_tests.c:1719 (discriminator 1)
    cmd = [config.get('ADDR2LINE', 'addr2line'), '-e', binary, '-i', '-f', '--pretty', '--address']
    cmd.extend(addrs)

    p = subprocess.Popen(cmd, stdout=subprocess.PIPE)
    out, err = p.communicate()
    if p.returncode != 0:
        puts(line)
        return

    for line in out.splitlines():
        m = re.match(rb'(.*) at (.*):(([0-9]+)|\?)([^:]*)', line)
        if m is None:
            puts('%s\n' % line)
            return

        head, path, maybeline, line, tail = m.groups()
        path = os.path.relpath(os.path.realpath(path), start=os.path.realpath(os.getcwdb()))
        puts('%s at %s:%s%s\n' % (head.decode(), path.decode(), maybeline.decode(), tail.decode()))
        if line:
            line = int(line)
            try:
                lines = open(path).readlines()
            except IOError:
                continue
            if line > 1:
                puts('        %s\n' % lines[line - 2].rstrip())
            puts('      > %s\n' % lines[line - 1].rstrip())
            if line < len(lines):
                puts('        %s\n' % lines[line].rstrip())

def main():
    if len(sys.argv) != 2:
        sys.stderr.write('usage: %s <kernel>\n' % sys.argv[0])
        sys.exit(1)

    binary = sys.argv[1]
    if binary.endswith('.flat'):
        binary = binary.replace('.flat', '.elf')
    elif binary.endswith('.efi'):
        binary += '.debug'

    with open("config.mak") as config_file:
        for line in config_file:
            name, val = line.partition("=")[::2]
            config[name.strip()] = val.strip()

    try:
        while True:
            # Subvert input buffering.
            line = sys.stdin.readline()
            if line == '':
                break

            puts(line)

            if not line.strip().startswith('STACK:'):
                continue

            try:
                pretty_print_stack(binary, line)
            except Exception:
                puts('Error pretty printing stack:\n')
                puts(traceback.format_exc())
                puts('Continuing without pretty printing...\n')
                while True:
                    puts(line)
                    line = sys.stdin.readline()
                    if line == '':
                        break
    except:
        sys.exit(1)

if __name__ == '__main__':
    main()
