#! /bin/bash
#
# Copyright (c) 2015-2019, Intel Corporation
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are met:
#
#  * Redistributions of source code must retain the above copyright notice,
#    this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above copyright notice,
#    this list of conditions and the following disclaimer in the documentation
#    and/or other materials provided with the distribution.
#  * Neither the name of Intel Corporation nor the names of its contributors
#    may be used to endorse or promote products derived from this software
#    without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.

set -e

prog=`basename $0`
master=""
kcore=""
sysroot=""

usage() {
    cat <<EOF
usage: $prog [<options>] <perf.data-file>

Create --pevent options for ptdump and ptxed based on <perf.data-file>
and previously generated <perf.data-file>-sideband*.pevent files.

When tracing ring-0, use perf-with-kcore and supply the path to kcore_dir
using the -k option.

options:
  -h         this text
  -m <file>  set <file> as the master sideband file (current: $master)
  -k <dir>   set the kcore directory to <dir> (current: $kcore)
  -s <dir>   set the sysroot directory to <dir> (current: $sysroot)

<perf.data-file> defaults to perf.data.
EOF
}

while getopts "hm:k:s:" opt; do
    case $opt in
        h)
            usage
            exit 0
            ;;
        m)
            master="$OPTARG"
            ;;
        k)
            kcore="$OPTARG"
            ;;
        s)
            sysroot="$OPTARG"
            ;;
    esac
done

shift $(($OPTIND-1))


if [[ $# == 0 ]]; then
    file="perf.data"
elif [[ $# == 1 ]]; then
    file="$1"
    shift
else
    usage
    exit 1
fi


perf script --header-only -i $file | \
  gawk -F'[ ,]' -- '
    /^# cpuid : /  {
      vendor   = $4
      family   = strtonum($5)
      model    = strtonum($6)
      stepping = strtonum($7)

      if (vendor == "GenuineIntel") {
        printf(" --cpu %d/%d/%d", family, model, stepping)
      }
  }
'

perf script --no-itrace -i $file -D | \
  grep -A18 -e PERF_RECORD_AUXTRACE_INFO | \
  gawk -F' ' -- '
  /^ *Time Shift/           { printf(" --pevent:time-shift %s", $NF) }
  /^ *Time Muliplier/       { printf(" --pevent:time-mult %s", $NF) }
  /^ *Time Multiplier/      { printf(" --pevent:time-mult %s", $NF) }
  /^ *Time Zero/            { printf(" --pevent:time-zero %s", $NF) }
  /^ *TSC:CTC numerator/    { printf(" --cpuid-0x15.ebx %s", $NF) }
  /^ *TSC:CTC denominator/  { printf(" --cpuid-0x15.eax %s", $NF) }
  /^ *Max non-turbo ratio/  { printf(" --nom-freq %s", $NF) }
'

gawk_sample_type() {
  echo $1 | gawk -- '
  BEGIN         { RS = "[|\n]" }
  /^TID$/        { config += 0x00002 }
  /^TIME$/       { config += 0x00004 }
  /^ID$/         { config += 0x00040 }
  /^CPU$/        { config += 0x00080 }
  /^STREAM$/     { config += 0x00200 }
  /^IDENTIFIER$/ { config += 0x10000 }
  END           {
    if (config != 0) {
      printf(" --pevent:sample-type 0x%x", config)
    }
  }
'
}

attr_sample_types=$(perf evlist -v -i $file |  gawk -F' ' -- '
  BEGIN { RS = "," }
  /sample_type/  { print $2 }
' | sort | uniq)

for attr in $attr_sample_types; do
    # We assume at most one attr with and at most one attr without CPU
    #
    if [[ $(echo $attr | grep -e CPU) ]]; then
        gawk_sample_type $attr
    else
        gawk_sample_type $attr
    fi
done

perf evlist -v -i $file | grep intel_pt | gawk -F' ' -- '
  BEGIN             { RS = "," }
  /config/ {
    config = strtonum($2)
    mtc_freq = and(rshift(config, 14), 0xf)

    printf(" --mtc-freq 0x%x", mtc_freq)
  }
'

if [[ -n "$sysroot" ]]; then
    echo -n " --pevent:sysroot $sysroot"

    if [[ -r "$sysroot/vdso/vdso-x64.so" ]]; then
        echo -n " --pevent:vdso-x64 $sysroot/vdso/vdso-x64.so"
    fi

    if [[ -r "$sysroot/vdso/vdso-x32.so" ]]; then
        echo -n " --pevent:vdso-x32 $sysroot/vdso/vdso-x32.so"
    fi

    if [[ -r "$sysroot/vdso/vdso-ia32.so" ]]; then
        echo -n " --pevent:vdso-ia32 $sysroot/vdso/vdso-ia32.so"
    fi
fi

if [[ -n "$kcore" ]]; then
    if [[ ! -d "$kcore" ]]; then
        echo "$prog: kcore_dir '$kcore' is not a directory."
        exit 1
    fi

    if [[ ! -r "$kcore/kcore" ]]; then
        echo "$prog: 'kcore' not found in '$kcore' or not readable."
        exit 1
    fi

    echo -n " --pevent:kcore $kcore/kcore"

    if [[ ! -r "$kcore/kallsyms" ]]; then
        echo "$prog: 'kallsyms' not found in '$kcore' or not readable."
        exit 1
    fi

    cat "$kcore/kallsyms" | \
        gawk -M -- '
            function update_kernel_start(vaddr) {
              if (vaddr < kernel_start) {
                kernel_start = vaddr
              }
            }

            BEGIN                   { kernel_start = 0xffffffffffffffff }
            /^[0-9a-f]+ T _text$/   { update_kernel_start(strtonum("0x" $1)) }
            /^[0-9a-f]+ T _stext$/  { update_kernel_start(strtonum("0x" $1)) }
            END {
              if (kernel_start < 0xffffffffffffffff) {
                printf(" --pevent:kernel-start 0x%x", kernel_start)
              }
            }
        '
fi

for sbfile in $(ls -1 "$(basename $file)"-sideband*.pevent 2>/dev/null); do
    if [[ -z "$master" || "$sbfile" == "$master" ]]; then
        echo -n " --pevent:primary $sbfile"
    else
        echo -n " --pevent:secondary $sbfile"
    fi
done
