#!/usr/bin/env python
# SPDX-License-Identifier: BSD-2-Clause
#
# Copyright (c) 2017, Linaro Limited
#


import argparse
import glob
import os
import re
import subprocess
import sys

CALL_STACK_RE = re.compile('Call stack:')
# This gets the address from lines looking like this:
# E/TC:0  0x001044a8
STACK_ADDR_RE = re.compile(
    r'[UEIDFM]/T[AC]:(\?+|[0-9]+) [0-9]* +(?P<addr>0x[0-9a-f]+)')
ABORT_ADDR_RE = re.compile(r'-abort at address (?P<addr>0x[0-9a-f]+)')
REGION_RE = re.compile(r'region +[0-9]+: va (?P<addr>0x[0-9a-f]+) '
                       r'pa 0x[0-9a-f]+ size (?P<size>0x[0-9a-f]+)'
                       r'( flags .{6} (\[(?P<elf_idx>[0-9]+)\])?)?')
ELF_LIST_RE = re.compile(r'\[(?P<idx>[0-9]+)\] (?P<uuid>[0-9a-f\-]+)'
                         r' @ (?P<load_addr>0x[0-9a-f\-]+)')

epilog = '''
This scripts reads an OP-TEE abort or panic message from stdin and adds debug
information to the output, such as '<function> at <file>:<line>' next to each
address in the call stack. Any message generated by OP-TEE and containing a
call stack can in principle be processed by this script. This currently
includes aborts and panics from the TEE core as well as from any TA.
The paths provided on the command line are used to locate the appropriate ELF
binary (tee.elf or Trusted Application). The GNU binutils (addr2line, objdump,
nm) are used to extract the debug info. If the CROSS_COMPILE environment
variable is set, it is used as a prefix to the binutils tools. That is, the
script will invoke $(CROSS_COMPILE)addr2line etc. If it is not set however,
the prefix will be determined automatically for each ELF file based on its
architecture (arm-linux-gnueabihf-, aarch64-linux-gnu-). The resulting command
is then expected to be found in the user's PATH.

OP-TEE abort and panic messages are sent to the secure console. They look like
the following:

  E/TC:0 User TA data-abort at address 0xffffdecd (alignment fault)
  ...
  E/TC:0 Call stack:
  E/TC:0  0x4000549e
  E/TC:0  0x40001f4b
  E/TC:0  0x4000273f
  E/TC:0  0x40005da7

Inspired by a script of the same name by the Chromium project.

Sample usage:

  $ scripts/symbolize.py -d out/arm-plat-hikey/core -d ../optee_test/out/ta/*
  <paste whole dump here>
  ^D
'''


def get_args():
    parser = argparse.ArgumentParser(
        formatter_class=argparse.RawDescriptionHelpFormatter,
        description='Symbolizes OP-TEE abort dumps',
        epilog=epilog)
    parser.add_argument('-d', '--dir', action='append', nargs='+',
                        help='Search for ELF file in DIR. tee.elf is needed '
                        'to decode a TEE Core or pseudo-TA abort, while '
                        '<TA_uuid>.elf is required if a user-mode TA has '
                        'crashed. For convenience, ELF files may also be '
                        'given.')
    parser.add_argument('-s', '--strip_path', nargs='?',
                        help='Strip STRIP_PATH from file paths (default: '
                        'current directory, use -s with no argument to show '
                        'full paths)', default=os.getcwd())

    return parser.parse_args()


