#! /bin/bash
#
# Copyright (c) 2015-2018, 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 " --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
