#!/usr/bin/env python3
#
# Build a systemtap script for a given image, kernel
#
# Effectively script extracts needed information from set of
# 'bitbake -e' commands and contructs proper invocation of stap on
# host to build systemtap script for a given target.
#
# By default script will compile scriptname.ko that could be copied
# to taget and activated with 'staprun scriptname.ko' command. Or if
# --remote user@hostname option is specified script will build, load
# execute script on target.
#
# This script is very similar and inspired by crosstap shell script.
# The major difference that this script supports user-land related
# systemtap script, whereas crosstap could deal only with scripts
# related to kernel.
#
# Copyright (c) 2018, Cisco Systems.
#
# SPDX-License-Identifier: GPL-2.0-only
#

import sys
import re
import subprocess
import os
import optparse

class Stap(object):
    def __init__(self, script, module, remote):
        self.script = script
        self.module = module
        self.remote = remote
        self.stap = None
        self.sysroot = None
        self.runtime = None
        self.tapset = None
        self.arch = None
        self.cross_compile = None
        self.kernel_release = None
        self.target_path = None
        self.target_ld_library_path = None

        if not self.remote:
            if not self.module:
                # derive module name from script
                self.module = os.path.basename(self.script)
                if self.module[-4:] == ".stp":
                    self.module = self.module[:-4]
                    # replace - if any with _
                    self.module = self.module.replace("-", "_")

    def command(self, args):
        ret = []
        ret.append(self.stap)

        if self.remote:
            ret.append("--remote")
            ret.append(self.remote)
        else:
            ret.append("-p4")
            ret.append("-m")
            ret.append(self.module)

        ret.append("-a")
        ret.append(self.arch)

        ret.append("-B")
        ret.append("CROSS_COMPILE=" + self.cross_compile)

        ret.append("-r")
        ret.append(self.kernel_release)

        ret.append("-I")
        ret.append(self.tapset)

        ret.append("-R")
        ret.append(self.runtime)

        if self.sysroot:
            ret.append("--sysroot")
            ret.append(self.sysroot)

            ret.append("--sysenv=PATH=" + self.target_path)
            ret.append("--sysenv=LD_LIBRARY_PATH=" + self.target_ld_library_path)

        ret = ret + args

        ret.append(self.script)
        return ret

    def additional_environment(self):
        ret = {}
        ret["SYSTEMTAP_DEBUGINFO_PATH"] = "+:.debug:build"
        return ret

    def environment(self):
        ret = os.environ.copy()
        additional = self.additional_environment()
        for e in additional:
            ret[e] = additional[e]
        return ret

    def display_command(self, args):
        additional_env = self.additional_environment()
        command = self.command(args)

        print("#!/bin/sh")
        for e in additional_env:
            print("export %s=\"%s\"" % (e, additional_env[e]))
        print(" ".join(command))

class BitbakeEnvInvocationException(Exception):
    def __init__(self, message):
        self.message = message

class BitbakeEnv(object):
    BITBAKE="bitbake"

    def __init__(self, package):
        self.package = package
        self.cmd = BitbakeEnv.BITBAKE + " -e " + self.package
        self.popen = subprocess.Popen(self.cmd, shell=True,
                                      stdout=subprocess.PIPE,
                                      stderr=subprocess.STDOUT)
        self.__lines = self.popen.stdout.readlines()
        self.popen.wait()

        self.lines = []
        for line in self.__lines:
                self.lines.append(line.decode('utf-8'))

    def get_vars(self, vars):
        if self.popen.returncode:
            raise BitbakeEnvInvocationException(
                "\nFailed to execute '" + self.cmd +
                "' with the following message:\n" +
                ''.join(self.lines))

        search_patterns = []
        retdict = {}
        for var in vars:
            # regular not exported variable
            rexpr = "^" + var + "=\"(.*)\""
            re_compiled = re.compile(rexpr)
            search_patterns.append((var, re_compiled))

            # exported variable
            rexpr = "^export " + var + "=\"(.*)\""
            re_compiled = re.compile(rexpr)
            search_patterns.append((var, re_compiled))

            for line in self.lines:
                for var, rexpr in search_patterns:
                    m = rexpr.match(line)
                    if m:
                        value = m.group(1)
                        retdict[var] = value

        # fill variables values in order how they were requested
        ret = []
        for var in vars:
            ret.append(retdict.get(var))

        # if it is single value list return it as scalar, not the list
        if len(ret) == 1:
            ret = ret[0]

        return ret

