#!/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.
# All rights reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 2 as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
# See the GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

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 depreciated:
  %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()
