Annotation of qemu/scripts/tracetool, revision 1.1.1.2

1.1       root        1: #!/bin/sh
                      2: #
                      3: # Code generator for trace events
                      4: #
                      5: # Copyright IBM, Corp. 2010
                      6: #
                      7: # This work is licensed under the terms of the GNU GPL, version 2.  See
                      8: # the COPYING file in the top-level directory.
                      9: 
                     10: # Disable pathname expansion, makes processing text with '*' characters simpler
                     11: set -f
                     12: 
                     13: usage()
                     14: {
                     15:     cat >&2 <<EOF
                     16: usage: $0 [--nop | --simple | --stderr | --ust | --dtrace] [-h | -c]
                     17: Generate tracing code for a file on stdin.
                     18: 
                     19: Backends:
                     20:   --nop     Tracing disabled
                     21:   --simple  Simple built-in backend
                     22:   --stderr  Stderr built-in backend
                     23:   --ust     LTTng User Space Tracing backend
                     24:   --dtrace  DTrace/SystemTAP backend
                     25: 
                     26: Output formats:
                     27:   -h     Generate .h file
                     28:   -c     Generate .c file
                     29:   -d     Generate .d file (DTrace only)
                     30:   --stap Generate .stp file (DTrace with SystemTAP only)
                     31: 
                     32: Options:
1.1.1.2 ! root       33:   --binary       [path]    Full path to QEMU binary
        !            34:   --target-arch  [arch]    QEMU emulator target arch
        !            35:   --target-type  [type]    QEMU emulator target type ('system' or 'user')
        !            36:   --probe-prefix [prefix]  Prefix for dtrace probe names
        !            37:                            (default: qemu-\$targettype-\$targetarch)
1.1       root       38: 
                     39: EOF
                     40:     exit 1
                     41: }
                     42: 
                     43: # Get the name of a trace event
                     44: get_name()
                     45: {
                     46:     echo ${1%%\(*}
                     47: }
                     48: 
                     49: # Get the argument list of a trace event, including types and names
                     50: get_args()
                     51: {
                     52:     local args
                     53:     args=${1#*\(}
1.1.1.2 ! root       54:     args=${args%%\)*}
1.1       root       55:     echo "$args"
                     56: }
                     57: 
                     58: # Get the argument name list of a trace event
                     59: get_argnames()
                     60: {
                     61:     local nfields field name sep
                     62:     nfields=0
                     63:     sep="$2"
                     64:     for field in $(get_args "$1"); do
                     65:         nfields=$((nfields + 1))
                     66: 
                     67:         # Drop pointer star
                     68:         field=${field#\*}
                     69: 
                     70:         # Only argument names have commas at the end
                     71:         name=${field%,}
                     72:         test "$field" = "$name" && continue
                     73: 
                     74:         printf "%s%s " $name $sep
                     75:     done
                     76: 
                     77:     # Last argument name
                     78:     if [ "$nfields" -gt 1 ]
                     79:     then
                     80:         printf "%s" "$name"
                     81:     fi
                     82: }
                     83: 
                     84: # Get the number of arguments to a trace event
                     85: get_argc()
                     86: {
                     87:     local name argc
                     88:     argc=0
                     89:     for name in $(get_argnames "$1", ","); do
                     90:         argc=$((argc + 1))
                     91:     done
                     92:     echo $argc
                     93: }
                     94: 
                     95: # Get the format string for a trace event
                     96: get_fmt()
                     97: {
                     98:     local fmt
                     99:     fmt=${1#*\"}
                    100:     fmt=${fmt%\"*}
                    101:     echo "$fmt"
                    102: }
                    103: 
                    104: # Get the state of a trace event
                    105: get_state()
                    106: {
                    107:     local str disable state
                    108:     str=$(get_name "$1")
                    109:     disable=${str##disable }
                    110:     if [ "$disable" = "$str" ] ; then
                    111:         state=1
                    112:     else
                    113:         state=0
                    114:     fi
                    115:     echo "$state"
                    116: }
                    117: 
                    118: linetoh_begin_nop()
                    119: {
                    120:     return
                    121: }
                    122: 
                    123: linetoh_nop()
                    124: {
                    125:     local name args
                    126:     name=$(get_name "$1")
                    127:     args=$(get_args "$1")
                    128: 
                    129:     # Define an empty function for the trace event
                    130:     cat <<EOF
                    131: static inline void trace_$name($args)
                    132: {
                    133: }
                    134: EOF
                    135: }
                    136: 
                    137: linetoh_end_nop()
                    138: {
                    139:     return
                    140: }
                    141: 
                    142: linetoc_begin_nop()
                    143: {
                    144:     return
                    145: }
                    146: 
                    147: linetoc_nop()
                    148: {
                    149:     # No need for function definitions in nop backend
                    150:     return
                    151: }
                    152: 
                    153: linetoc_end_nop()
                    154: {
                    155:     return
                    156: }
                    157: 
                    158: linetoh_begin_simple()
                    159: {
                    160:     cat <<EOF
                    161: #include "simpletrace.h"
                    162: EOF
                    163: 
                    164:     simple_event_num=0
                    165: }
                    166: 
                    167: cast_args_to_uint64_t()
                    168: {
                    169:     local arg
                    170:     for arg in $(get_argnames "$1", ","); do
                    171:         printf "%s" "(uint64_t)(uintptr_t)$arg"
                    172:     done
                    173: }
                    174: 
                    175: linetoh_simple()
                    176: {
                    177:     local name args argc trace_args state
                    178:     name=$(get_name "$1")
                    179:     args=$(get_args "$1")
                    180:     argc=$(get_argc "$1")
                    181:     state=$(get_state "$1")
                    182:     if [ "$state" = "0" ]; then
                    183:         name=${name##disable }
                    184:     fi
                    185: 
                    186:     trace_args="$simple_event_num"
                    187:     if [ "$argc" -gt 0 ]
                    188:     then
                    189:         trace_args="$trace_args, $(cast_args_to_uint64_t "$1")"
                    190:     fi
                    191: 
                    192:     cat <<EOF
                    193: static inline void trace_$name($args)
                    194: {
                    195:     trace$argc($trace_args);
                    196: }
                    197: EOF
                    198: 
                    199:     simple_event_num=$((simple_event_num + 1))
                    200: }
                    201: 
                    202: linetoh_end_simple()
                    203: {
                    204:     cat <<EOF
                    205: #define NR_TRACE_EVENTS $simple_event_num
                    206: extern TraceEvent trace_list[NR_TRACE_EVENTS];
                    207: EOF
                    208: }
                    209: 
                    210: linetoc_begin_simple()
                    211: {
                    212:     cat <<EOF
                    213: #include "trace.h"
                    214: 
                    215: TraceEvent trace_list[] = {
                    216: EOF
                    217:     simple_event_num=0
                    218: 
                    219: }
                    220: 
                    221: linetoc_simple()
                    222: {
                    223:     local name state
                    224:     name=$(get_name "$1")
                    225:     state=$(get_state "$1")
                    226:     if [ "$state" = "0" ] ; then
                    227:         name=${name##disable }
                    228:     fi
                    229:     cat <<EOF
                    230: {.tp_name = "$name", .state=$state},
                    231: EOF
                    232:     simple_event_num=$((simple_event_num + 1))
                    233: }
                    234: 
                    235: linetoc_end_simple()
                    236: {
                    237:     cat <<EOF
                    238: };
                    239: EOF
                    240: }
                    241: 
                    242: #STDERR
                    243: linetoh_begin_stderr()
                    244: {
                    245:     cat <<EOF
                    246: #include <stdio.h>
                    247: EOF
                    248: }
                    249: 
                    250: linetoh_stderr()
                    251: {
                    252:     local name args argnames argc fmt
                    253:     name=$(get_name "$1")
                    254:     args=$(get_args "$1")
                    255:     argnames=$(get_argnames "$1" ",")
                    256:     argc=$(get_argc "$1")
                    257:     fmt=$(get_fmt "$1")
                    258: 
                    259:     if [ "$argc" -gt 0 ]; then
                    260:         argnames=", $argnames"
                    261:     fi
                    262: 
                    263:     cat <<EOF
                    264: static inline void trace_$name($args)
                    265: {
                    266:     fprintf(stderr, "$name $fmt\n" $argnames);
                    267: }
                    268: EOF
                    269: }
                    270: 
                    271: linetoh_end_stderr()
                    272: {
                    273: return
                    274: }
                    275: 
                    276: linetoc_begin_stderr()
                    277: {
                    278: return
                    279: }
                    280: 
                    281: linetoc_stderr()
                    282: {
                    283: return
                    284: }
                    285: 
                    286: linetoc_end_stderr()
                    287: {
                    288: return
                    289: }
                    290: #END OF STDERR
                    291: 
                    292: # Clean up after UST headers which pollute the namespace
                    293: ust_clean_namespace() {
                    294:     cat <<EOF
                    295: #undef mutex_lock
                    296: #undef mutex_unlock
                    297: #undef inline
                    298: #undef wmb
                    299: EOF
                    300: }
                    301: 
                    302: linetoh_begin_ust()
                    303: {
                    304:     echo "#include <ust/tracepoint.h>"
                    305:     ust_clean_namespace
                    306: }
                    307: 
                    308: linetoh_ust()
                    309: {
                    310:     local name args argnames
                    311:     name=$(get_name "$1")
                    312:     args=$(get_args "$1")
                    313:     argnames=$(get_argnames "$1", ",")
                    314: 
                    315:     cat <<EOF
                    316: DECLARE_TRACE(ust_$name, TP_PROTO($args), TP_ARGS($argnames));
                    317: #define trace_$name trace_ust_$name
                    318: EOF
                    319: }
                    320: 
                    321: linetoh_end_ust()
                    322: {
                    323:     return
                    324: }
                    325: 
                    326: linetoc_begin_ust()
                    327: {
                    328:     cat <<EOF
                    329: #include <ust/marker.h>
                    330: $(ust_clean_namespace)
                    331: #include "trace.h"
                    332: EOF
                    333: }
                    334: 
                    335: linetoc_ust()
                    336: {
                    337:     local name args argnames fmt
                    338:     name=$(get_name "$1")
                    339:     args=$(get_args "$1")
                    340:     argnames=$(get_argnames "$1", ",")
1.1.1.2 ! root      341:     [ -z "$argnames" ] || argnames=", $argnames"
1.1       root      342:     fmt=$(get_fmt "$1")
                    343: 
                    344:     cat <<EOF
                    345: DEFINE_TRACE(ust_$name);
                    346: 
                    347: static void ust_${name}_probe($args)
                    348: {
1.1.1.2 ! root      349:     trace_mark(ust, $name, "$fmt"$argnames);
1.1       root      350: }
                    351: EOF
                    352: 
                    353:     # Collect names for later
                    354:     names="$names $name"
                    355: }
                    356: 
                    357: linetoc_end_ust()
                    358: {
                    359:     cat <<EOF
                    360: static void __attribute__((constructor)) trace_init(void)
                    361: {
                    362: EOF
                    363: 
                    364:     for name in $names; do
                    365:         cat <<EOF
                    366:     register_trace_ust_$name(ust_${name}_probe);
                    367: EOF
                    368:     done
                    369: 
                    370:     echo "}"
                    371: }
                    372: 
                    373: linetoh_begin_dtrace()
                    374: {
                    375:     cat <<EOF
                    376: #include "trace-dtrace.h"
                    377: EOF
                    378: }
                    379: 
                    380: linetoh_dtrace()
                    381: {
                    382:     local name args argnames state nameupper
                    383:     name=$(get_name "$1")
                    384:     args=$(get_args "$1")
                    385:     argnames=$(get_argnames "$1", ",")
                    386:     state=$(get_state "$1")
                    387:     if [ "$state" = "0" ] ; then
                    388:         name=${name##disable }
                    389:     fi
                    390: 
                    391:     nameupper=`echo $name | tr '[:lower:]' '[:upper:]'`
                    392: 
                    393:     # Define an empty function for the trace event
                    394:     cat <<EOF
                    395: static inline void trace_$name($args) {
                    396:     if (QEMU_${nameupper}_ENABLED()) {
                    397:         QEMU_${nameupper}($argnames);
                    398:     }
                    399: }
                    400: EOF
                    401: }
                    402: 
                    403: linetoh_end_dtrace()
                    404: {
                    405:     return
                    406: }
                    407: 
                    408: linetoc_begin_dtrace()
                    409: {
                    410:     return
                    411: }
                    412: 
                    413: linetoc_dtrace()
                    414: {
                    415:     # No need for function definitions in dtrace backend
                    416:     return
                    417: }
                    418: 
                    419: linetoc_end_dtrace()
                    420: {
                    421:     return
                    422: }
                    423: 
                    424: linetod_begin_dtrace()
                    425: {
                    426:     cat <<EOF
                    427: provider qemu {
                    428: EOF
                    429: }
                    430: 
                    431: linetod_dtrace()
                    432: {
                    433:     local name args state
                    434:     name=$(get_name "$1")
                    435:     args=$(get_args "$1")
                    436:     state=$(get_state "$1")
                    437:     if [ "$state" = "0" ] ; then
                    438:         name=${name##disable }
                    439:     fi
                    440: 
                    441:     # DTrace provider syntax expects foo() for empty
                    442:     # params, not foo(void)
                    443:     if [ "$args" = "void" ]; then
                    444:        args=""
                    445:     fi
                    446: 
                    447:     # Define prototype for probe arguments
                    448:     cat <<EOF
                    449:         probe $name($args);
                    450: EOF
                    451: }
                    452: 
                    453: linetod_end_dtrace()
                    454: {
                    455:     cat <<EOF
                    456: };
                    457: EOF
                    458: }
                    459: 
                    460: linetostap_begin_dtrace()
                    461: {
                    462:     return
                    463: }
                    464: 
                    465: linetostap_dtrace()
                    466: {
                    467:     local i arg name args arglist state
                    468:     name=$(get_name "$1")
                    469:     args=$(get_args "$1")
                    470:     arglist=$(get_argnames "$1", "")
                    471:     state=$(get_state "$1")
                    472:     if [ "$state" = "0" ] ; then
                    473:         name=${name##disable }
                    474:     fi
                    475: 
                    476:     # Define prototype for probe arguments
                    477:     cat <<EOF
1.1.1.2 ! root      478: probe $probeprefix.$name = process("$binary").mark("$name")
1.1       root      479: {
                    480: EOF
                    481: 
                    482:     i=1
                    483:     for arg in $arglist
                    484:     do
                    485:         # 'limit' is a reserved keyword
                    486:         if [ "$arg" = "limit" ]; then
                    487:           arg="_limit"
                    488:         fi
                    489:         cat <<EOF
                    490:   $arg = \$arg$i;
                    491: EOF
1.1.1.2 ! root      492:         i="$((i+1))"
1.1       root      493:     done
                    494: 
                    495:     cat <<EOF
                    496: }
                    497: EOF
                    498: }
                    499: 
                    500: linetostap_end_dtrace()
                    501: {
                    502:     return
                    503: }
                    504: 
                    505: # Process stdin by calling begin, line, and end functions for the backend
                    506: convert()
                    507: {
                    508:     local begin process_line end str disable
                    509:     begin="lineto$1_begin_$backend"
                    510:     process_line="lineto$1_$backend"
                    511:     end="lineto$1_end_$backend"
                    512: 
                    513:     "$begin"
                    514: 
                    515:     while read -r str; do
                    516:         # Skip comments and empty lines
                    517:         test -z "${str%%#*}" && continue
                    518: 
                    519:         # Process the line.  The nop backend handles disabled lines.
                    520:         disable=${str%%disable *}
                    521:         echo
                    522:         if test -z "$disable"; then
                    523:             # Pass the disabled state as an arg for the simple
                    524:             # or DTrace backends which handle it dynamically.
                    525:             # For all other backends, call lineto$1_nop()
                    526:             if [ $backend = "simple" -o "$backend" = "dtrace" ]; then
                    527:                 "$process_line" "$str"
                    528:             else
                    529:                 "lineto$1_nop" "${str##disable }"
                    530:             fi
                    531:         else
                    532:             "$process_line" "$str"
                    533:         fi
                    534:     done
                    535: 
                    536:     echo
                    537:     "$end"
                    538: }
                    539: 
                    540: tracetoh()
                    541: {
                    542:     cat <<EOF
                    543: #ifndef TRACE_H
                    544: #define TRACE_H
                    545: 
                    546: /* This file is autogenerated by tracetool, do not edit. */
                    547: 
                    548: #include "qemu-common.h"
                    549: EOF
                    550:     convert h
                    551:     echo "#endif /* TRACE_H */"
                    552: }
                    553: 
                    554: tracetoc()
                    555: {
                    556:     echo "/* This file is autogenerated by tracetool, do not edit. */"
                    557:     convert c
                    558: }
                    559: 
                    560: tracetod()
                    561: {
                    562:     if [ $backend != "dtrace" ]; then
                    563:        echo "DTrace probe generator not applicable to $backend backend"
                    564:        exit 1
                    565:     fi
                    566:     echo "/* This file is autogenerated by tracetool, do not edit. */"
                    567:     convert d
                    568: }
                    569: 
                    570: tracetostap()
                    571: {
                    572:     if [ $backend != "dtrace" ]; then
                    573:        echo "SystemTAP tapset generator not applicable to $backend backend"
                    574:        exit 1
                    575:     fi
                    576:     if [ -z "$binary" ]; then
                    577:        echo "--binary is required for SystemTAP tapset generator"
                    578:        exit 1
                    579:     fi
1.1.1.2 ! root      580:     if [ -z "$probeprefix" -a -z "$targettype" ]; then
1.1       root      581:        echo "--target-type is required for SystemTAP tapset generator"
                    582:        exit 1
                    583:     fi
1.1.1.2 ! root      584:     if [ -z "$probeprefix" -a -z "$targetarch" ]; then
1.1       root      585:        echo "--target-arch is required for SystemTAP tapset generator"
                    586:        exit 1
                    587:     fi
1.1.1.2 ! root      588:     if [ -z "$probeprefix" ]; then
        !           589:         probeprefix="qemu.$targettype.$targetarch";
        !           590:     fi
1.1       root      591:     echo "/* This file is autogenerated by tracetool, do not edit. */"
                    592:     convert stap
                    593: }
                    594: 
                    595: 
                    596: backend=
                    597: output=
                    598: binary=
                    599: targettype=
                    600: targetarch=
1.1.1.2 ! root      601: probeprefix=
1.1       root      602: 
                    603: 
                    604: until [ -z "$1" ]
                    605: do
                    606:   case "$1" in
                    607:     "--nop" | "--simple" | "--stderr" | "--ust" | "--dtrace") backend="${1#--}" ;;
                    608: 
                    609:     "--binary") shift ; binary="$1" ;;
                    610:     "--target-arch") shift ; targetarch="$1" ;;
                    611:     "--target-type") shift ; targettype="$1" ;;
1.1.1.2 ! root      612:     "--probe-prefix") shift ; probeprefix="$1" ;;
1.1       root      613: 
                    614:     "-h" | "-c" | "-d") output="${1#-}" ;;
                    615:     "--stap") output="${1#--}" ;;
                    616: 
                    617:     "--check-backend") exit 0 ;; # used by ./configure to test for backend
                    618: 
                    619:     "--list-backends") # used by ./configure to list available backends
                    620:           echo "nop simple stderr ust dtrace"
                    621:           exit 0
                    622:           ;;
                    623: 
                    624:     *)
                    625:       usage;;
                    626:   esac
                    627:   shift
                    628: done
                    629: 
                    630: if [ "$backend" = "" -o "$output" = "" ]; then
                    631:   usage
                    632: fi
                    633: 
                    634: gen="traceto$output"
                    635: "$gen"
                    636: 
                    637: exit 0

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.