class ParamDiscovery(object):
    SYMBOLS_CHECK_MESSAGE = """
WARNING: image '%s' does not have dbg-pkgs IMAGE_FEATURES enabled and no
"image-combined-dbg" in inherited classes is specified. As result the image
does not have symbols for user-land processes DWARF based probes. Consider
adding 'dbg-pkgs' to EXTRA_IMAGE_FEATURES or adding "image-combined-dbg" to
USER_CLASSES. I.e add this line 'USER_CLASSES += "image-combined-dbg"' to
local.conf file.

Or you may use IMAGE_GEN_DEBUGFS="1" option, and then after build you need
recombine/unpack image and image-dbg tarballs and pass resulting dir location
with --sysroot option.
"""

    def __init__(self, image):
        self.image = image

        self.image_rootfs = None
        self.image_features = None
        self.image_gen_debugfs = None
        self.inherit = None
        self.base_bindir = None
        self.base_sbindir = None
        self.base_libdir = None
        self.bindir = None
        self.sbindir = None
        self.libdir = None

        self.staging_bindir_toolchain = None
        self.target_prefix = None
        self.target_arch = None
        self.target_kernel_builddir = None

        self.staging_dir_native = None

        self.image_combined_dbg = False

    def discover(self):
        if self.image:
            benv_image = BitbakeEnv(self.image)
            (self.image_rootfs,
             self.image_features,
             self.image_gen_debugfs,
             self.inherit,
             self.base_bindir,
             self.base_sbindir,
             self.base_libdir,
             self.bindir,
             self.sbindir,
             self.libdir
            ) = benv_image.get_vars(
                 ("IMAGE_ROOTFS",
                  "IMAGE_FEATURES",
                  "IMAGE_GEN_DEBUGFS",
                  "INHERIT",
                  "base_bindir",
                  "base_sbindir",
                  "base_libdir",
                  "bindir",
                  "sbindir",
                  "libdir"
                  ))

        benv_kernel = BitbakeEnv("virtual/kernel")
        (self.staging_bindir_toolchain,
         self.target_prefix,
         self.target_arch,
         self.target_kernel_builddir
        ) = benv_kernel.get_vars(
             ("STAGING_BINDIR_TOOLCHAIN",
              "TARGET_PREFIX",
              "TRANSLATED_TARGET_ARCH",
              "B"
            ))

        benv_systemtap = BitbakeEnv("systemtap-native")
        (self.staging_dir_native
        ) = benv_systemtap.get_vars(["STAGING_DIR_NATIVE"])

        if self.inherit:
            if "image-combined-dbg" in self.inherit.split():
                self.image_combined_dbg = True

    def check(self, sysroot_option):
        ret = True
        if self.image_rootfs:
            sysroot = self.image_rootfs
            if not os.path.isdir(self.image_rootfs):
                print("ERROR: Cannot find '" + sysroot +
                      "' directory. Was '" + self.image + "' image built?")
                ret = False

        stap = self.staging_dir_native + "/usr/bin/stap"
        if not os.path.isfile(stap):
            print("ERROR: Cannot find '" + stap +
                  "'. Was 'systemtap-native' built?")
            ret = False

        if not os.path.isdir(self.target_kernel_builddir):
            print("ERROR: Cannot find '" + self.target_kernel_builddir +
                  "' directory. Was 'kernel/virtual' built?")
            ret = False

        if not sysroot_option and self.image_rootfs:
            dbg_pkgs_found = False

            if self.image_features:
                image_features = self.image_features.split()
                if "dbg-pkgs" in image_features:
                    dbg_pkgs_found = True

            if not dbg_pkgs_found \
               and not self.image_combined_dbg:
                print(ParamDiscovery.SYMBOLS_CHECK_MESSAGE % (self.image))

        if not ret:
            print("")

        return ret

    def __map_systemtap_arch(self):
        a = self.target_arch
        ret = a
        if   re.match('(athlon|x86.64)$', a):
            ret = 'x86_64'
        elif re.match('i.86$', a):
            ret = 'i386'
        elif re.match('arm$', a):
            ret = 'arm'
        elif re.match('aarch64$', a):
            ret = 'arm64'
        elif re.match('mips(isa|)(32|64|)(r6|)(el|)$', a):
            ret = 'mips'
        elif re.match('p(pc|owerpc)(|64)', a):
            ret = 'powerpc'
        return ret

    def fill_stap(self, stap):
        stap.stap = self.staging_dir_native + "/usr/bin/stap"
        if not stap.sysroot:
            if self.image_rootfs:
                if self.image_combined_dbg:
                    stap.sysroot = self.image_rootfs + "-dbg"
                else:
                    stap.sysroot = self.image_rootfs
        stap.runtime = self.staging_dir_native + "/usr/share/systemtap/runtime"
        stap.tapset = self.staging_dir_native + "/usr/share/systemtap/tapset"
        stap.arch = self.__map_systemtap_arch()
        stap.cross_compile = self.staging_bindir_toolchain + "/" + \
                             self.target_prefix
        stap.kernel_release = self.target_kernel_builddir

        # do we have standard that tells in which order these need to appear
        target_path = []
        if self.sbindir:
            target_path.append(self.sbindir)
        if self.bindir:
            target_path.append(self.bindir)
        if self.base_sbindir:
            target_path.append(self.base_sbindir)
        if self.base_bindir:
            target_path.append(self.base_bindir)
        stap.target_path = ":".join(target_path)

        target_ld_library_path = []
        if self.libdir:
            target_ld_library_path.append(self.libdir)
        if self.base_libdir:
            target_ld_library_path.append(self.base_libdir)
        stap.target_ld_library_path = ":".join(target_ld_library_path)


