Annotation of qemu/scripts/tracetool, revision 1.1.1.1

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

unix.superglobalmegacorp.com

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