2010-05-22 18:52:39 +02:00
|
|
|
#!/bin/sh
|
|
|
|
#
|
|
|
|
# Code generator for trace events
|
|
|
|
#
|
|
|
|
# Copyright IBM, Corp. 2010
|
|
|
|
#
|
|
|
|
# This work is licensed under the terms of the GNU GPL, version 2. See
|
|
|
|
# the COPYING file in the top-level directory.
|
|
|
|
|
|
|
|
# Disable pathname expansion, makes processing text with '*' characters simpler
|
|
|
|
set -f
|
|
|
|
|
|
|
|
usage()
|
|
|
|
{
|
|
|
|
cat >&2 <<EOF
|
2010-05-22 20:24:51 +02:00
|
|
|
usage: $0 [--nop | --simple] [-h | -c]
|
2010-05-22 18:52:39 +02:00
|
|
|
Generate tracing code for a file on stdin.
|
|
|
|
|
|
|
|
Backends:
|
2010-05-22 20:24:51 +02:00
|
|
|
--nop Tracing disabled
|
|
|
|
--simple Simple built-in backend
|
2010-05-22 18:52:39 +02:00
|
|
|
|
|
|
|
Output formats:
|
|
|
|
-h Generate .h file
|
|
|
|
-c Generate .c file
|
|
|
|
EOF
|
|
|
|
exit 1
|
|
|
|
}
|
|
|
|
|
|
|
|
# Get the name of a trace event
|
|
|
|
get_name()
|
|
|
|
{
|
|
|
|
echo ${1%%\(*}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Get the argument list of a trace event, including types and names
|
|
|
|
get_args()
|
|
|
|
{
|
|
|
|
local args
|
|
|
|
args=${1#*\(}
|
|
|
|
args=${args%)*}
|
|
|
|
echo "$args"
|
|
|
|
}
|
|
|
|
|
|
|
|
# Get the argument name list of a trace event
|
|
|
|
get_argnames()
|
|
|
|
{
|
|
|
|
local nfields field name
|
|
|
|
nfields=0
|
|
|
|
for field in $(get_args "$1"); do
|
|
|
|
nfields=$((nfields + 1))
|
|
|
|
|
|
|
|
# Drop pointer star
|
|
|
|
field=${field#\*}
|
|
|
|
|
|
|
|
# Only argument names have commas at the end
|
|
|
|
name=${field%,}
|
|
|
|
test "$field" = "$name" && continue
|
|
|
|
|
|
|
|
printf "%s" "$name, "
|
|
|
|
done
|
|
|
|
|
|
|
|
# Last argument name
|
|
|
|
if [ "$nfields" -gt 1 ]
|
|
|
|
then
|
|
|
|
printf "%s" "$name"
|
|
|
|
fi
|
|
|
|
}
|
|
|
|
|
2010-05-22 20:24:51 +02:00
|
|
|
# Get the number of arguments to a trace event
|
|
|
|
get_argc()
|
|
|
|
{
|
|
|
|
local name argc
|
|
|
|
argc=0
|
|
|
|
for name in $(get_argnames "$1"); do
|
|
|
|
argc=$((argc + 1))
|
|
|
|
done
|
|
|
|
echo $argc
|
|
|
|
}
|
|
|
|
|
2010-05-22 18:52:39 +02:00
|
|
|
# Get the format string for a trace event
|
|
|
|
get_fmt()
|
|
|
|
{
|
|
|
|
local fmt
|
|
|
|
fmt=${1#*\"}
|
|
|
|
fmt=${fmt%\"*}
|
|
|
|
echo "$fmt"
|
|
|
|
}
|
|
|
|
|
|
|
|
linetoh_begin_nop()
|
|
|
|
{
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
linetoh_nop()
|
|
|
|
{
|
|
|
|
local name args
|
|
|
|
name=$(get_name "$1")
|
|
|
|
args=$(get_args "$1")
|
|
|
|
|
|
|
|
# Define an empty function for the trace event
|
|
|
|
cat <<EOF
|
|
|
|
static inline void trace_$name($args)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
EOF
|
|
|
|
}
|
|
|
|
|
|
|
|
linetoh_end_nop()
|
|
|
|
{
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
linetoc_begin_nop()
|
|
|
|
{
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
linetoc_nop()
|
|
|
|
{
|
|
|
|
# No need for function definitions in nop backend
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
|
|
|
linetoc_end_nop()
|
|
|
|
{
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2010-05-22 20:24:51 +02:00
|
|
|
linetoh_begin_simple()
|
|
|
|
{
|
|
|
|
cat <<EOF
|
|
|
|
#include "simpletrace.h"
|
|
|
|
EOF
|
|
|
|
|
|
|
|
simple_event_num=0
|
|
|
|
}
|
|
|
|
|
|
|
|
cast_args_to_uint64_t()
|
|
|
|
{
|
|
|
|
local arg
|
|
|
|
for arg in $(get_argnames "$1"); do
|
|
|
|
printf "%s" "(uint64_t)(uintptr_t)$arg"
|
|
|
|
done
|
|
|
|
}
|
|
|
|
|
|
|
|
linetoh_simple()
|
|
|
|
{
|
|
|
|
local name args argc trace_args
|
|
|
|
name=$(get_name "$1")
|
|
|
|
args=$(get_args "$1")
|
|
|
|
argc=$(get_argc "$1")
|
|
|
|
|
|
|
|
trace_args="$simple_event_num"
|
|
|
|
if [ "$argc" -gt 0 ]
|
|
|
|
then
|
|
|
|
trace_args="$trace_args, $(cast_args_to_uint64_t "$1")"
|
|
|
|
fi
|
|
|
|
|
|
|
|
cat <<EOF
|
|
|
|
static inline void trace_$name($args)
|
|
|
|
{
|
|
|
|
trace$argc($trace_args);
|
|
|
|
}
|
|
|
|
EOF
|
|
|
|
|
|
|
|
simple_event_num=$((simple_event_num + 1))
|
|
|
|
}
|
|
|
|
|
|
|
|
linetoh_end_simple()
|
|
|
|
{
|
2010-06-24 13:34:53 +02:00
|
|
|
cat <<EOF
|
|
|
|
#define NR_TRACE_EVENTS $simple_event_num
|
|
|
|
extern TraceEvent trace_list[NR_TRACE_EVENTS];
|
|
|
|
EOF
|
2010-05-22 20:24:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
linetoc_begin_simple()
|
|
|
|
{
|
2010-06-24 13:34:53 +02:00
|
|
|
cat <<EOF
|
|
|
|
#include "trace.h"
|
|
|
|
|
|
|
|
TraceEvent trace_list[] = {
|
|
|
|
EOF
|
|
|
|
simple_event_num=0
|
|
|
|
|
2010-05-22 20:24:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
linetoc_simple()
|
|
|
|
{
|
2010-06-24 13:34:53 +02:00
|
|
|
local name
|
|
|
|
name=$(get_name "$1")
|
|
|
|
cat <<EOF
|
|
|
|
{.tp_name = "$name", .state=0},
|
|
|
|
EOF
|
|
|
|
simple_event_num=$((simple_event_num + 1))
|
2010-05-22 20:24:51 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
linetoc_end_simple()
|
|
|
|
{
|
2010-06-24 13:34:53 +02:00
|
|
|
cat <<EOF
|
|
|
|
};
|
|
|
|
EOF
|
2010-05-22 20:24:51 +02:00
|
|
|
}
|
|
|
|
|
2010-05-22 18:52:39 +02:00
|
|
|
# Process stdin by calling begin, line, and end functions for the backend
|
|
|
|
convert()
|
|
|
|
{
|
|
|
|
local begin process_line end
|
|
|
|
begin="lineto$1_begin_$backend"
|
|
|
|
process_line="lineto$1_$backend"
|
|
|
|
end="lineto$1_end_$backend"
|
|
|
|
|
|
|
|
"$begin"
|
|
|
|
|
|
|
|
while read -r str; do
|
|
|
|
# Skip comments and empty lines
|
|
|
|
str=${str%%#*}
|
|
|
|
test -z "$str" && continue
|
|
|
|
|
|
|
|
echo
|
|
|
|
"$process_line" "$str"
|
|
|
|
done
|
|
|
|
|
|
|
|
echo
|
|
|
|
"$end"
|
|
|
|
}
|
|
|
|
|
|
|
|
tracetoh()
|
|
|
|
{
|
|
|
|
cat <<EOF
|
|
|
|
#ifndef TRACE_H
|
|
|
|
#define TRACE_H
|
|
|
|
|
|
|
|
/* This file is autogenerated by tracetool, do not edit. */
|
|
|
|
|
|
|
|
#include "qemu-common.h"
|
|
|
|
EOF
|
|
|
|
convert h
|
|
|
|
echo "#endif /* TRACE_H */"
|
|
|
|
}
|
|
|
|
|
|
|
|
tracetoc()
|
|
|
|
{
|
|
|
|
echo "/* This file is autogenerated by tracetool, do not edit. */"
|
|
|
|
convert c
|
|
|
|
}
|
|
|
|
|
|
|
|
# Choose backend
|
|
|
|
case "$1" in
|
2010-05-22 20:24:51 +02:00
|
|
|
"--nop" | "--simple") backend="${1#--}" ;;
|
2010-05-22 18:52:39 +02:00
|
|
|
*) usage ;;
|
|
|
|
esac
|
|
|
|
shift
|
|
|
|
|
|
|
|
case "$1" in
|
|
|
|
"-h") tracetoh ;;
|
|
|
|
"-c") tracetoc ;;
|
|
|
|
"--check-backend") exit 0 ;; # used by ./configure to test for backend
|
|
|
|
*) usage ;;
|
|
|
|
esac
|
|
|
|
|
|
|
|
exit 0
|