#!/usr/bin/env python

# Copyright 2016 The Fuchsia Authors
#
# Use of this source code is governed by a MIT-style
# license that can be found in the LICENSE file or at
# https://opensource.org/licenses/MIT

"""

This tool will symbolize a crash from Zircon's crash logger, adding
function names and, if available, source code locations (filenames and
line numbers from debug info).

Example usage #1:
  ./scripts/run-zircon -a x86-64 | ./scripts/symbolize devmgr.elf --build-dir=build-zircon-pc-x86-64

Example usage #2:
  ./scripts/symbolize devmgr.elf --build-dir=build-zircon-pc-x86-64
  <copy and paste output from Zircon>

Example usage #3 (for zircon kernel output):
  ./scripts/symbolize --build-dir=build-zircon-pc-x86-64
  <copy and paste output from Zircon>


"""

import argparse
import errno
import os
import re
import subprocess
import sys

SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
PREBUILTS_BASE_DIR = os.path.abspath(os.path.join(os.path.dirname(SCRIPT_DIR), "prebuilt",
                                                  "downloads"))
GCC_VERSION = '6.3.0'
name_to_full_path = {}


def find_func(find_args, dirname, names):
    if find_args["path"] != "":  # found something!
        return
    if dirname.find("sysroot") != -1:
        return
    for name in names:
        if name == find_args["name"]:
            find_args["path"] = dirname
            return


def find_file_in_build_dir(name, build_dirs):
    find_args = {"name": name, "path": ""}
    for location in build_dirs:
        os.path.walk(location, find_func, find_args)
        if find_args["path"] != "":
            return os.path.abspath(os.path.join(find_args["path"], name))
    return None


def buildid_to_full_path(buildid, build_dirs):
    for build_dir in build_dirs:
        id_file_path = os.path.join(build_dir, "ids.txt")
        if os.path.exists(id_file_path):
            with open(id_file_path) as id_file:
                for line in id_file:
                    id, path = line.split()
                    if id == buildid:
                        return path
    return None


def find_file_in_boot_manifest(boot_app_name, build_dirs):
    manifest_path = find_file_in_build_dir("bootfs.manifest", build_dirs)
    if manifest_path:
        with open(manifest_path) as manifest_file:
            for line in manifest_file:
                out_path, in_path = line.rstrip().split("=")
                if out_path == boot_app_name:
                    if in_path.endswith(".strip"):
                        in_path = in_path[:-len(".strip")]
                    return in_path
    return None


def find_dso_full_path_uncached(dso, exe_name, name_to_buildid, build_dirs):
    if dso in name_to_buildid:
        found_path = buildid_to_full_path(name_to_buildid[dso], build_dirs)
        if found_path:
            return found_path

    # The name 'app' indicates the real app name is unknown.
    # If the process has a name property that will be printed, but
    # it has a max of 32 characters so it may be insufficient.
    # Crashlogger prefixes such names with "app:" for our benefit.
    if dso == "app" or dso.startswith("app:"):
        # If an executable was passed on the command-line, try using that
        if exe_name:
            found_path = find_file_in_build_dir(exe_name, build_dirs)
            if found_path:
                return found_path

        # If this looks like a program in boot fs, consult the manifest
        if dso.startswith("app:/boot/"):
            boot_app_name = dso[len("app:/boot/"):]
            found_path = find_file_in_boot_manifest(boot_app_name, build_dirs)
            if found_path:
                return found_path
        return None

    # First, try an exact match for the filename
    found_path = find_file_in_build_dir(dso, build_dirs)
    if not found_path:
        # If that fails, and this file doesn't end with .so, try the executable
        # name
        if not dso.endswith(".so"):
            found_path = find_file_in_build_dir(exe_name, build_dirs)
    if not found_path:
        # If that still fails and this looks like an absolute path, try the
        # last path component
        if dso.startswith("/"):
            short_name = dso[dso.rfind("/"):]
            found_path = find_file_in_build_dir(short_name, build_dirs)
    return found_path


def find_dso_full_path(dso, exe_name, name_to_buildid, build_dirs):
    if dso in name_to_full_path:
        return name_to_full_path[dso]
    found_path = find_dso_full_path_uncached(dso, exe_name, name_to_buildid, build_dirs)
    if found_path:
        name_to_full_path[dso] = found_path
    return found_path


def tool_path(arch, tool):
    if sys.platform.startswith("linux"):
        platform = "Linux"
    elif sys.platform.startswith("darwin"):
        platform = "Darwin"
    else:
        raise Exception("Unsupported platform!")
    return ("%s/%s-elf-%s-%s-x86_64/bin/%s-elf-%s" %
            (PREBUILTS_BASE_DIR, arch, GCC_VERSION, platform, arch, tool))


