diff options
Diffstat (limited to 'import-layers/yocto-poky/scripts/crosstap')
-rwxr-xr-x | import-layers/yocto-poky/scripts/crosstap | 469 |
1 files changed, 0 insertions, 469 deletions
diff --git a/import-layers/yocto-poky/scripts/crosstap b/import-layers/yocto-poky/scripts/crosstap deleted file mode 100755 index e33fa4ad4..000000000 --- a/import-layers/yocto-poky/scripts/crosstap +++ /dev/null @@ -1,469 +0,0 @@ -#!/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() |