18c2ecf20Sopenharmony_ci#!/bin/sh
28c2ecf20Sopenharmony_ci# SPDX-License-Identifier: GPL-2.0-only
38c2ecf20Sopenharmony_ci
48c2ecf20Sopenharmony_ciusage() {
58c2ecf20Sopenharmony_ci	echo "Dump boot-time tracing bootconfig from ftrace"
68c2ecf20Sopenharmony_ci	echo "Usage: $0 [--debug] [ > BOOTCONFIG-FILE]"
78c2ecf20Sopenharmony_ci	exit 1
88c2ecf20Sopenharmony_ci}
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ciDEBUG=
118c2ecf20Sopenharmony_ciwhile [ x"$1" != x ]; do
128c2ecf20Sopenharmony_ci	case "$1" in
138c2ecf20Sopenharmony_ci	"--debug")
148c2ecf20Sopenharmony_ci		DEBUG=$1;;
158c2ecf20Sopenharmony_ci	-*)
168c2ecf20Sopenharmony_ci		usage
178c2ecf20Sopenharmony_ci		;;
188c2ecf20Sopenharmony_ci	esac
198c2ecf20Sopenharmony_ci	shift 1
208c2ecf20Sopenharmony_cidone
218c2ecf20Sopenharmony_ci
228c2ecf20Sopenharmony_ciif [ x"$DEBUG" != x ]; then
238c2ecf20Sopenharmony_ci	set -x
248c2ecf20Sopenharmony_cifi
258c2ecf20Sopenharmony_ci
268c2ecf20Sopenharmony_ciTRACEFS=`grep -m 1 -w tracefs /proc/mounts | cut -f 2 -d " "`
278c2ecf20Sopenharmony_ciif [ -z "$TRACEFS" ]; then
288c2ecf20Sopenharmony_ci	if ! grep -wq debugfs /proc/mounts; then
298c2ecf20Sopenharmony_ci		echo "Error: No tracefs/debugfs was mounted."
308c2ecf20Sopenharmony_ci		exit 1
318c2ecf20Sopenharmony_ci	fi
328c2ecf20Sopenharmony_ci	TRACEFS=`grep -m 1 -w debugfs /proc/mounts | cut -f 2 -d " "`/tracing
338c2ecf20Sopenharmony_ci	if [ ! -d $TRACEFS ]; then
348c2ecf20Sopenharmony_ci		echo "Error: ftrace is not enabled on this kernel." 1>&2
358c2ecf20Sopenharmony_ci		exit 1
368c2ecf20Sopenharmony_ci	fi
378c2ecf20Sopenharmony_cifi
388c2ecf20Sopenharmony_ci
398c2ecf20Sopenharmony_ci######## main #########
408c2ecf20Sopenharmony_ci
418c2ecf20Sopenharmony_ciset -e
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ciemit_kv() { # key =|+= value
448c2ecf20Sopenharmony_ci	echo "$@"
458c2ecf20Sopenharmony_ci}
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ciglobal_options() {
488c2ecf20Sopenharmony_ci	val=`cat $TRACEFS/max_graph_depth`
498c2ecf20Sopenharmony_ci	[ $val != 0 ] && emit_kv kernel.fgraph_max_depth = $val
508c2ecf20Sopenharmony_ci	if grep -qv "^#" $TRACEFS/set_graph_function $TRACEFS/set_graph_notrace ; then
518c2ecf20Sopenharmony_ci		cat 1>&2 << EOF
528c2ecf20Sopenharmony_ci# WARN: kernel.fgraph_filters and kernel.fgraph_notrace are not supported, since the wild card expression was expanded and lost from memory.
538c2ecf20Sopenharmony_ciEOF
548c2ecf20Sopenharmony_ci	fi
558c2ecf20Sopenharmony_ci}
568c2ecf20Sopenharmony_ci
578c2ecf20Sopenharmony_cikprobe_event_options() {
588c2ecf20Sopenharmony_ci	cat $TRACEFS/kprobe_events | while read p args; do
598c2ecf20Sopenharmony_ci		case $p in
608c2ecf20Sopenharmony_ci		r*)
618c2ecf20Sopenharmony_ci		cat 1>&2 << EOF
628c2ecf20Sopenharmony_ci# WARN: A return probe found but it is not supported by bootconfig. Skip it.
638c2ecf20Sopenharmony_ciEOF
648c2ecf20Sopenharmony_ci		continue;;
658c2ecf20Sopenharmony_ci		esac
668c2ecf20Sopenharmony_ci		p=${p#*:}
678c2ecf20Sopenharmony_ci		event=${p#*/}
688c2ecf20Sopenharmony_ci		group=${p%/*}
698c2ecf20Sopenharmony_ci		if [ $group != "kprobes" ]; then
708c2ecf20Sopenharmony_ci			cat 1>&2 << EOF
718c2ecf20Sopenharmony_ci# WARN: kprobes group name $group is changed to "kprobes" for bootconfig.
728c2ecf20Sopenharmony_ciEOF
738c2ecf20Sopenharmony_ci		fi
748c2ecf20Sopenharmony_ci		emit_kv $PREFIX.event.kprobes.$event.probes += $args
758c2ecf20Sopenharmony_ci	done
768c2ecf20Sopenharmony_ci}
778c2ecf20Sopenharmony_ci
788c2ecf20Sopenharmony_cisynth_event_options() {
798c2ecf20Sopenharmony_ci	cat $TRACEFS/synthetic_events | while read event fields; do
808c2ecf20Sopenharmony_ci		emit_kv $PREFIX.event.synthetic.$event.fields = `echo $fields | sed "s/;/,/g"`
818c2ecf20Sopenharmony_ci	done
828c2ecf20Sopenharmony_ci}
838c2ecf20Sopenharmony_ci
848c2ecf20Sopenharmony_ci# Variables resolver
858c2ecf20Sopenharmony_ciDEFINED_VARS=
868c2ecf20Sopenharmony_ciUNRESOLVED_EVENTS=
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_cidefined_vars() { # event-dir
898c2ecf20Sopenharmony_ci	grep "^hist" $1/trigger | grep -o ':[a-zA-Z0-9]*='
908c2ecf20Sopenharmony_ci}
918c2ecf20Sopenharmony_cireferred_vars() {
928c2ecf20Sopenharmony_ci	grep "^hist" $1/trigger | grep -o '$[a-zA-Z0-9]*'
938c2ecf20Sopenharmony_ci}
948c2ecf20Sopenharmony_ci
958c2ecf20Sopenharmony_ciper_event_options() { # event-dir
968c2ecf20Sopenharmony_ci	evdir=$1
978c2ecf20Sopenharmony_ci	# Check the special event which has no filter and no trigger
988c2ecf20Sopenharmony_ci	[ ! -f $evdir/filter ] && return
998c2ecf20Sopenharmony_ci
1008c2ecf20Sopenharmony_ci	if grep -q "^hist:" $evdir/trigger; then
1018c2ecf20Sopenharmony_ci		# hist action can refer the undefined variables
1028c2ecf20Sopenharmony_ci		__vars=`defined_vars $evdir`
1038c2ecf20Sopenharmony_ci		for v in `referred_vars $evdir`; do
1048c2ecf20Sopenharmony_ci			if echo $DEFINED_VARS $__vars | grep -vqw ${v#$}; then
1058c2ecf20Sopenharmony_ci				# $v is not defined yet, defer it
1068c2ecf20Sopenharmony_ci				UNRESOLVED_EVENTS="$UNRESOLVED_EVENTS $evdir"
1078c2ecf20Sopenharmony_ci				return;
1088c2ecf20Sopenharmony_ci			fi
1098c2ecf20Sopenharmony_ci		done
1108c2ecf20Sopenharmony_ci		DEFINED_VARS="$DEFINED_VARS "`defined_vars $evdir`
1118c2ecf20Sopenharmony_ci	fi
1128c2ecf20Sopenharmony_ci	grep -v "^#" $evdir/trigger | while read action active; do
1138c2ecf20Sopenharmony_ci		emit_kv $PREFIX.event.$group.$event.actions += \'$action\'
1148c2ecf20Sopenharmony_ci	done
1158c2ecf20Sopenharmony_ci
1168c2ecf20Sopenharmony_ci	# enable is not checked; this is done by set_event in the instance.
1178c2ecf20Sopenharmony_ci	val=`cat $evdir/filter`
1188c2ecf20Sopenharmony_ci	if [ "$val" != "none" ]; then
1198c2ecf20Sopenharmony_ci		emit_kv $PREFIX.event.$group.$event.filter = "$val"
1208c2ecf20Sopenharmony_ci	fi
1218c2ecf20Sopenharmony_ci}
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ciretry_unresolved() {
1248c2ecf20Sopenharmony_ci	unresolved=$UNRESOLVED_EVENTS
1258c2ecf20Sopenharmony_ci	UNRESOLVED_EVENTS=
1268c2ecf20Sopenharmony_ci	for evdir in $unresolved; do
1278c2ecf20Sopenharmony_ci		event=${evdir##*/}
1288c2ecf20Sopenharmony_ci		group=${evdir%/*}; group=${group##*/}
1298c2ecf20Sopenharmony_ci		per_event_options $evdir
1308c2ecf20Sopenharmony_ci	done
1318c2ecf20Sopenharmony_ci}
1328c2ecf20Sopenharmony_ci
1338c2ecf20Sopenharmony_cievent_options() {
1348c2ecf20Sopenharmony_ci	# PREFIX and INSTANCE must be set
1358c2ecf20Sopenharmony_ci	if [ $PREFIX = "ftrace" ]; then
1368c2ecf20Sopenharmony_ci		# define the dynamic events
1378c2ecf20Sopenharmony_ci		kprobe_event_options
1388c2ecf20Sopenharmony_ci		synth_event_options
1398c2ecf20Sopenharmony_ci	fi
1408c2ecf20Sopenharmony_ci	for group in `ls $INSTANCE/events/` ; do
1418c2ecf20Sopenharmony_ci		[ ! -d $INSTANCE/events/$group ] && continue
1428c2ecf20Sopenharmony_ci		for event in `ls $INSTANCE/events/$group/` ;do
1438c2ecf20Sopenharmony_ci			[ ! -d $INSTANCE/events/$group/$event ] && continue
1448c2ecf20Sopenharmony_ci			per_event_options $INSTANCE/events/$group/$event
1458c2ecf20Sopenharmony_ci		done
1468c2ecf20Sopenharmony_ci	done
1478c2ecf20Sopenharmony_ci	retry=0
1488c2ecf20Sopenharmony_ci	while [ $retry -lt 3 ]; do
1498c2ecf20Sopenharmony_ci		retry_unresolved
1508c2ecf20Sopenharmony_ci		retry=$((retry + 1))
1518c2ecf20Sopenharmony_ci	done
1528c2ecf20Sopenharmony_ci	if [ "$UNRESOLVED_EVENTS" ]; then
1538c2ecf20Sopenharmony_ci		cat 1>&2 << EOF
1548c2ecf20Sopenharmony_ci! ERROR: hist triggers in $UNRESOLVED_EVENTS use some undefined variables.
1558c2ecf20Sopenharmony_ciEOF
1568c2ecf20Sopenharmony_ci	fi
1578c2ecf20Sopenharmony_ci}
1588c2ecf20Sopenharmony_ci
1598c2ecf20Sopenharmony_ciis_default_trace_option() { # option
1608c2ecf20Sopenharmony_cigrep -qw $1 << EOF
1618c2ecf20Sopenharmony_ciprint-parent
1628c2ecf20Sopenharmony_cinosym-offset
1638c2ecf20Sopenharmony_cinosym-addr
1648c2ecf20Sopenharmony_cinoverbose
1658c2ecf20Sopenharmony_cinoraw
1668c2ecf20Sopenharmony_cinohex
1678c2ecf20Sopenharmony_cinobin
1688c2ecf20Sopenharmony_cinoblock
1698c2ecf20Sopenharmony_citrace_printk
1708c2ecf20Sopenharmony_ciannotate
1718c2ecf20Sopenharmony_cinouserstacktrace
1728c2ecf20Sopenharmony_cinosym-userobj
1738c2ecf20Sopenharmony_cinoprintk-msg-only
1748c2ecf20Sopenharmony_cicontext-info
1758c2ecf20Sopenharmony_cinolatency-format
1768c2ecf20Sopenharmony_cirecord-cmd
1778c2ecf20Sopenharmony_cinorecord-tgid
1788c2ecf20Sopenharmony_cioverwrite
1798c2ecf20Sopenharmony_cinodisable_on_free
1808c2ecf20Sopenharmony_ciirq-info
1818c2ecf20Sopenharmony_cimarkers
1828c2ecf20Sopenharmony_cinoevent-fork
1838c2ecf20Sopenharmony_cinopause-on-trace
1848c2ecf20Sopenharmony_cifunction-trace
1858c2ecf20Sopenharmony_cinofunction-fork
1868c2ecf20Sopenharmony_cinodisplay-graph
1878c2ecf20Sopenharmony_cinostacktrace
1888c2ecf20Sopenharmony_cinotest_nop_accept
1898c2ecf20Sopenharmony_cinotest_nop_refuse
1908c2ecf20Sopenharmony_ciEOF
1918c2ecf20Sopenharmony_ci}
1928c2ecf20Sopenharmony_ci
1938c2ecf20Sopenharmony_ciinstance_options() { # [instance-name]
1948c2ecf20Sopenharmony_ci	if [ $# -eq 0 ]; then
1958c2ecf20Sopenharmony_ci		PREFIX="ftrace"
1968c2ecf20Sopenharmony_ci		INSTANCE=$TRACEFS
1978c2ecf20Sopenharmony_ci	else
1988c2ecf20Sopenharmony_ci		PREFIX="ftrace.instance.$1"
1998c2ecf20Sopenharmony_ci		INSTANCE=$TRACEFS/instances/$1
2008c2ecf20Sopenharmony_ci	fi
2018c2ecf20Sopenharmony_ci	val=
2028c2ecf20Sopenharmony_ci	for i in `cat $INSTANCE/trace_options`; do
2038c2ecf20Sopenharmony_ci		is_default_trace_option $i && continue
2048c2ecf20Sopenharmony_ci		val="$val, $i"
2058c2ecf20Sopenharmony_ci	done
2068c2ecf20Sopenharmony_ci	[ "$val" ] && emit_kv $PREFIX.options = "${val#,}"
2078c2ecf20Sopenharmony_ci	val="local"
2088c2ecf20Sopenharmony_ci	for i in `cat $INSTANCE/trace_clock` ; do
2098c2ecf20Sopenharmony_ci		[ "${i#*]}" ] && continue
2108c2ecf20Sopenharmony_ci		i=${i%]}; val=${i#[}
2118c2ecf20Sopenharmony_ci	done
2128c2ecf20Sopenharmony_ci	[ $val != "local" ] && emit_kv $PREFIX.trace_clock = $val
2138c2ecf20Sopenharmony_ci	val=`cat $INSTANCE/buffer_size_kb`
2148c2ecf20Sopenharmony_ci	if echo $val | grep -vq "expanded" ; then
2158c2ecf20Sopenharmony_ci		emit_kv $PREFIX.buffer_size = $val"KB"
2168c2ecf20Sopenharmony_ci	fi
2178c2ecf20Sopenharmony_ci	if grep -q "is allocated" $INSTANCE/snapshot ; then
2188c2ecf20Sopenharmony_ci		emit_kv $PREFIX.alloc_snapshot
2198c2ecf20Sopenharmony_ci	fi
2208c2ecf20Sopenharmony_ci	val=`cat $INSTANCE/tracing_cpumask`
2218c2ecf20Sopenharmony_ci	if [ `echo $val | sed -e s/f//g`x != x ]; then
2228c2ecf20Sopenharmony_ci		emit_kv $PREFIX.cpumask = $val
2238c2ecf20Sopenharmony_ci	fi
2248c2ecf20Sopenharmony_ci	val=`cat $INSTANCE/tracing_on`
2258c2ecf20Sopenharmony_ci	if [ "$val" = "0" ]; then
2268c2ecf20Sopenharmony_ci		emit_kv $PREFIX.tracing_on = 0
2278c2ecf20Sopenharmony_ci	fi
2288c2ecf20Sopenharmony_ci
2298c2ecf20Sopenharmony_ci	val=
2308c2ecf20Sopenharmony_ci	for i in `cat $INSTANCE/set_event`; do
2318c2ecf20Sopenharmony_ci		val="$val, $i"
2328c2ecf20Sopenharmony_ci	done
2338c2ecf20Sopenharmony_ci	[ "$val" ] && emit_kv $PREFIX.events = "${val#,}"
2348c2ecf20Sopenharmony_ci	val=`cat $INSTANCE/current_tracer`
2358c2ecf20Sopenharmony_ci	[ $val != nop ] && emit_kv $PREFIX.tracer = $val
2368c2ecf20Sopenharmony_ci	if grep -qv "^#" $INSTANCE/set_ftrace_filter $INSTANCE/set_ftrace_notrace; then
2378c2ecf20Sopenharmony_ci		cat 1>&2 << EOF
2388c2ecf20Sopenharmony_ci# WARN: kernel.ftrace.filters and kernel.ftrace.notrace are not supported, since the wild card expression was expanded and lost from memory.
2398c2ecf20Sopenharmony_ciEOF
2408c2ecf20Sopenharmony_ci	fi
2418c2ecf20Sopenharmony_ci	event_options
2428c2ecf20Sopenharmony_ci}
2438c2ecf20Sopenharmony_ci
2448c2ecf20Sopenharmony_ciglobal_options
2458c2ecf20Sopenharmony_ciinstance_options
2468c2ecf20Sopenharmony_cifor i in `ls $TRACEFS/instances` ; do
2478c2ecf20Sopenharmony_ci	instance_options $i
2488c2ecf20Sopenharmony_cidone
249