class Symbolizer(object):
    def __init__(self, out, dirs, strip_path):
        self._out = out
        self._dirs = dirs
        self._strip_path = strip_path
        self._addr2line = None
        self.reset()

    def my_Popen(self, cmd):
        try:
            return subprocess.Popen(cmd, stdin=subprocess.PIPE,
                                    stdout=subprocess.PIPE)
        except OSError as e:
            if e.errno == os.errno.ENOENT:
                print >> sys.stderr, "*** Error:", cmd[0] + \
                    ": command not found"
                sys.exit(1)

    def get_elf(self, elf_or_uuid):
        if not elf_or_uuid.endswith('.elf'):
            elf_or_uuid += '.elf'
        for d in self._dirs:
            if d.endswith(elf_or_uuid) and os.path.isfile(d):
                return d
            elf = glob.glob(d + '/' + elf_or_uuid)
            if elf:
                return elf[0]

    def set_arch(self):
        if self._arch:
            return
        self._arch = os.getenv('CROSS_COMPILE')
        if self._arch:
            return
        elf = self.get_elf(self._elfs[0][0])
        if elf is None:
            return
        p = subprocess.Popen(['file', self.get_elf(self._elfs[0][0])],
                             stdout=subprocess.PIPE)
        output = p.stdout.readlines()
        p.terminate()
        if 'ARM aarch64,' in output[0]:
            self._arch = 'aarch64-linux-gnu-'
        elif 'ARM,' in output[0]:
            self._arch = 'arm-linux-gnueabihf-'

    def arch_prefix(self, cmd):
        self.set_arch()
        if self._arch is None:
            return ''
        return self._arch + cmd

    def spawn_addr2line(self, elf_name):
        if elf_name is None:
            return
        if self._addr2line_elf_name is elf_name:
            return
        if self._addr2line:
            self._addr2line.terminate
            self._addr2line = None
        elf = self.get_elf(elf_name)
        if not elf:
            return
        cmd = self.arch_prefix('addr2line')
        if not cmd:
            return
        self._addr2line = self.my_Popen([cmd, '-f', '-p', '-e', elf])
        self._addr2line_elf_name = elf_name

    # If addr falls into a region that maps a TA ELF file, return the load
    # address of that file.
    def elf_load_addr(self, addr):
        if self._regions:
            for r in self._regions:
                r_addr = int(r[0], 16)
                r_size = int(r[1], 16)
                i_addr = int(addr, 16)
                if (i_addr >= r_addr and i_addr < (r_addr + r_size)):
                    # Found region
                    elf_idx = r[2]
                    if elf_idx is not None:
                        return self._elfs[int(elf_idx)][1]
            return None
        else:
            # tee.elf
            return '0x0'

    def elf_for_addr(self, addr):
        l_addr = self.elf_load_addr(addr)
        if l_addr is None:
            return None
        if l_addr is '0x0':
            return 'tee.elf'
        for k in self._elfs:
            e = self._elfs[k]
            if int(e[1], 16) == int(l_addr, 16):
                return e[0]
        return None

    def subtract_load_addr(self, addr):
        l_addr = self.elf_load_addr(addr)
        if l_addr is None:
            return None
        if int(l_addr, 16) > int(addr, 16):
            return ''
        return '0x{:x}'.format(int(addr, 16) - int(l_addr, 16))

    def resolve(self, addr):
        reladdr = self.subtract_load_addr(addr)
        self.spawn_addr2line(self.elf_for_addr(addr))
        if not reladdr or not self._addr2line:
            return '???'
        try:
            print >> self._addr2line.stdin, reladdr
            ret = self._addr2line.stdout.readline().rstrip('\n')
        except IOError:
            ret = '!!!'
        return ret

    def symbol_plus_offset(self, addr):
        ret = ''
        prevsize = 0
        reladdr = self.subtract_load_addr(addr)
        elf_name = self.elf_for_addr(addr)
        if elf_name is None:
            return ''
        elf = self.get_elf(elf_name)
        cmd = self.arch_prefix('nm')
        if not reladdr or not elf or not cmd:
            return ''
        ireladdr = int(reladdr, 16)
        nm = self.my_Popen([cmd, '--numeric-sort', '--print-size', elf])
        for line in iter(nm.stdout.readline, ''):
            try:
                addr, size, _, name = line.split()
            except ValueError:
                # Size is missing
                try:
                    addr, _, name = line.split()
                    size = '0'
                except ValueError:
                    # E.g., undefined (external) symbols (line = "U symbol")
                    continue
            iaddr = int(addr, 16)
            isize = int(size, 16)
            if iaddr == ireladdr:
                ret = name
                break
            if iaddr < ireladdr and iaddr + isize >= ireladdr:
                offs = ireladdr - iaddr
                ret = name + '+' + str(offs)
                break
            if iaddr > ireladdr and prevsize == 0:
                offs = iaddr + ireladdr
                ret = prevname + '+' + str(offs)
                break
            prevsize = size
            prevname = name
        nm.terminate()
        return ret

    def section_plus_offset(self, addr):
        ret = ''
        reladdr = self.subtract_load_addr(addr)
        elf_name = self.elf_for_addr(addr)
        if elf_name is None:
            return ''
        elf = self.get_elf(elf_name)
        cmd = self.arch_prefix('objdump')
        if not reladdr or not elf or not cmd:
            return ''
        iaddr = int(reladdr, 16)
        objdump = self.my_Popen([cmd, '--section-headers', elf])
        for line in iter(objdump.stdout.readline, ''):
            try:
                idx, name, size, vma, lma, offs, algn = line.split()
            except ValueError:
                continue
            ivma = int(vma, 16)
            isize = int(size, 16)
            if ivma == iaddr:
                ret = name
                break
            if ivma < iaddr and ivma + isize >= iaddr:
                offs = iaddr - ivma
                ret = name + '+' + str(offs)
                break
        objdump.terminate()
        return ret

    def process_abort(self, line):
        ret = ''
        match = re.search(ABORT_ADDR_RE, line)
        addr = match.group('addr')
        pre = match.start('addr')
        post = match.end('addr')
        sym = self.symbol_plus_offset(addr)
        sec = self.section_plus_offset(addr)
        if sym or sec:
            ret += line[:pre]
            ret += addr
            if sym:
                ret += ' ' + sym
            if sec:
                ret += ' ' + sec
            ret += line[post:]
        return ret

    # Return all ELF sections with the ALLOC flag
    def read_sections(self, elf_name):
        if elf_name is None:
            return
        if elf_name in self._sections:
            return
        elf = self.get_elf(elf_name)
        cmd = self.arch_prefix('objdump')
        if not elf or not cmd:
            return
        self._sections[elf_name] = []
        objdump = self.my_Popen([cmd, '--section-headers', elf])
        for line in iter(objdump.stdout.readline, ''):
            try:
                _, name, size, vma, _, _, _ = line.split()
            except ValueError:
                if 'ALLOC' in line:
                    self._sections[elf_name].append([name, int(vma, 16),
                                                     int(size, 16)])

    def overlaps(self, section, addr, size):
        sec_addr = section[1]
        sec_size = section[2]
        if not size or not sec_size:
            return False
        return ((addr <= (sec_addr + sec_size - 1)) and
                ((addr + size - 1) >= sec_addr))

    def sections_in_region(self, addr, size, elf_idx):
        ret = ''
        addr = self.subtract_load_addr(addr)
        if not addr:
            return ''
        iaddr = int(addr, 16)
        isize = int(size, 16)
        elf = self._elfs[int(elf_idx)][0]
        if elf is None:
            return ''
        self.read_sections(elf)
        if elf not in self._sections:
            return ''
        for s in self._sections[elf]:
            if self.overlaps(s, iaddr, isize):
                ret += ' ' + s[0]
        return ret

    def reset(self):
        self._call_stack_found = False
        if self._addr2line:
            self._addr2line.terminate()
            self._addr2line = None
        self._addr2line_elf_name = None
        self._arch = None
        self._saved_abort_line = ''
        self._sections = {}  # {elf_name: [[name, addr, size], ...], ...}
        self._regions = []   # [[addr, size, elf_idx, saved line], ...]
        self._elfs = {0: ["tee.elf", 0]}  # {idx: [uuid, load_addr], ...}

    def pretty_print_path(self, path):
        if self._strip_path:
            return re.sub(re.escape(self._strip_path) + '/*', '', path)
        return path

    def write(self, line):
        if self._call_stack_found:
            match = re.search(STACK_ADDR_RE, line)
            if match:
                addr = match.group('addr')
                pre = match.start('addr')
                post = match.end('addr')
                self._out.write(line[:pre])
                self._out.write(addr)
                res = self.resolve(addr)
                res = self.pretty_print_path(res)
                self._out.write(' ' + res)
                self._out.write(line[post:])
                return
            else:
                self.reset()
        match = re.search(REGION_RE, line)
        if match:
            # Region table: save info for later processing once
            # we know which UUID corresponds to which ELF index
            addr = match.group('addr')
            size = match.group('size')
            elf_idx = match.group('elf_idx')
            self._regions.append([addr, size, elf_idx, line])
            return
        match = re.search(ELF_LIST_RE, line)
        if match:
            # ELF list: save info for later. Region table and ELF list
            # will be displayed when the call stack is reached
            i = int(match.group('idx'))
            self._elfs[i] = [match.group('uuid'), match.group('load_addr'),
                             line]
            return
        match = re.search(CALL_STACK_RE, line)
        if match:
            self._call_stack_found = True
            if self._regions:
                for r in self._regions:
                    r_addr = r[0]
                    r_size = r[1]
                    elf_idx = r[2]
                    saved_line = r[3]
                    if elf_idx is None:
                        self._out.write(saved_line)
                    else:
                        self._out.write(saved_line.strip() +
                                        self.sections_in_region(r_addr,
                                                                r_size,
                                                                elf_idx) +
                                        '\n')
            if self._elfs:
                for k in self._elfs:
                    e = self._elfs[k]
                    if (len(e) >= 3):
                        # TA executable or library
                        self._out.write(e[2].strip())
                        elf = self.get_elf(e[0])
                        if elf:
                            rpath = os.path.realpath(elf)
                            path = self.pretty_print_path(rpath)
                            self._out.write(' (' + path + ')')
                        self._out.write('\n')
            # Here is a good place to resolve the abort address because we
            # have all the information we need
            if self._saved_abort_line:
                self._out.write(self.process_abort(self._saved_abort_line))
        match = re.search(ABORT_ADDR_RE, line)
        if match:
            self.reset()
            # At this point the arch and TA load address are unknown.
            # Save the line so We can translate the abort address later.
            self._saved_abort_line = line
        self._out.write(line)

    def flush(self):
        self._out.flush()


def main():
    args = get_args()
    if args.dir:
        # Flatten list in case -d is used several times *and* with multiple
        # arguments
        args.dirs = [item for sublist in args.dir for item in sublist]
    else:
        args.dirs = []
    symbolizer = Symbolizer(sys.stdout, args.dirs, args.strip_path)

    for line in sys.stdin:
        symbolizer.write(line)
    symbolizer.flush()


if __name__ == "__main__":
    main()
