github.com/google/syzkaller@v0.0.0-20240517125934-c0f1611a36d6/tools/syz-trace2syz/parser/straceLex.rl (about)

     1  // Copyright 2018 syzkaller project authors. All rights reserved.
     2  // Use of this source code is governed by Apache 2 LICENSE that can be found in the LICENSE file.
     3  
     4  // +build !codeanalysis
     5  
     6  package parser
     7  
     8  import (
     9      "fmt"
    10      "encoding/hex"
    11      "strconv"
    12      "strings"
    13      "github.com/google/syzkaller/pkg/log"
    14  )
    15  
    16  %%{
    17      machine strace;
    18      write data;
    19      access lex.;
    20      variable p lex.p;
    21      variable pe lex.pe;
    22  }%%
    23  
    24  type Stracelexer struct {
    25      result *Syscall
    26      data []byte
    27      p, pe, cs int
    28      ts, te, act int
    29  }
    30  
    31  func newStraceLexer (data []byte) *Stracelexer {
    32      lex := &Stracelexer {
    33          data: data,
    34          pe: len(data),
    35      }
    36  
    37      %% write init;
    38      return lex
    39  }
    40  
    41  func (lex *Stracelexer) Lex(out *StraceSymType) int {
    42      eof := lex.pe
    43      tok := 0
    44      %%{
    45          dateSep = '-' | '\/';
    46          datetimeSep = 'T' | '-';
    47          microTimeSep = '+' | '-';
    48          date = digit{4}.dateSep.digit{2}.dateSep.digit{2};
    49          nullptr = "NULL";
    50          time = digit{2}.':'.digit{2}.':'.digit{2} |
    51              digit{2}.':'.digit{2}.':'.digit{2}.microTimeSep.digit{4} |
    52              digit{2}.':'.digit{2}.':'.digit{2}.microTimeSep.digit{4}.'.'.digit+ |
    53              digit{2}.':'.digit{2}.':'.digit{2}.'.'.digit+;
    54          datetime = date.datetimeSep.time;
    55          unfinished = '<unfinished ...>' | ',  <unfinished ...>';
    56          ipv4 = digit{1,3}.'\.'.digit{1,3}.'\.'.digit{1,3}.'\.'.digit{1,3};
    57          identifier = ([A-Za-z':'].[0-9a-z'_'\*\.\-':']*) | ipv4;
    58          resumed = '<... '.identifier+.' resumed>'
    59                      | '<... '.identifier+.' resumed> ,'
    60                      | '<... resuming'.' '.identifier.' '.identifier.' '.'...>';
    61          flag = (['_']+?upper+ . ['_'A-Z0-9]+)-nullptr;
    62          string = '\"'.['_''\.'('')'' ''#'':'0-9a-zA-Z\/\\\*]*.'\"';
    63          mac = xdigit{2}.':'.xdigit{2}.':'.xdigit{2}.':'.xdigit{2}.':'.xdigit{2}.':'.xdigit{2};
    64          comment := |*
    65              ((any-"*\/"));
    66              "*\/" => {fgoto main;};
    67          *|;
    68  
    69          main := |*
    70              [0-9]* => {out.val_int, _ = strconv.ParseInt(string(lex.data[lex.ts : lex.te]), 0, 64); tok = INT;fbreak;};
    71              digit . '.' . digit* => {out.val_double, _ = strconv.ParseFloat(string(lex.data[lex.ts : lex.te]), 64); tok= DOUBLE; fbreak;};
    72              '0x'xdigit+ => {out.val_uint, _ = strconv.ParseUint(string(lex.data[lex.ts:lex.te]), 0, 64); tok = UINT;fbreak;};
    73              string.['.']* => {out.data = ParseString(string(lex.data[lex.ts+1:lex.te-1])); tok = STRING_LITERAL;fbreak;};
    74              nullptr => {tok = NULL; fbreak;};
    75              flag => {out.data = string(lex.data[lex.ts:lex.te]); tok = FLAG; fbreak;};
    76              '\"'.flag.'\"' => {out.data = string(lex.data[lex.ts+1:lex.te-1]); tok=FLAG; fbreak;};
    77              identifier => {out.data = string(lex.data[lex.ts:lex.te]); tok = IDENTIFIER;fbreak;};
    78              unfinished => {tok = UNFINISHED; fbreak;};
    79              resumed => {tok = RESUMED; fbreak;};
    80              mac => {out.data = string(lex.data[lex.ts : lex.te]); tok = MAC; fbreak;};
    81              '=' => {tok = EQUALS;fbreak;};
    82              '(' => {tok = LPAREN;fbreak;};
    83              '=@' => {tok = EQUALAT; fbreak;};
    84              ')' => {tok = RPAREN;fbreak;};
    85              '[' => {tok = LBRACKET_SQUARE;fbreak;};
    86              ']' => {tok = RBRACKET_SQUARE;fbreak;};
    87              '*' => {tok = TIMES; fbreak;};
    88              '{' => {tok = LBRACKET;fbreak;};
    89              [.]*.'}' => {tok = RBRACKET;fbreak;};
    90              '|' => {tok = OR;fbreak;};
    91              ':' => {tok = COLON; fbreak;};
    92              '&' => {tok = AND;fbreak;};
    93              '!' => {tok = NOT;fbreak;};
    94              '~' => {tok = ONESCOMP; fbreak;};
    95              '<<' => {tok = LSHIFT; fbreak;};
    96              '>>' => {tok = RSHIFT; fbreak;};
    97              '->' => {tok = ARROW; fbreak;};
    98              '=>' => {tok = ARROW; fbreak;};
    99              ',' => {tok = COMMA;fbreak;};
   100              '-' => {tok = MINUS; fbreak;};
   101              '+' => {tok = PLUS; fbreak;};
   102              '\/' => {tok = FORWARDSLASH; fbreak;};
   103              datetime => {out.data = string(lex.data[lex.ts:lex.te]); tok = DATETIME; fbreak;};
   104              "\/*" => {fgoto comment;};
   105              "?" => {tok = QUESTION; fbreak;};
   106              space;
   107          *|;
   108  
   109          write exec;
   110        }%%
   111  
   112      return tok;
   113  }
   114  
   115  func (lex *Stracelexer) Error(e string) {
   116      fmt.Println("error:", e)
   117  }
   118  
   119  func ParseString(s string) string{
   120  	var decoded []byte
   121  	var err error
   122  	var strippedStr string
   123  	strippedStr = strings.Replace(s, `\x`, "", -1)
   124  	strippedStr = strings.Replace(strippedStr, `"`, "", -1)
   125  
   126  	if decoded, err = hex.DecodeString(strippedStr); err != nil {
   127  		log.Logf(2, "failed to decode string: %s, with error: %s", s, err.Error())
   128  		decoded = []byte(strippedStr)
   129  	}
   130  	return string(decoded)
   131  }