Annotation of qemu/scripts/tracetool, revision 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.