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 }