def main():
    usage = """usage: %prog -s <systemtap-script> [options] [-- [systemtap options]]

%prog cross compile given SystemTap script against given image, kernel

It needs to run in environtment set for bitbake - it uses bitbake -e
invocations to retrieve information to construct proper stap cross build
invocation arguments. It assumes that systemtap-native is built in given
bitbake workspace.

Anything after -- option is passed directly to stap.

Legacy script invocation style supported but deprecated:
  %prog <user@hostname> <sytemtap-script> [systemtap options]

To enable most out of systemtap the following site.conf or local.conf
configuration is recommended:

# enables symbol + target binaries rootfs-dbg in workspace
IMAGE_GEN_DEBUGFS = "1"
IMAGE_FSTYPES_DEBUGFS = "tar.bz2"
USER_CLASSES += "image-combined-dbg"

# enables kernel debug symbols
KERNEL_EXTRA_FEATURES:append = " features/debug/debug-kernel.scc"

# minimal, just run-time systemtap configuration in target image
PACKAGECONFIG:pn-systemtap = "monitor"

# add systemtap run-time into target image if it is not there yet
IMAGE_INSTALL:append = " systemtap"
"""
    option_parser = optparse.OptionParser(usage=usage)

    option_parser.add_option("-s", "--script", dest="script",
                             help="specify input script FILE name",
                             metavar="FILE")

    option_parser.add_option("-i", "--image", dest="image",
                             help="specify image name for which script should be compiled")

    option_parser.add_option("-r", "--remote", dest="remote",
                             help="specify username@hostname of remote target to run script "
                             "optional, it assumes that remote target can be accessed through ssh")

    option_parser.add_option("-m", "--module", dest="module",
                             help="specify module name, optional, has effect only if --remote is not used, "
                             "if not specified module name will be derived from passed script name")

    option_parser.add_option("-y", "--sysroot", dest="sysroot",
                             help="explicitely specify image sysroot location. May need to use it in case "
                             "when IMAGE_GEN_DEBUGFS=\"1\" option is used and recombined with symbols "
                             "in different location",
                             metavar="DIR")

    option_parser.add_option("-o", "--out", dest="out",
                             action="store_true",
                             help="output shell script that equvivalent invocation of this script with "
                             "given set of arguments, in given bitbake environment. It could be stored in "
                             "separate shell script and could be repeated without incuring bitbake -e "
                             "invocation overhead",
                             default=False)

    option_parser.add_option("-d", "--debug", dest="debug",
                             action="store_true",
                             help="enable debug output. Use this option to see resulting stap invocation",
                             default=False)

    # is invocation follow syntax from orignal crosstap shell script
    legacy_args = False

    # check if we called the legacy way
    if len(sys.argv) >= 3:
        if sys.argv[1].find("@") != -1 and os.path.exists(sys.argv[2]):
            legacy_args = True

            # fill options values for legacy invocation case
            options = optparse.Values
            options.script = sys.argv[2]
            options.remote = sys.argv[1]
            options.image = None
            options.module = None
            options.sysroot = None
            options.out = None
            options.debug = None
            remaining_args = sys.argv[3:]

    if not legacy_args:
        (options, remaining_args) = option_parser.parse_args()

    if not options.script or not os.path.exists(options.script):
        print("'-s FILE' option is missing\n")
        option_parser.print_help()
    else:
        stap = Stap(options.script, options.module, options.remote)
        discovery = ParamDiscovery(options.image)
        discovery.discover()
        if not discovery.check(options.sysroot):
            option_parser.print_help()
        else:
            stap.sysroot = options.sysroot
            discovery.fill_stap(stap)

            if options.out:
                stap.display_command(remaining_args)
            else:
                cmd = stap.command(remaining_args)
                env = stap.environment()

                if options.debug:
                    print(" ".join(cmd))

                os.execve(cmd[0], cmd, env)

main()