def run_tool(arch, tool, *args):
    cmd = [tool_path(arch, tool)] + list(args)
    try:
        output = subprocess.check_output(cmd)
    except Exception as e:
        print "Calling %s failed: command %s error %s" % (tool, cmd, e)
        return False
    return output

# On BSD platforms there are cases where writing to stdout can return EAGAIN.
# In that event, retry the line again. This only manifests itself when piping
# qemu's stdout directly to this script.
def writelines(lines):
    for line in lines:
        writeline(line)


def writeline(line):
    while True:
        try:
            sys.stdout.write(line)
        except IOError as e:
            if e.errno == errno.EAGAIN:
                continue
        break


def main():
    parser = argparse.ArgumentParser(
        description=__doc__,
        formatter_class=argparse.RawDescriptionHelpFormatter)
    parser.add_argument("--file", "-f", nargs="?", type=argparse.FileType("r"),
                        default=sys.stdin,
                        help="File to read from, stdin by default")
    parser.add_argument("--build-dir", "-b", nargs="*",
                        help="List of additional build directories to search")
    parser.add_argument("--disassemble", "-d", action="store_true",
                        help="Show disassembly of each function")
    parser.add_argument("--stack_size", "-s", type=int,
                        default=256*1024,
                        help="Change the assumed size of the stack (e.g. use 1048576 for ftl or mtl default thread size")
    parser.add_argument("--echo", dest="echo", action="store_true",
                        help="Echo lines of input (on by default)")
    parser.add_argument("--no-echo", dest="echo", action="store_false",
                        help="Don't echo lines of input")
    parser.add_argument("app", nargs="?", help="Name of primary application")
    parser.set_defaults(echo=True)
    args = parser.parse_args()

    zircon_build_dir = os.path.join(
        os.path.dirname(SCRIPT_DIR), "build-zircon-pc-x86-64")
    if not os.path.exists(zircon_build_dir):
        zircon_build_dir = os.path.join(
            os.path.dirname(SCRIPT_DIR), os.pardir, "out", "build-zircon", "build-zircon-pc-x86-64")
    build_dirs = [zircon_build_dir]
    if args.build_dir:
        build_dirs = args.build_dir + build_dirs
    else:
        fuchsia_build_dir = os.path.abspath(os.path.join(
            os.path.dirname(SCRIPT_DIR), os.pardir, "out", "debug-x86-64"))
        build_dirs.insert(0, fuchsia_build_dir)

    # Parsing vars
    arch = "x86_64"
    name_to_buildid = {}
    processed_lines = []
    prev_sp = None
    prev_frame_num = None
    frame_sizes = []
    total_stack_size = 0

    # Regex for parsing
    # Either nothing, or something like "[00007.268] 00304.00325> "
    full_prefix = "^(|\[\d+\.\d+\] \d+\.\d+> )"
    btre = re.compile(full_prefix + "bt#(\d+):")
    bt_with_offset_re = re.compile(full_prefix +
        "bt#(\d+): pc 0x[0-9a-f]+ sp (0x[0-9a-f]+) \(([^,]+),(0x[0-9a-f]+)\)$")
    bt_end_re = re.compile(full_prefix + "bt#(\d+): end")
    arch_re = re.compile(full_prefix + "arch: ([\\S]+)$")
    build_id_re = re.compile(full_prefix +
        "dso: id=([0-9a-z]+) base=(0x[0-9a-f]+) name=(.+)$")
    disasm_re = re.compile("^ *(0x[0-9a-f]+)( .+)$")

    # Zircon backtraces
    zircon_crash_re = re.compile("^ZIRCON KERNEL PANIC$")
    # TODO(cja): Add ARM to the regex
    zircon_pc_re = re.compile("RIP: (0x[0-9a-z]+)")
    zircon_bt_re = re.compile(full_prefix +
        "bt#(\d+): (\dx[0-9a-fA-F]+)$")
    zircon_elf_path = ''
    zircon_bt = False
    zircon_pc = ''

    while True:
        line = args.file.readline()
        if args.echo and not args.file.isatty():
            writeline(line)
        end_of_file = (line == '')
        # Strip any trailing carriage return character ("\r"), since
        # these appear in the serial console output from QEMU.
        line = line.rstrip()
        if bt_end_re.match(line):
            if len(processed_lines) != 0:
                writeline("\nstart of symbolized stack:\n")
                writelines(processed_lines)
                writeline("end of symbolized stack\n")

                if total_stack_size > args.stack_size - 8*1024:
                    if total_stack_size >= args.stack_size:
                        message = "Overflowed stack"
                    else:
                        message = "Potentially overflowed stack"
                    writeline("WARNING: %s (total usage: %d, stack size: %d)\n" % (message, total_stack_size, args.stack_size))
                    for frame, size in frame_sizes:
                        writeline("#%s: %d bytes\n" % (frame, size))
                # Since we don't have the last stack frame, leave some leeway
                # when warning about stackoverflow
                processed_lines = []
                frames_sizes = []
                name_to_buildid = {}
                total_stack_size = 0
                prev_sp = None
                zircon_bt = False
            if end_of_file:
                break
        m = arch_re.match(line)
        if m:
            arch = m.group(2)
            continue
        m = build_id_re.match(line)
        if m:
            buildid = m.group(2)
            bias = int(m.group(3), 16)
            name = m.group(4)
            name_to_buildid[name] = buildid
            continue
        m = btre.match(line)
        if m and not zircon_bt:
            frame_num = m.group(2)
            m = bt_with_offset_re.match(line)
            if m:
                sp = int(m.group(3), 16)
                if prev_sp is not None:
                    frame_size = sp - prev_sp
                    total_stack_size += frame_size
                    frame_sizes.append((prev_frame_num, frame_size))
                prev_sp = sp
                prev_frame_num = frame_num

                dso = m.group(4)
                off = m.group(5)
                dso_full_path = find_dso_full_path(
                    dso, args.app, name_to_buildid, build_dirs)
                if dso_full_path:
                    addr2line_output = run_tool(arch, "addr2line", "-Cipfe",
                                                dso_full_path, off)
                    if addr2line_output:
                        processed_lines.append(
                            "#%s: %s" % (frame_num, addr2line_output))
                    if args.disassemble:
                        pc = int(off, 16)
                        disassembly = run_tool(
                            arch, "gdb", "--nx", "--batch", "-ex",
                            "disassemble %#x" % pc, dso_full_path)
                        if disassembly:
                            for line in disassembly.splitlines():
                                m = disasm_re.match(line)
                                if m:
                                    timestamp, addr, rest = m.groups()
                                    addr = int(addr, 16)
                                    if addr == pc:
                                        prefix = "=> "
                                    else:
                                        prefix = "   "
                                        line = "%s%#.16x%s" % (prefix, bias + addr, rest)
                                    processed_lines.append(line + "\n")
                    continue

            # fallthru print if we don't recognize the format of the backtrace entry
            processed_lines.append("#%s: (unknown)\n" % (frame_num,))

        # Zircon Specific Handling
        if zircon_crash_re.search(line):
            zircon_elf_path = find_file_in_build_dir("zircon.elf", build_dirs)
            if zircon_elf_path:
                zircon_bt = True
            else:
                sys.stderr.write("Symbolize could not find the zircon elf binary. Perhaps you need to build "
                                  "zircon or specify the build directory with -b?\n")
        m = zircon_pc_re.search(line)
        if m:
            zircon_pc = m.group(1)
        m = zircon_bt_re.match(line)
        if m and zircon_bt:
            frame_num = m.group(2)
            addr = m.group(3)
            # If we saw the instruction pointer for the fault/panic then use it once
            if zircon_pc:
                prefix = "   pc: %s => " % zircon_pc
                a2l_out = run_tool(arch, "addr2line", "-Cpife", zircon_elf_path,
                        zircon_pc)
                processed_lines.append(prefix +
                        a2l_out.replace("(inlined", (" " * len(prefix)) + "(inlined"))
                zircon_pc = None


            prefix = "bt#%s: %s => " % (frame_num, addr)
            # Subtract 1 to convert from a return address to a call site
            # address.  (To be more exact, this converts to an address that
            # is within the call site instruction.)  This adjustment gives
            # more correct results in the presence of inlining and
            # 'noreturn' functions.  (See ZX-842.)
            call_addr = "0x%x" % (int(addr, 16) - 1)
            a2l_out = run_tool(arch, "addr2line", "-Cpife", zircon_elf_path,
                               call_addr)
            # In the case of inlined methods, it is more readable if the
            # inlined lines are aligned to be to the right of "=>".
            processed_lines.append(prefix +
                    a2l_out.replace("(inlined", (" " * len(prefix)) + "(inlined"))
            continue

        # Exit if we've reached the end of stdin
        if end_of_file:
            break

if __name__ == '__main__':
    sys.exit(main())
