Browse Source

Initial import

maze 5 months ago
parent
commit
007e3bf1c5
18 changed files with 5471 additions and 21 deletions
  1. 5
    21
      .gitignore
  2. 449
    0
      assembler.go
  3. 82
    0
      cmd/bpfasm/main.go
  4. 4
    0
      doc.go
  5. 6
    0
      go.mod
  6. 4
    0
      go.sum
  7. 140
    0
      parse.go
  8. 205
    0
      parser/BPF.g4
  9. 183
    0
      parser/bpf_base_listener.go
  10. 116
    0
      parser/bpf_base_visitor.go
  11. 313
    0
      parser/bpf_lexer.go
  12. 171
    0
      parser/bpf_listener.go
  13. 3667
    0
      parser/bpf_parser.go
  14. 90
    0
      parser/bpf_visitor.go
  15. 4
    0
      testdata/example1.asm
  16. 4
    0
      testdata/example2.asm
  17. 17
    0
      testdata/example3.asm
  18. 11
    0
      testdata/example4.asm

+ 5
- 21
.gitignore View File

@@ -12,28 +12,12 @@
12 12
 # Output of the go coverage tool, specifically when used with LiteIDE
13 13
 *.out
14 14
 
15
-# ---> Java
16
-# Compiled class file
17
-*.class
18
-
19 15
 # Log file
20 16
 *.log
21 17
 
22
-# BlueJ files
23
-*.ctxt
24
-
25
-# Mobile Tools for Java (J2ME)
26
-.mtj.tmp/
27
-
28
-# Package Files #
29
-*.jar
30
-*.war
31
-*.nar
32
-*.ear
33
-*.zip
34
-*.tar.gz
35
-*.rar
36
-
37
-# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
38
-hs_err_pid*
18
+# IntelliJ files
19
+.idea/
39 20
 
21
+# Antlr artifacts
22
+parser/*.interp
23
+parser/*.tokens

+ 449
- 0
assembler.go View File

@@ -0,0 +1,449 @@
1
+//go:generate antlr -package parser -Dlanguage=Go -visitor parser/BPF.g4
2
+package bpf
3
+
4
+import (
5
+	"errors"
6
+	"fmt"
7
+	"log"
8
+
9
+	"github.com/antlr/antlr4/runtime/Go/antlr"
10
+	"golang.org/x/net/bpf"
11
+
12
+	"maze.io/x/bpf/parser"
13
+)
14
+
15
+// Assemble BPF instructions from source.
16
+func Assemble(source string) ([]bpf.RawInstruction, error) {
17
+	var (
18
+		input  = antlr.NewInputStream(source)
19
+		lexer  = parser.NewBPFLexer(input)
20
+		stream = antlr.NewCommonTokenStream(lexer, 0)
21
+		parse  = parser.NewBPFParser(stream)
22
+	)
23
+	parse.BuildParseTrees = true
24
+
25
+	asm := new(assembler)
26
+	result := asm.Visit(parse.Program()).([]interface{})
27
+
28
+	/*
29
+		tokens := stream.GetAllTokens()
30
+		log.Printf("%d tokens", len(tokens))
31
+		for _, token := range tokens {
32
+			log.Printf("token: %s", token)
33
+		}
34
+	*/
35
+	log.Printf("result: %+v", result)
36
+
37
+	if result[1] == nil {
38
+		return result[0].([]bpf.RawInstruction), nil
39
+	}
40
+	return nil, result[1].(error)
41
+}
42
+
43
+type assembler struct {
44
+	*antlr.BaseParseTreeVisitor
45
+}
46
+
47
+func (asm *assembler) Visit(tree antlr.ParseTree) interface{} {
48
+	return tree.Accept(asm)
49
+}
50
+
51
+func (asm *assembler) VisitChildren(node antlr.RuleNode) interface{} {
52
+	var results []interface{}
53
+	for _, child := range node.GetChildren() {
54
+		switch child := child.(type) {
55
+		case *antlr.ErrorNodeImpl:
56
+			results = append(results, fmt.Errorf("invalid token %q", child.GetText()))
57
+
58
+		default:
59
+			instruction := child.(antlr.ParseTree).Accept(asm)
60
+			if instruction != nil {
61
+				results = append(results, instruction)
62
+			}
63
+		}
64
+	}
65
+	return results
66
+}
67
+
68
+func (asm *assembler) VisitProgram(ctx *parser.ProgramContext) interface{} {
69
+	program := []interface{}{}
70
+	labelAddresses := map[string]uint32{}
71
+
72
+	results := asm.VisitChildren(ctx)
73
+	for _, result := range results.([]interface{}) {
74
+		switch result := result.(type) {
75
+		case string:
76
+			labelAddresses[result] = uint32(len(program))
77
+			//log.Printf("label %q at %d", result, labelAddresses[result])
78
+
79
+		case []interface{}:
80
+			for _, word := range result {
81
+				switch word := word.(type) {
82
+				case string:
83
+					labelAddresses[word] = uint32(len(program))
84
+				default:
85
+					program = append(program, word)
86
+				}
87
+			}
88
+
89
+		case error:
90
+			return []interface{}{nil, result}
91
+
92
+		default:
93
+			program = append(program, result)
94
+		}
95
+	}
96
+
97
+	resolveLabelAddress := func(i int, label string) (skip uint8, err error) {
98
+		if addr, ok := labelAddresses[label]; ok {
99
+			// log.Printf("label %q at %d -> %d", label, addr, addr-uint32(i)-1)
100
+			if addr < uint32(i) {
101
+				return 0, fmt.Errorf("instruction %d: jump to negative offset label %q", i, label)
102
+			}
103
+			return uint8(addr - uint32(i) - 1), nil
104
+		}
105
+		return 0, fmt.Errorf("instruction %d: jump to unresolved label %q", i, label)
106
+	}
107
+
108
+	var instructions []bpf.Instruction
109
+	for i, word := range program {
110
+		// log.Printf("program: %T: %+v", word, word)
111
+		switch word := word.(type) {
112
+		case bpf.Instruction:
113
+			instructions = append(instructions, word)
114
+
115
+		case conditionalJump:
116
+			switch skip := word.skipTrue.(type) {
117
+			case uint8:
118
+				word.Instruction.SkipTrue = skip
119
+			case string:
120
+				addr, err := resolveLabelAddress(i, skip)
121
+				if err != nil {
122
+					return []interface{}{nil, err}
123
+				}
124
+				word.Instruction.SkipFalse = addr
125
+			default:
126
+				return []interface{}{nil, fmt.Errorf("instruction %d: invalid jump true %T", i, skip)}
127
+			}
128
+			switch skip := word.skipFalse.(type) {
129
+			case uint8:
130
+				word.Instruction.SkipFalse = skip
131
+			case string:
132
+				addr, err := resolveLabelAddress(i, skip)
133
+				if err != nil {
134
+					return []interface{}{nil, err}
135
+				}
136
+				word.Instruction.SkipFalse = addr
137
+			}
138
+			instructions = append(instructions, word.Instruction)
139
+
140
+		case conditionalJumpX:
141
+			switch skip := word.skipTrue.(type) {
142
+			case uint8:
143
+				word.Instruction.SkipTrue = skip
144
+			case string:
145
+				addr, err := resolveLabelAddress(i, skip)
146
+				if err != nil {
147
+					return []interface{}{nil, err}
148
+				}
149
+				word.Instruction.SkipFalse = addr
150
+			}
151
+			switch skip := word.skipFalse.(type) {
152
+			case uint8:
153
+				word.Instruction.SkipFalse = skip
154
+			case string:
155
+				addr, err := resolveLabelAddress(i, skip)
156
+				if err != nil {
157
+					return []interface{}{nil, err}
158
+				}
159
+				word.Instruction.SkipFalse = addr
160
+			}
161
+			instructions = append(instructions, word.Instruction)
162
+
163
+		default:
164
+			return []interface{}{nil, fmt.Errorf("instruction %d: unknown type %T", i, word)}
165
+		}
166
+	}
167
+
168
+	raw, err := bpf.Assemble(instructions)
169
+	return []interface{}{raw, err}
170
+}
171
+
172
+func (asm *assembler) VisitLabelDefinition(ctx *parser.LabelDefinitionContext) interface{} {
173
+	return ctx.IDENTIFIER().GetText()
174
+}
175
+
176
+func (asm *assembler) VisitLabel(ctx *parser.LabelContext) interface{} {
177
+	return ctx.IDENTIFIER().GetText()
178
+}
179
+
180
+func (asm *assembler) VisitComment(ctx *parser.CommentContext) interface{} {
181
+	return asm.VisitChildren(ctx)
182
+}
183
+
184
+func (asm *assembler) VisitInstruction(ctx *parser.InstructionContext) interface{} {
185
+	switch {
186
+	case ctx.AluOperation() != nil:
187
+		return asm.Visit(ctx.AluOperation())
188
+
189
+	case ctx.JumpOperation() != nil:
190
+		return asm.Visit(ctx.JumpOperation())
191
+
192
+	case ctx.JumpConditionalOperation() != nil:
193
+		return asm.Visit(ctx.JumpConditionalOperation())
194
+
195
+	case ctx.LoadOperation() != nil:
196
+		return asm.Visit(ctx.LoadOperation())
197
+
198
+	case ctx.StoreOperation() != nil:
199
+		return asm.Visit(ctx.StoreOperation())
200
+
201
+	case ctx.SimpleOperation() != nil:
202
+		return asm.Visit(ctx.SimpleOperation())
203
+
204
+	case ctx.ReturnOperation() != nil:
205
+		return asm.Visit(ctx.ReturnOperation())
206
+
207
+	default:
208
+		return fmt.Errorf("unknown instruction: %#+v", ctx)
209
+	}
210
+}
211
+
212
+func (asm *assembler) VisitAluOperation(ctx *parser.AluOperationContext) interface{} {
213
+	var (
214
+		opcode = asm.Visit(ctx.AluOperator()).(bpf.ALUOp)
215
+	)
216
+	switch {
217
+	case ctx.LiteralNumber() != nil:
218
+		return bpf.ALUOpConstant{Op: opcode, Val: asm.Visit(ctx.LiteralNumber()).(uint32)}
219
+	case ctx.RegisterX() != nil:
220
+		return bpf.ALUOpX{Op: opcode}
221
+	default:
222
+		return nil
223
+	}
224
+}
225
+
226
+func (asm *assembler) VisitAluOperator(ctx *parser.AluOperatorContext) interface{} {
227
+	return parseAluOpcode(ctx)
228
+}
229
+
230
+func (asm *assembler) VisitJumpOperation(ctx *parser.JumpOperationContext) interface{} {
231
+	return asm.VisitChildren(ctx)
232
+}
233
+
234
+func (asm *assembler) VisitJumpOperator(ctx *parser.JumpOperatorContext) interface{} {
235
+	return asm.VisitChildren(ctx)
236
+}
237
+
238
+type conditionalJump struct {
239
+	Instruction bpf.JumpIf
240
+	skipTrue    interface{}
241
+	skipFalse   interface{}
242
+}
243
+
244
+type conditionalJumpX struct {
245
+	Instruction bpf.JumpIfX
246
+	skipTrue    interface{}
247
+	skipFalse   interface{}
248
+}
249
+
250
+func (asm *assembler) VisitJumpConditionalOperation(ctx *parser.JumpConditionalOperationContext) interface{} {
251
+	var (
252
+		test    = asm.Visit(ctx.JumpConditionalOperator()).(bpf.JumpTest)
253
+		ifTrue  = asm.Visit(ctx.IfTrue())
254
+		ifFalse interface{}
255
+	)
256
+	if ctx.IfFalse() != nil {
257
+		ifFalse = asm.Visit(ctx.IfFalse())
258
+	}
259
+	switch {
260
+	case ctx.LiteralNumber() != nil:
261
+		return conditionalJump{
262
+			Instruction: bpf.JumpIf{
263
+				Cond: test,
264
+				Val:  asm.Visit(ctx.LiteralNumber()).(uint32),
265
+			},
266
+			skipTrue:  ifTrue,
267
+			skipFalse: ifFalse,
268
+		}
269
+
270
+	case ctx.RegisterX() != nil:
271
+		return conditionalJumpX{
272
+			Instruction: bpf.JumpIfX{
273
+				Cond: test,
274
+			},
275
+			skipTrue:  ifTrue,
276
+			skipFalse: ifFalse,
277
+		}
278
+
279
+	default:
280
+		return errors.New("invalid conditional jump")
281
+	}
282
+}
283
+
284
+func (asm *assembler) VisitJumpConditionalOperator(ctx *parser.JumpConditionalOperatorContext) interface{} {
285
+	return parseJumpCondition(ctx)
286
+}
287
+
288
+func (asm *assembler) VisitIfTrue(ctx *parser.IfTrueContext) interface{} {
289
+	switch {
290
+	case ctx.Label() != nil:
291
+		return asm.Visit(ctx.Label())
292
+	default:
293
+		return uint8(asm.Visit(ctx.Number()).(uint32))
294
+	}
295
+}
296
+
297
+func (asm *assembler) VisitIfFalse(ctx *parser.IfFalseContext) interface{} {
298
+	switch {
299
+	case ctx.Label() != nil:
300
+		return asm.Visit(ctx.Label())
301
+	default:
302
+		return uint8(asm.Visit(ctx.Number()).(uint32))
303
+	}
304
+}
305
+
306
+func (asm *assembler) VisitLoadOperation(ctx *parser.LoadOperationContext) interface{} {
307
+	target := asm.Visit(ctx.LoadOperator()).(dst)
308
+
309
+	switch {
310
+	case ctx.AbsoluteNumber() != nil:
311
+		var (
312
+			number      = asm.Visit(ctx.AbsoluteNumber()).(uint32)
313
+			instruction = bpf.LoadConstant{Val: number}
314
+		)
315
+		switch target {
316
+		case regA:
317
+			instruction.Dst = bpf.RegA
318
+		case regX:
319
+			instruction.Dst = bpf.RegX
320
+		}
321
+		return instruction
322
+
323
+	case ctx.RegisterR() != nil:
324
+		var (
325
+			register    = asm.Visit(ctx.RegisterR()).(int)
326
+			instruction = bpf.LoadScratch{N: register}
327
+		)
328
+		switch target {
329
+		case regA:
330
+			instruction.Dst = bpf.RegA
331
+		case regX:
332
+			instruction.Dst = bpf.RegX
333
+		}
334
+		return instruction
335
+
336
+	case ctx.IndirectX() != nil:
337
+		var (
338
+			number      = asm.Visit(ctx.IndirectX()).(uint32)
339
+			instruction = bpf.LoadIndirect{Off: number}
340
+		)
341
+		switch target {
342
+		case regA, regX:
343
+			instruction.Size = 1
344
+		case reg2:
345
+			instruction.Size = 2
346
+		case reg4:
347
+			instruction.Size = 4
348
+		}
349
+		return instruction
350
+
351
+	case ctx.Extension() != nil:
352
+		return bpf.LoadExtension{Num: asm.Visit(ctx.Extension()).(bpf.Extension)}
353
+
354
+	default:
355
+		return nil
356
+	}
357
+}
358
+
359
+func (asm *assembler) VisitLoadOperator(ctx *parser.LoadOperatorContext) interface{} {
360
+	switch {
361
+	case ctx.LDA() != nil:
362
+		return regA
363
+	case ctx.LDX() != nil:
364
+		return regX
365
+	case ctx.LDB() != nil:
366
+		return reg2
367
+	case ctx.LDH() != nil:
368
+		return reg4
369
+	default:
370
+		return invalid
371
+	}
372
+}
373
+
374
+func (asm *assembler) VisitStoreOperation(ctx *parser.StoreOperationContext) interface{} {
375
+	return bpf.StoreScratch{
376
+		Src: asm.Visit(ctx.StoreOperator()).(bpf.Register),
377
+		N:   asm.Visit(ctx.RegisterR()).(int),
378
+	}
379
+}
380
+
381
+func (asm *assembler) VisitStoreOperator(ctx *parser.StoreOperatorContext) interface{} {
382
+	switch {
383
+	case ctx.STA() != nil:
384
+		return bpf.RegA
385
+	case ctx.STX() != nil:
386
+		return bpf.RegX
387
+	default:
388
+		return 0
389
+	}
390
+}
391
+
392
+func (asm *assembler) VisitSimpleOperation(ctx *parser.SimpleOperationContext) interface{} {
393
+	switch {
394
+	case ctx.TAX() != nil:
395
+		return bpf.TAX{}
396
+	case ctx.TXA() != nil:
397
+		return bpf.TXA{}
398
+	case ctx.NEG() != nil:
399
+		return bpf.NegateA{}
400
+	default:
401
+		return nil
402
+	}
403
+
404
+}
405
+
406
+func (asm *assembler) VisitReturnOperation(ctx *parser.ReturnOperationContext) interface{} {
407
+	switch {
408
+	case ctx.RegisterA() != nil:
409
+		return bpf.RetA{}
410
+
411
+	case ctx.LiteralNumber() != nil:
412
+		return bpf.RetConstant{Val: asm.Visit(ctx.LiteralNumber()).(uint32)}
413
+
414
+	default:
415
+		return nil
416
+	}
417
+}
418
+
419
+func (asm *assembler) VisitNumber(ctx *parser.NumberContext) interface{} {
420
+	return parseNumber(ctx.NUMBER().GetText())
421
+}
422
+
423
+func (asm *assembler) VisitLiteralNumber(ctx *parser.LiteralNumberContext) interface{} {
424
+	return asm.Visit(ctx.Number())
425
+}
426
+
427
+func (asm *assembler) VisitIndirectX(ctx *parser.IndirectXContext) interface{} {
428
+	return asm.Visit(ctx.Number())
429
+}
430
+
431
+func (asm *assembler) VisitAbsoluteNumber(ctx *parser.AbsoluteNumberContext) interface{} {
432
+	return asm.Visit(ctx.Number())
433
+}
434
+
435
+func (asm *assembler) VisitRegisterA(ctx *parser.RegisterAContext) interface{} {
436
+	return bpf.RegA
437
+}
438
+
439
+func (asm *assembler) VisitRegisterX(ctx *parser.RegisterXContext) interface{} {
440
+	return bpf.RegX
441
+}
442
+
443
+func (asm *assembler) VisitRegisterR(ctx *parser.RegisterRContext) interface{} {
444
+	return int(parseNumber(ctx.NUMBER().GetText()))
445
+}
446
+
447
+func (asm *assembler) VisitExtension(ctx *parser.ExtensionContext) interface{} {
448
+	return parseExtension(ctx.IDENTIFIER().GetText())
449
+}

+ 82
- 0
cmd/bpfasm/main.go View File

@@ -0,0 +1,82 @@
1
+/*
2
+Package bpfasm implements a basic BPF assembler.
3
+
4
+
5
+Output modes
6
+
7
+To show the parsed assembly, supply the `-asm` flag.
8
+
9
+To show the raw opcodes, compatible with `bpf_asm -c`, supply the `-opc` flag.
10
+
11
+By default, bpfasm will output to the input file name with the added ".bin"
12
+suffix.
13
+*/
14
+package main
15
+
16
+import (
17
+	"encoding/binary"
18
+	"flag"
19
+	"fmt"
20
+	"io"
21
+	"io/ioutil"
22
+	"os"
23
+
24
+	"maze.io/x/bpf"
25
+)
26
+
27
+func main() {
28
+	outASM := flag.Bool("asm", false, "output assembly")
29
+	outCode := flag.Bool("opc", false, "output opcodes")
30
+	outFile := flag.String("o", "", "output file (default: stdout)")
31
+	flag.Parse()
32
+
33
+	if flag.NArg() != 1 {
34
+		fmt.Fprintln(os.Stderr, "usage: bpfasm <source>")
35
+		os.Exit(1)
36
+	}
37
+
38
+	b, err := ioutil.ReadFile(flag.Arg(0))
39
+	if err != nil {
40
+		fmt.Fprintln(os.Stderr, "error loading", flag.Arg(0)+":", err)
41
+		os.Exit(2)
42
+	}
43
+
44
+	raw, err := bpf.Assemble(string(b))
45
+	if err != nil {
46
+		fmt.Fprintln(os.Stderr, "error assembling", flag.Arg(0)+":", err)
47
+		os.Exit(2)
48
+	}
49
+
50
+	if !*outASM && !*outCode && *outFile == "" {
51
+		*outFile = flag.Arg(0) + ".bin"
52
+		fmt.Fprintln(os.Stderr, "writing to", *outFile)
53
+	}
54
+
55
+	var output io.WriteCloser
56
+	if *outFile != "" {
57
+		if output, err = os.Create(*outFile); err != nil {
58
+			fmt.Fprintln(os.Stderr, "error opening", *outFile+":", err)
59
+			os.Exit(2)
60
+		}
61
+	} else {
62
+		output = os.Stdout
63
+	}
64
+	defer output.Close()
65
+
66
+	if *outCode {
67
+		for _, instruction := range raw {
68
+			fmt.Fprintf(output, "{ %#02x, %2d, %2d, %#08x },\n", instruction.Op, instruction.Jt, instruction.Jf, instruction.K)
69
+		}
70
+	} else if *outASM {
71
+		for _, instruction := range raw {
72
+			fmt.Fprintln(output, instruction.Disassemble())
73
+		}
74
+	} else {
75
+		for _, instruction := range raw {
76
+			binary.Write(output, binary.BigEndian, instruction)
77
+		}
78
+	}
79
+
80
+	//assembled := unsafe.Pointer(&raw[0])
81
+
82
+}

+ 4
- 0
doc.go View File

@@ -0,0 +1,4 @@
1
+/*
2
+Package bpf is an assembler for the Berkeley Packet Filter (bpf).
3
+*/
4
+package bpf

+ 6
- 0
go.mod View File

@@ -0,0 +1,6 @@
1
+module maze.io/x/bpf
2
+
3
+require (
4
+	github.com/antlr/antlr4 v0.0.0-20190223165740-dade65a895c2
5
+	golang.org/x/net v0.0.0-20190227160552-c95aed5357e7
6
+)

+ 4
- 0
go.sum View File

@@ -0,0 +1,4 @@
1
+github.com/antlr/antlr4 v0.0.0-20190223165740-dade65a895c2 h1:Q1TGw0wvj6lqZQ4/CMfZykGQDnkslNcvuDID+AfNiQE=
2
+github.com/antlr/antlr4 v0.0.0-20190223165740-dade65a895c2/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y=
3
+golang.org/x/net v0.0.0-20190227160552-c95aed5357e7 h1:C2F/nMkR/9sfUTpvR3QrjBuTdvMUC/cFajkphs1YLQo=
4
+golang.org/x/net v0.0.0-20190227160552-c95aed5357e7/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=

+ 140
- 0
parse.go View File

@@ -0,0 +1,140 @@
1
+package bpf
2
+
3
+import (
4
+	"log"
5
+	"math"
6
+	"strconv"
7
+	"strings"
8
+
9
+	"golang.org/x/net/bpf"
10
+	"maze.io/x/bpf/parser"
11
+)
12
+
13
+type dst uint8
14
+
15
+const (
16
+	regA dst = iota
17
+	regX
18
+	reg2
19
+	reg4
20
+	invalid dst = 0xff
21
+)
22
+
23
+func parseNumber(text string) uint32 {
24
+	switch {
25
+	case strings.HasPrefix(text, "0x"):
26
+		value, err := strconv.ParseUint(text[2:], 16, 32)
27
+		if err != nil {
28
+			log.Fatalln(err)
29
+		}
30
+		return uint32(value)
31
+
32
+	case strings.HasPrefix(text, "0b"):
33
+		value, err := strconv.ParseUint(text[2:], 2, 32)
34
+		if err != nil {
35
+			log.Fatalln(err)
36
+		}
37
+		return uint32(value)
38
+
39
+	case strings.HasPrefix(text, "0o"):
40
+		value, err := strconv.ParseUint(text[1:], 8, 32)
41
+		if err != nil {
42
+			log.Fatalln(err)
43
+		}
44
+		return uint32(value)
45
+
46
+	default:
47
+		value, err := strconv.Atoi(text)
48
+		if err != nil {
49
+			log.Fatalln(err)
50
+		}
51
+		return uint32(value)
52
+	}
53
+}
54
+
55
+func parseAluOpcode(ctx *parser.AluOperatorContext) bpf.ALUOp {
56
+	switch {
57
+	case ctx.ADD() != nil:
58
+		return bpf.ALUOpAdd
59
+	case ctx.SUB() != nil:
60
+		return bpf.ALUOpSub
61
+	case ctx.MUL() != nil:
62
+		return bpf.ALUOpMul
63
+	case ctx.DIV() != nil:
64
+		return bpf.ALUOpDiv
65
+	case ctx.MOD() != nil:
66
+		return bpf.ALUOpMod
67
+	case ctx.AND() != nil:
68
+		return bpf.ALUOpAnd
69
+	case ctx.OR() != nil:
70
+		return bpf.ALUOpOr
71
+	case ctx.XOR() != nil:
72
+		return bpf.ALUOpXor
73
+	case ctx.LSH() != nil:
74
+		return bpf.ALUOpShiftLeft
75
+	case ctx.RSH() != nil:
76
+		return bpf.ALUOpShiftRight
77
+	default:
78
+		return bpf.ALUOp(0)
79
+	}
80
+}
81
+
82
+func parseJumpCondition(ctx *parser.JumpConditionalOperatorContext) bpf.JumpTest {
83
+	switch {
84
+	case ctx.JEQ() != nil:
85
+		return bpf.JumpEqual
86
+	case ctx.JNE() != nil:
87
+		return bpf.JumpNotEqual
88
+	case ctx.JGT() != nil:
89
+		return bpf.JumpGreaterThan
90
+	case ctx.JLT() != nil:
91
+		return bpf.JumpLessThan
92
+	case ctx.JGE() != nil:
93
+		return bpf.JumpGreaterOrEqual
94
+	case ctx.JLE() != nil:
95
+		return bpf.JumpLessOrEqual
96
+	case ctx.JSE() != nil:
97
+		return bpf.JumpBitsSet
98
+	default:
99
+		return math.MaxUint16
100
+	}
101
+}
102
+
103
+func parseExtension(ext string) bpf.Extension {
104
+	switch ext {
105
+	case "len": // skb->len
106
+		return bpf.ExtLen
107
+	case "proto": // skb->protocol
108
+		return bpf.ExtProto
109
+	case "type": // skb->pkt_type
110
+		return bpf.ExtType
111
+	case "poff": // Payload start offset
112
+		return bpf.ExtPayloadOffset
113
+	case "ifidx": // skb->dev->ifindex
114
+		return bpf.ExtInterfaceIndex
115
+	case "nla": // Netlink attribute of type X with offset A
116
+		return bpf.ExtNetlinkAttr
117
+	case "nlan": // Nested Netlink attribute of type X with offset A
118
+		return bpf.ExtNetlinkAttrNested
119
+	case "mark": // skb->mark
120
+		return bpf.ExtMark
121
+	case "queue": // skb->queue_mapping
122
+		return bpf.ExtQueue
123
+	case "hatype": // skb->dev->type
124
+		return bpf.ExtLinkLayerType
125
+	case "rxhash": // skb->hash
126
+		return bpf.ExtRXHash
127
+	case "cpu": // raw_smp_processor_id()
128
+		return bpf.ExtCPUID
129
+	case "vlan_tci": // skb_vlan_tag_get(skb)
130
+		return bpf.ExtVLANTag
131
+	case "vlan_avail": // skb_vlan_tag_present(skb)
132
+		return bpf.ExtVLANTagPresent
133
+	case "vlan_tpid": // skb->vlan_proto
134
+		return bpf.ExtVLANProto
135
+	case "rand": // prandom_u32()
136
+		return bpf.ExtRand
137
+	default:
138
+		return 0
139
+	}
140
+}

+ 205
- 0
parser/BPF.g4 View File

@@ -0,0 +1,205 @@
1
+grammar BPF;
2
+
3
+program
4
+	: (labelDefinition | labelDefinition? instruction)+ EOF
5
+	;
6
+
7
+labelDefinition
8
+    : IDENTIFIER ':'
9
+    ;
10
+
11
+label : IDENTIFIER ;
12
+
13
+comment
14
+	: COMMENT
15
+	;
16
+
17
+instruction
18
+	: aluOperation
19
+	| jumpOperation
20
+	| jumpConditionalOperation
21
+	| loadOperation
22
+	| storeOperation
23
+	| simpleOperation
24
+	| returnOperation
25
+	;
26
+
27
+aluOperation
28
+	: aluOperator (literalNumber | registerX)
29
+	;
30
+
31
+aluOperator
32
+	: ADD
33
+	| SUB
34
+	| MUL
35
+	| DIV
36
+	| MOD
37
+	| AND
38
+	| OR
39
+	| XOR
40
+	| LSH
41
+	| RSH
42
+	;
43
+
44
+ADD : 'add' | 'ADD' ;
45
+SUB : 'sub' | 'SUB' ;
46
+MUL : 'mul' | 'MUL' ;
47
+DIV : 'div' | 'DIV' ;
48
+MOD : 'mod' | 'MOD' ;
49
+AND : 'and' | 'AND' ;
50
+OR  : 'or'  | 'OR'  ;
51
+XOR : 'xor' | 'XOR' ;
52
+LSH : 'lsh' | 'LSH' ;
53
+RSH : 'rsh' | 'RSH' ;
54
+
55
+jumpOperation
56
+	: jumpOperator number
57
+	;
58
+
59
+jumpOperator
60
+	: JA
61
+	;
62
+
63
+jumpConditionalOperation
64
+	: jumpConditionalOperator (literalNumber | registerX) ',' (ifTrue) (',' (ifFalse))?
65
+	;
66
+
67
+jumpConditionalOperator
68
+	: JEQ
69
+	| JNE
70
+	| JLT
71
+	| JLE
72
+	| JGT
73
+	| JGE
74
+	| JSE
75
+	;
76
+
77
+ifTrue
78
+	: number
79
+	| label
80
+	;
81
+
82
+ifFalse
83
+	: number
84
+	| label
85
+	;
86
+
87
+JA  : 'ja'  | 'JA'  ;
88
+JEQ : 'jeq' | 'JEQ' ;
89
+JNE : 'jne' | 'JNE' | 'jneq' | 'JNEQ' ;
90
+JLT : 'jlt' | 'JLT' ;
91
+JLE : 'jle' | 'JLE' ;
92
+JGT : 'jgt' | 'JGT' ;
93
+JGE : 'jge' | 'JGE' ;
94
+JSE : 'jse' | 'JSE' | 'jset' | 'JSET' ;
95
+
96
+loadOperation
97
+	: loadOperator (indirectX | absoluteNumber | registerR | extension)
98
+	;
99
+
100
+loadOperator
101
+	: LDA
102
+	| LDX
103
+	| LDB
104
+	| LDH
105
+	;
106
+
107
+LDA : 'lda' | 'LDA' | 'ld' | 'LD' ;
108
+LDX : 'ldx' | 'LDX' ;
109
+LDB : 'ldb' | 'LDB' ;
110
+LDH : 'ldh' | 'LDH' ;
111
+
112
+storeOperation
113
+	: storeOperator registerR
114
+	;
115
+
116
+storeOperator
117
+	: STA
118
+	| STX
119
+	;
120
+
121
+STA	: 'sta' | 'STA' | 'st' | 'ST' ;
122
+STX : 'stx' | 'STX' ;
123
+
124
+simpleOperation
125
+	: TAX
126
+	| TXA
127
+	| NEG
128
+	;
129
+
130
+TAX	: 'tax' | 'TAX' ;
131
+TXA : 'txa' | 'TXA' ;
132
+NEG : 'neg' | 'NEG' ;
133
+
134
+returnOperation
135
+	: RET (registerA | literalNumber)
136
+	;
137
+
138
+RET : 'ret' | 'RET' ;
139
+
140
+
141
+number
142
+   	: NUMBER
143
+   	;
144
+
145
+literalNumber
146
+	: ('#' number)
147
+	;
148
+
149
+indirectX
150
+	: ('[' 'x' '+' number ']')
151
+	;
152
+
153
+absoluteNumber
154
+	: ('[' number ']')
155
+	;
156
+
157
+registerA
158
+	: REGA
159
+	;
160
+
161
+registerX
162
+	: REGX
163
+	;
164
+
165
+registerR
166
+	: 'r' NUMBER
167
+	;
168
+
169
+extension
170
+	: IDENTIFIER
171
+	;
172
+
173
+/*
174
+NUMBER
175
+	: '0b' [01]+
176
+   	| '0x' [0-9a-fA-F]+
177
+   	| [0-9]+
178
+    | '-'? [0-9]+
179
+   	;
180
+*/
181
+NUMBER
182
+	: '0b' [01]+
183
+	| '0x' [0-9a-fA-F]+
184
+	| '-'? [0-9]+
185
+	;
186
+
187
+COMMENT
188
+   	: ';' ~ [\r\n]* -> skip
189
+   	;
190
+
191
+IDENTIFIER
192
+    : [._a-zA-Z]+
193
+    ;
194
+
195
+WHITESPACE
196
+   	: [ \t\r\n]+ -> skip
197
+   	;
198
+
199
+REGA
200
+	: 'a' | 'A'
201
+	;
202
+
203
+REGX
204
+	: 'x' | 'X'
205
+	;

+ 183
- 0
parser/bpf_base_listener.go View File

@@ -0,0 +1,183 @@
1
+// Code generated from parser/BPF.g4 by ANTLR 4.7.2. DO NOT EDIT.
2
+
3
+package parser // BPF
4
+import "github.com/antlr/antlr4/runtime/Go/antlr"
5
+
6
+// BaseBPFListener is a complete listener for a parse tree produced by BPFParser.
7
+type BaseBPFListener struct{}
8
+
9
+var _ BPFListener = &BaseBPFListener{}
10
+
11
+// VisitTerminal is called when a terminal node is visited.
12
+func (s *BaseBPFListener) VisitTerminal(node antlr.TerminalNode) {}
13
+
14
+// VisitErrorNode is called when an error node is visited.
15
+func (s *BaseBPFListener) VisitErrorNode(node antlr.ErrorNode) {}
16
+
17
+// EnterEveryRule is called when any rule is entered.
18
+func (s *BaseBPFListener) EnterEveryRule(ctx antlr.ParserRuleContext) {}
19
+
20
+// ExitEveryRule is called when any rule is exited.
21
+func (s *BaseBPFListener) ExitEveryRule(ctx antlr.ParserRuleContext) {}
22
+
23
+// EnterProgram is called when production program is entered.
24
+func (s *BaseBPFListener) EnterProgram(ctx *ProgramContext) {}
25
+
26
+// ExitProgram is called when production program is exited.
27
+func (s *BaseBPFListener) ExitProgram(ctx *ProgramContext) {}
28
+
29
+// EnterLabelDefinition is called when production labelDefinition is entered.
30
+func (s *BaseBPFListener) EnterLabelDefinition(ctx *LabelDefinitionContext) {}
31
+
32
+// ExitLabelDefinition is called when production labelDefinition is exited.
33
+func (s *BaseBPFListener) ExitLabelDefinition(ctx *LabelDefinitionContext) {}
34
+
35
+// EnterLabel is called when production label is entered.
36
+func (s *BaseBPFListener) EnterLabel(ctx *LabelContext) {}
37
+
38
+// ExitLabel is called when production label is exited.
39
+func (s *BaseBPFListener) ExitLabel(ctx *LabelContext) {}
40
+
41
+// EnterComment is called when production comment is entered.
42
+func (s *BaseBPFListener) EnterComment(ctx *CommentContext) {}
43
+
44
+// ExitComment is called when production comment is exited.
45
+func (s *BaseBPFListener) ExitComment(ctx *CommentContext) {}
46
+
47
+// EnterInstruction is called when production instruction is entered.
48
+func (s *BaseBPFListener) EnterInstruction(ctx *InstructionContext) {}
49
+
50
+// ExitInstruction is called when production instruction is exited.
51
+func (s *BaseBPFListener) ExitInstruction(ctx *InstructionContext) {}
52
+
53
+// EnterAluOperation is called when production aluOperation is entered.
54
+func (s *BaseBPFListener) EnterAluOperation(ctx *AluOperationContext) {}
55
+
56
+// ExitAluOperation is called when production aluOperation is exited.
57
+func (s *BaseBPFListener) ExitAluOperation(ctx *AluOperationContext) {}
58
+
59
+// EnterAluOperator is called when production aluOperator is entered.
60
+func (s *BaseBPFListener) EnterAluOperator(ctx *AluOperatorContext) {}
61
+
62
+// ExitAluOperator is called when production aluOperator is exited.
63
+func (s *BaseBPFListener) ExitAluOperator(ctx *AluOperatorContext) {}
64
+
65
+// EnterJumpOperation is called when production jumpOperation is entered.
66
+func (s *BaseBPFListener) EnterJumpOperation(ctx *JumpOperationContext) {}
67
+
68
+// ExitJumpOperation is called when production jumpOperation is exited.
69
+func (s *BaseBPFListener) ExitJumpOperation(ctx *JumpOperationContext) {}
70
+
71
+// EnterJumpOperator is called when production jumpOperator is entered.
72
+func (s *BaseBPFListener) EnterJumpOperator(ctx *JumpOperatorContext) {}
73
+
74
+// ExitJumpOperator is called when production jumpOperator is exited.
75
+func (s *BaseBPFListener) ExitJumpOperator(ctx *JumpOperatorContext) {}
76
+
77
+// EnterJumpConditionalOperation is called when production jumpConditionalOperation is entered.
78
+func (s *BaseBPFListener) EnterJumpConditionalOperation(ctx *JumpConditionalOperationContext) {}
79
+
80
+// ExitJumpConditionalOperation is called when production jumpConditionalOperation is exited.
81
+func (s *BaseBPFListener) ExitJumpConditionalOperation(ctx *JumpConditionalOperationContext) {}
82
+
83
+// EnterJumpConditionalOperator is called when production jumpConditionalOperator is entered.
84
+func (s *BaseBPFListener) EnterJumpConditionalOperator(ctx *JumpConditionalOperatorContext) {}
85
+
86
+// ExitJumpConditionalOperator is called when production jumpConditionalOperator is exited.
87
+func (s *BaseBPFListener) ExitJumpConditionalOperator(ctx *JumpConditionalOperatorContext) {}
88
+
89
+// EnterIfTrue is called when production ifTrue is entered.
90
+func (s *BaseBPFListener) EnterIfTrue(ctx *IfTrueContext) {}
91
+
92
+// ExitIfTrue is called when production ifTrue is exited.
93
+func (s *BaseBPFListener) ExitIfTrue(ctx *IfTrueContext) {}
94
+
95
+// EnterIfFalse is called when production ifFalse is entered.
96
+func (s *BaseBPFListener) EnterIfFalse(ctx *IfFalseContext) {}
97
+
98
+// ExitIfFalse is called when production ifFalse is exited.
99
+func (s *BaseBPFListener) ExitIfFalse(ctx *IfFalseContext) {}
100
+
101
+// EnterLoadOperation is called when production loadOperation is entered.
102
+func (s *BaseBPFListener) EnterLoadOperation(ctx *LoadOperationContext) {}
103
+
104
+// ExitLoadOperation is called when production loadOperation is exited.
105
+func (s *BaseBPFListener) ExitLoadOperation(ctx *LoadOperationContext) {}
106
+
107
+// EnterLoadOperator is called when production loadOperator is entered.
108
+func (s *BaseBPFListener) EnterLoadOperator(ctx *LoadOperatorContext) {}
109
+
110
+// ExitLoadOperator is called when production loadOperator is exited.
111
+func (s *BaseBPFListener) ExitLoadOperator(ctx *LoadOperatorContext) {}
112
+
113
+// EnterStoreOperation is called when production storeOperation is entered.
114
+func (s *BaseBPFListener) EnterStoreOperation(ctx *StoreOperationContext) {}
115
+
116
+// ExitStoreOperation is called when production storeOperation is exited.
117
+func (s *BaseBPFListener) ExitStoreOperation(ctx *StoreOperationContext) {}
118
+
119
+// EnterStoreOperator is called when production storeOperator is entered.
120
+func (s *BaseBPFListener) EnterStoreOperator(ctx *StoreOperatorContext) {}
121
+
122
+// ExitStoreOperator is called when production storeOperator is exited.
123
+func (s *BaseBPFListener) ExitStoreOperator(ctx *StoreOperatorContext) {}
124
+
125
+// EnterSimpleOperation is called when production simpleOperation is entered.
126
+func (s *BaseBPFListener) EnterSimpleOperation(ctx *SimpleOperationContext) {}
127
+
128
+// ExitSimpleOperation is called when production simpleOperation is exited.
129
+func (s *BaseBPFListener) ExitSimpleOperation(ctx *SimpleOperationContext) {}
130
+
131
+// EnterReturnOperation is called when production returnOperation is entered.
132
+func (s *BaseBPFListener) EnterReturnOperation(ctx *ReturnOperationContext) {}
133
+
134
+// ExitReturnOperation is called when production returnOperation is exited.
135
+func (s *BaseBPFListener) ExitReturnOperation(ctx *ReturnOperationContext) {}
136
+
137
+// EnterNumber is called when production number is entered.
138
+func (s *BaseBPFListener) EnterNumber(ctx *NumberContext) {}
139
+
140
+// ExitNumber is called when production number is exited.
141
+func (s *BaseBPFListener) ExitNumber(ctx *NumberContext) {}
142
+
143
+// EnterLiteralNumber is called when production literalNumber is entered.
144
+func (s *BaseBPFListener) EnterLiteralNumber(ctx *LiteralNumberContext) {}
145
+
146
+// ExitLiteralNumber is called when production literalNumber is exited.
147
+func (s *BaseBPFListener) ExitLiteralNumber(ctx *LiteralNumberContext) {}
148
+
149
+// EnterIndirectX is called when production indirectX is entered.
150
+func (s *BaseBPFListener) EnterIndirectX(ctx *IndirectXContext) {}
151
+
152
+// ExitIndirectX is called when production indirectX is exited.
153
+func (s *BaseBPFListener) ExitIndirectX(ctx *IndirectXContext) {}
154
+
155
+// EnterAbsoluteNumber is called when production absoluteNumber is entered.
156
+func (s *BaseBPFListener) EnterAbsoluteNumber(ctx *AbsoluteNumberContext) {}
157
+
158
+// ExitAbsoluteNumber is called when production absoluteNumber is exited.
159
+func (s *BaseBPFListener) ExitAbsoluteNumber(ctx *AbsoluteNumberContext) {}
160
+
161
+// EnterRegisterA is called when production registerA is entered.
162
+func (s *BaseBPFListener) EnterRegisterA(ctx *RegisterAContext) {}
163
+
164
+// ExitRegisterA is called when production registerA is exited.
165
+func (s *BaseBPFListener) ExitRegisterA(ctx *RegisterAContext) {}
166
+
167
+// EnterRegisterX is called when production registerX is entered.
168
+func (s *BaseBPFListener) EnterRegisterX(ctx *RegisterXContext) {}
169
+
170
+// ExitRegisterX is called when production registerX is exited.
171
+func (s *BaseBPFListener) ExitRegisterX(ctx *RegisterXContext) {}
172
+
173
+// EnterRegisterR is called when production registerR is entered.
174
+func (s *BaseBPFListener) EnterRegisterR(ctx *RegisterRContext) {}
175
+
176
+// ExitRegisterR is called when production registerR is exited.
177
+func (s *BaseBPFListener) ExitRegisterR(ctx *RegisterRContext) {}
178
+
179
+// EnterExtension is called when production extension is entered.
180
+func (s *BaseBPFListener) EnterExtension(ctx *ExtensionContext) {}
181
+
182
+// ExitExtension is called when production extension is exited.
183
+func (s *BaseBPFListener) ExitExtension(ctx *ExtensionContext) {}

+ 116
- 0
parser/bpf_base_visitor.go View File

@@ -0,0 +1,116 @@
1
+// Code generated from parser/BPF.g4 by ANTLR 4.7.2. DO NOT EDIT.
2
+
3
+package parser // BPF
4
+import "github.com/antlr/antlr4/runtime/Go/antlr"
5
+
6
+type BaseBPFVisitor struct {
7
+	*antlr.BaseParseTreeVisitor
8
+}
9
+
10
+func (v *BaseBPFVisitor) VisitProgram(ctx *ProgramContext) interface{} {
11
+	return v.VisitChildren(ctx)
12
+}
13
+
14
+func (v *BaseBPFVisitor) VisitLabelDefinition(ctx *LabelDefinitionContext) interface{} {
15
+	return v.VisitChildren(ctx)
16
+}
17
+
18
+func (v *BaseBPFVisitor) VisitLabel(ctx *LabelContext) interface{} {
19
+	return v.VisitChildren(ctx)
20
+}
21
+
22
+func (v *BaseBPFVisitor) VisitComment(ctx *CommentContext) interface{} {
23
+	return v.VisitChildren(ctx)
24
+}
25
+
26
+func (v *BaseBPFVisitor) VisitInstruction(ctx *InstructionContext) interface{} {
27
+	return v.VisitChildren(ctx)
28
+}
29
+
30
+func (v *BaseBPFVisitor) VisitAluOperation(ctx *AluOperationContext) interface{} {
31
+	return v.VisitChildren(ctx)
32
+}
33
+
34
+func (v *BaseBPFVisitor) VisitAluOperator(ctx *AluOperatorContext) interface{} {
35
+	return v.VisitChildren(ctx)
36
+}
37
+
38
+func (v *BaseBPFVisitor) VisitJumpOperation(ctx *JumpOperationContext) interface{} {
39
+	return v.VisitChildren(ctx)
40
+}
41
+
42
+func (v *BaseBPFVisitor) VisitJumpOperator(ctx *JumpOperatorContext) interface{} {
43
+	return v.VisitChildren(ctx)
44
+}
45
+
46
+func (v *BaseBPFVisitor) VisitJumpConditionalOperation(ctx *JumpConditionalOperationContext) interface{} {
47
+	return v.VisitChildren(ctx)
48
+}
49
+
50
+func (v *BaseBPFVisitor) VisitJumpConditionalOperator(ctx *JumpConditionalOperatorContext) interface{} {
51
+	return v.VisitChildren(ctx)
52
+}
53
+
54
+func (v *BaseBPFVisitor) VisitIfTrue(ctx *IfTrueContext) interface{} {
55
+	return v.VisitChildren(ctx)
56
+}
57
+
58
+func (v *BaseBPFVisitor) VisitIfFalse(ctx *IfFalseContext) interface{} {
59
+	return v.VisitChildren(ctx)
60
+}
61
+
62
+func (v *BaseBPFVisitor) VisitLoadOperation(ctx *LoadOperationContext) interface{} {
63
+	return v.VisitChildren(ctx)
64
+}
65
+
66
+func (v *BaseBPFVisitor) VisitLoadOperator(ctx *LoadOperatorContext) interface{} {
67
+	return v.VisitChildren(ctx)
68
+}
69
+
70
+func (v *BaseBPFVisitor) VisitStoreOperation(ctx *StoreOperationContext) interface{} {
71
+	return v.VisitChildren(ctx)
72
+}
73
+
74
+func (v *BaseBPFVisitor) VisitStoreOperator(ctx *StoreOperatorContext) interface{} {
75
+	return v.VisitChildren(ctx)
76
+}
77
+
78
+func (v *BaseBPFVisitor) VisitSimpleOperation(ctx *SimpleOperationContext) interface{} {
79
+	return v.VisitChildren(ctx)
80
+}
81
+
82
+func (v *BaseBPFVisitor) VisitReturnOperation(ctx *ReturnOperationContext) interface{} {
83
+	return v.VisitChildren(ctx)
84
+}
85
+
86
+func (v *BaseBPFVisitor) VisitNumber(ctx *NumberContext) interface{} {
87
+	return v.VisitChildren(ctx)
88
+}
89
+
90
+func (v *BaseBPFVisitor) VisitLiteralNumber(ctx *LiteralNumberContext) interface{} {
91
+	return v.VisitChildren(ctx)
92
+}
93
+
94
+func (v *BaseBPFVisitor) VisitIndirectX(ctx *IndirectXContext) interface{} {
95
+	return v.VisitChildren(ctx)
96
+}
97
+
98
+func (v *BaseBPFVisitor) VisitAbsoluteNumber(ctx *AbsoluteNumberContext) interface{} {
99
+	return v.VisitChildren(ctx)
100
+}
101
+
102
+func (v *BaseBPFVisitor) VisitRegisterA(ctx *RegisterAContext) interface{} {
103
+	return v.VisitChildren(ctx)
104
+}
105
+
106
+func (v *BaseBPFVisitor) VisitRegisterX(ctx *RegisterXContext) interface{} {
107
+	return v.VisitChildren(ctx)
108
+}
109
+
110
+func (v *BaseBPFVisitor) VisitRegisterR(ctx *RegisterRContext) interface{} {
111
+	return v.VisitChildren(ctx)
112
+}
113
+
114
+func (v *BaseBPFVisitor) VisitExtension(ctx *ExtensionContext) interface{} {
115
+	return v.VisitChildren(ctx)
116
+}

+ 313
- 0
parser/bpf_lexer.go View File

@@ -0,0 +1,313 @@
1
+// Code generated from parser/BPF.g4 by ANTLR 4.7.2. DO NOT EDIT.
2
+
3
+package parser
4
+
5
+import (
6
+	"fmt"
7
+	"unicode"
8
+
9
+	"github.com/antlr/antlr4/runtime/Go/antlr"
10
+)
11
+
12
+// Suppress unused import error
13
+var _ = fmt.Printf
14
+var _ = unicode.IsLetter
15
+
16
+var serializedLexerAtn = []uint16{
17
+	3, 24715, 42794, 33075, 47597, 16764, 15335, 30598, 22884, 2, 44, 398,
18
+	8, 1, 4, 2, 9, 2, 4, 3, 9, 3, 4, 4, 9, 4, 4, 5, 9, 5, 4, 6, 9, 6, 4, 7,
19
+	9, 7, 4, 8, 9, 8, 4, 9, 9, 9, 4, 10, 9, 10, 4, 11, 9, 11, 4, 12, 9, 12,
20
+	4, 13, 9, 13, 4, 14, 9, 14, 4, 15, 9, 15, 4, 16, 9, 16, 4, 17, 9, 17, 4,
21
+	18, 9, 18, 4, 19, 9, 19, 4, 20, 9, 20, 4, 21, 9, 21, 4, 22, 9, 22, 4, 23,
22
+	9, 23, 4, 24, 9, 24, 4, 25, 9, 25, 4, 26, 9, 26, 4, 27, 9, 27, 4, 28, 9,
23
+	28, 4, 29, 9, 29, 4, 30, 9, 30, 4, 31, 9, 31, 4, 32, 9, 32, 4, 33, 9, 33,
24
+	4, 34, 9, 34, 4, 35, 9, 35, 4, 36, 9, 36, 4, 37, 9, 37, 4, 38, 9, 38, 4,
25
+	39, 9, 39, 4, 40, 9, 40, 4, 41, 9, 41, 4, 42, 9, 42, 4, 43, 9, 43, 3, 2,
26
+	3, 2, 3, 3, 3, 3, 3, 4, 3, 4, 3, 5, 3, 5, 3, 6, 3, 6, 3, 7, 3, 7, 3, 8,
27
+	3, 8, 3, 9, 3, 9, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 3, 10, 5, 10, 110,
28
+	10, 10, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 3, 11, 5, 11, 118, 10, 11, 3,
29
+	12, 3, 12, 3, 12, 3, 12, 3, 12, 3, 12, 5, 12, 126, 10, 12, 3, 13, 3, 13,
30
+	3, 13, 3, 13, 3, 13, 3, 13, 5, 13, 134, 10, 13, 3, 14, 3, 14, 3, 14, 3,
31
+	14, 3, 14, 3, 14, 5, 14, 142, 10, 14, 3, 15, 3, 15, 3, 15, 3, 15, 3, 15,
32
+	3, 15, 5, 15, 150, 10, 15, 3, 16, 3, 16, 3, 16, 3, 16, 5, 16, 156, 10,
33
+	16, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 3, 17, 5, 17, 164, 10, 17, 3, 18,
34
+	3, 18, 3, 18, 3, 18, 3, 18, 3, 18, 5, 18, 172, 10, 18, 3, 19, 3, 19, 3,
35
+	19, 3, 19, 3, 19, 3, 19, 5, 19, 180, 10, 19, 3, 20, 3, 20, 3, 20, 3, 20,
36
+	5, 20, 186, 10, 20, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 3, 21, 5, 21, 194,
37
+	10, 21, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 3, 22,
38
+	3, 22, 3, 22, 3, 22, 3, 22, 3, 22, 5, 22, 210, 10, 22, 3, 23, 3, 23, 3,
39
+	23, 3, 23, 3, 23, 3, 23, 5, 23, 218, 10, 23, 3, 24, 3, 24, 3, 24, 3, 24,
40
+	3, 24, 3, 24, 5, 24, 226, 10, 24, 3, 25, 3, 25, 3, 25, 3, 25, 3, 25, 3,
41
+	25, 5, 25, 234, 10, 25, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 3, 26, 5, 26,
42
+	242, 10, 26, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 3,
43
+	27, 3, 27, 3, 27, 3, 27, 3, 27, 3, 27, 5, 27, 258, 10, 27, 3, 28, 3, 28,
44
+	3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 3, 28, 5, 28, 270, 10,
45
+	28, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 3, 29, 5, 29, 278, 10, 29, 3, 30,
46
+	3, 30, 3, 30, 3, 30, 3, 30, 3, 30, 5, 30, 286, 10, 30, 3, 31, 3, 31, 3,
47
+	31, 3, 31, 3, 31, 3, 31, 5, 31, 294, 10, 31, 3, 32, 3, 32, 3, 32, 3, 32,
48
+	3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 3, 32, 5, 32, 306, 10, 32, 3, 33, 3,
49
+	33, 3, 33, 3, 33, 3, 33, 3, 33, 5, 33, 314, 10, 33, 3, 34, 3, 34, 3, 34,
50
+	3, 34, 3, 34, 3, 34, 5, 34, 322, 10, 34, 3, 35, 3, 35, 3, 35, 3, 35, 3,
51
+	35, 3, 35, 5, 35, 330, 10, 35, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36, 3, 36,
52
+	5, 36, 338, 10, 36, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 3, 37, 5, 37, 346,
53
+	10, 37, 3, 38, 3, 38, 3, 38, 3, 38, 6, 38, 352, 10, 38, 13, 38, 14, 38,
54
+	353, 3, 38, 3, 38, 3, 38, 3, 38, 6, 38, 360, 10, 38, 13, 38, 14, 38, 361,
55
+	3, 38, 5, 38, 365, 10, 38, 3, 38, 6, 38, 368, 10, 38, 13, 38, 14, 38, 369,
56
+	5, 38, 372, 10, 38, 3, 39, 3, 39, 7, 39, 376, 10, 39, 12, 39, 14, 39, 379,
57
+	11, 39, 3, 39, 3, 39, 3, 40, 6, 40, 384, 10, 40, 13, 40, 14, 40, 385, 3,
58
+	41, 6, 41, 389, 10, 41, 13, 41, 14, 41, 390, 3, 41, 3, 41, 3, 42, 3, 42,
59
+	3, 43, 3, 43, 2, 2, 44, 3, 3, 5, 4, 7, 5, 9, 6, 11, 7, 13, 8, 15, 9, 17,
60
+	10, 19, 11, 21, 12, 23, 13, 25, 14, 27, 15, 29, 16, 31, 17, 33, 18, 35,
61
+	19, 37, 20, 39, 21, 41, 22, 43, 23, 45, 24, 47, 25, 49, 26, 51, 27, 53,
62
+	28, 55, 29, 57, 30, 59, 31, 61, 32, 63, 33, 65, 34, 67, 35, 69, 36, 71,
63
+	37, 73, 38, 75, 39, 77, 40, 79, 41, 81, 42, 83, 43, 85, 44, 3, 2, 10, 3,
64
+	2, 50, 51, 5, 2, 50, 59, 67, 72, 99, 104, 3, 2, 50, 59, 4, 2, 12, 12, 15,
65
+	15, 6, 2, 48, 48, 67, 92, 97, 97, 99, 124, 5, 2, 11, 12, 15, 15, 34, 34,
66
+	4, 2, 67, 67, 99, 99, 4, 2, 90, 90, 122, 122, 2, 442, 2, 3, 3, 2, 2, 2,
67
+	2, 5, 3, 2, 2, 2, 2, 7, 3, 2, 2, 2, 2, 9, 3, 2, 2, 2, 2, 11, 3, 2, 2, 2,
68
+	2, 13, 3, 2, 2, 2, 2, 15, 3, 2, 2, 2, 2, 17, 3, 2, 2, 2, 2, 19, 3, 2, 2,
69
+	2, 2, 21, 3, 2, 2, 2, 2, 23, 3, 2, 2, 2, 2, 25, 3, 2, 2, 2, 2, 27, 3, 2,
70
+	2, 2, 2, 29, 3, 2, 2, 2, 2, 31, 3, 2, 2, 2, 2, 33, 3, 2, 2, 2, 2, 35, 3,
71
+	2, 2, 2, 2, 37, 3, 2, 2, 2, 2, 39, 3, 2, 2, 2, 2, 41, 3, 2, 2, 2, 2, 43,
72
+	3, 2, 2, 2, 2, 45, 3, 2, 2, 2, 2, 47, 3, 2, 2, 2, 2, 49, 3, 2, 2, 2, 2,
73
+	51, 3, 2, 2, 2, 2, 53, 3, 2, 2, 2, 2, 55, 3, 2, 2, 2, 2, 57, 3, 2, 2, 2,
74
+	2, 59, 3, 2, 2, 2, 2, 61, 3, 2, 2, 2, 2, 63, 3, 2, 2, 2, 2, 65, 3, 2, 2,
75
+	2, 2, 67, 3, 2, 2, 2, 2, 69, 3, 2, 2, 2, 2, 71, 3, 2, 2, 2, 2, 73, 3, 2,
76
+	2, 2, 2, 75, 3, 2, 2, 2, 2, 77, 3, 2, 2, 2, 2, 79, 3, 2, 2, 2, 2, 81, 3,
77
+	2, 2, 2, 2, 83, 3, 2, 2, 2, 2, 85, 3, 2, 2, 2, 3, 87, 3, 2, 2, 2, 5, 89,
78
+	3, 2, 2, 2, 7, 91, 3, 2, 2, 2, 9, 93, 3, 2, 2, 2, 11, 95, 3, 2, 2, 2, 13,
79
+	97, 3, 2, 2, 2, 15, 99, 3, 2, 2, 2, 17, 101, 3, 2, 2, 2, 19, 109, 3, 2,
80
+	2, 2, 21, 117, 3, 2, 2, 2, 23, 125, 3, 2, 2, 2, 25, 133, 3, 2, 2, 2, 27,
81
+	141, 3, 2, 2, 2, 29, 149, 3, 2, 2, 2, 31, 155, 3, 2, 2, 2, 33, 163, 3,
82
+	2, 2, 2, 35, 171, 3, 2, 2, 2, 37, 179, 3, 2, 2, 2, 39, 185, 3, 2, 2, 2,
83
+	41, 193, 3, 2, 2, 2, 43, 209, 3, 2, 2, 2, 45, 217, 3, 2, 2, 2, 47, 225,
84
+	3, 2, 2, 2, 49, 233, 3, 2, 2, 2, 51, 241, 3, 2, 2, 2, 53, 257, 3, 2, 2,
85
+	2, 55, 269, 3, 2, 2, 2, 57, 277, 3, 2, 2, 2, 59, 285, 3, 2, 2, 2, 61, 293,
86
+	3, 2, 2, 2, 63, 305, 3, 2, 2, 2, 65, 313, 3, 2, 2, 2, 67, 321, 3, 2, 2,
87
+	2, 69, 329, 3, 2, 2, 2, 71, 337, 3, 2, 2, 2, 73, 345, 3, 2, 2, 2, 75, 371,
88
+	3, 2, 2, 2, 77, 373, 3, 2, 2, 2, 79, 383, 3, 2, 2, 2, 81, 388, 3, 2, 2,
89
+	2, 83, 394, 3, 2, 2, 2, 85, 396, 3, 2, 2, 2, 87, 88, 7, 60, 2, 2, 88, 4,
90
+	3, 2, 2, 2, 89, 90, 7, 46, 2, 2, 90, 6, 3, 2, 2, 2, 91, 92, 7, 37, 2, 2,
91
+	92, 8, 3, 2, 2, 2, 93, 94, 7, 93, 2, 2, 94, 10, 3, 2, 2, 2, 95, 96, 7,
92
+	122, 2, 2, 96, 12, 3, 2, 2, 2, 97, 98, 7, 45, 2, 2, 98, 14, 3, 2, 2, 2,
93
+	99, 100, 7, 95, 2, 2, 100, 16, 3, 2, 2, 2, 101, 102, 7, 116, 2, 2, 102,
94
+	18, 3, 2, 2, 2, 103, 104, 7, 99, 2, 2, 104, 105, 7, 102, 2, 2, 105, 110,
95
+	7, 102, 2, 2, 106, 107, 7, 67, 2, 2, 107, 108, 7, 70, 2, 2, 108, 110, 7,
96
+	70, 2, 2, 109, 103, 3, 2, 2, 2, 109, 106, 3, 2, 2, 2, 110, 20, 3, 2, 2,
97
+	2, 111, 112, 7, 117, 2, 2, 112, 113, 7, 119, 2, 2, 113, 118, 7, 100, 2,
98
+	2, 114, 115, 7, 85, 2, 2, 115, 116, 7, 87, 2, 2, 116, 118, 7, 68, 2, 2,
99
+	117, 111, 3, 2, 2, 2, 117, 114, 3, 2, 2, 2, 118, 22, 3, 2, 2, 2, 119, 120,
100
+	7, 111, 2, 2, 120, 121, 7, 119, 2, 2, 121, 126, 7, 110, 2, 2, 122, 123,
101
+	7, 79, 2, 2, 123, 124, 7, 87, 2, 2, 124, 126, 7, 78, 2, 2, 125, 119, 3,
102
+	2, 2, 2, 125, 122, 3, 2, 2, 2, 126, 24, 3, 2, 2, 2, 127, 128, 7, 102, 2,
103
+	2, 128, 129, 7, 107, 2, 2, 129, 134, 7, 120, 2, 2, 130, 131, 7, 70, 2,
104
+	2, 131, 132, 7, 75, 2, 2, 132, 134, 7, 88, 2, 2, 133, 127, 3, 2, 2, 2,
105
+	133, 130, 3, 2, 2, 2, 134, 26, 3, 2, 2, 2, 135, 136, 7, 111, 2, 2, 136,
106
+	137, 7, 113, 2, 2, 137, 142, 7, 102, 2, 2, 138, 139, 7, 79, 2, 2, 139,
107
+	140, 7, 81, 2, 2, 140, 142, 7, 70, 2, 2, 141, 135, 3, 2, 2, 2, 141, 138,
108
+	3, 2, 2, 2, 142, 28, 3, 2, 2, 2, 143, 144, 7, 99, 2, 2, 144, 145, 7, 112,
109
+	2, 2, 145, 150, 7, 102, 2, 2, 146, 147, 7, 67, 2, 2, 147, 148, 7, 80, 2,
110
+	2, 148, 150, 7, 70, 2, 2, 149, 143, 3, 2, 2, 2, 149, 146, 3, 2, 2, 2, 150,
111
+	30, 3, 2, 2, 2, 151, 152, 7, 113, 2, 2, 152, 156, 7, 116, 2, 2, 153, 154,
112
+	7, 81, 2, 2, 154, 156, 7, 84, 2, 2, 155, 151, 3, 2, 2, 2, 155, 153, 3,
113
+	2, 2, 2, 156, 32, 3, 2, 2, 2, 157, 158, 7, 122, 2, 2, 158, 159, 7, 113,
114
+	2, 2, 159, 164, 7, 116, 2, 2, 160, 161, 7, 90, 2, 2, 161, 162, 7, 81, 2,
115
+	2, 162, 164, 7, 84, 2, 2, 163, 157, 3, 2, 2, 2, 163, 160, 3, 2, 2, 2, 164,
116
+	34, 3, 2, 2, 2, 165, 166, 7, 110, 2, 2, 166, 167, 7, 117, 2, 2, 167, 172,
117
+	7, 106, 2, 2, 168, 169, 7, 78, 2, 2, 169, 170, 7, 85, 2, 2, 170, 172, 7,
118
+	74, 2, 2, 171, 165, 3, 2, 2, 2, 171, 168, 3, 2, 2, 2, 172, 36, 3, 2, 2,
119
+	2, 173, 174, 7, 116, 2, 2, 174, 175, 7, 117, 2, 2, 175, 180, 7, 106, 2,
120
+	2, 176, 177, 7, 84, 2, 2, 177, 178, 7, 85, 2, 2, 178, 180, 7, 74, 2, 2,
121
+	179, 173, 3, 2, 2, 2, 179, 176, 3, 2, 2, 2, 180, 38, 3, 2, 2, 2, 181, 182,
122
+	7, 108, 2, 2, 182, 186, 7, 99, 2, 2, 183, 184, 7, 76, 2, 2, 184, 186, 7,
123
+	67, 2, 2, 185, 181, 3, 2, 2, 2, 185, 183, 3, 2, 2, 2, 186, 40, 3, 2, 2,
124
+	2, 187, 188, 7, 108, 2, 2, 188, 189, 7, 103, 2, 2, 189, 194, 7, 115, 2,
125
+	2, 190, 191, 7, 76, 2, 2, 191, 192, 7, 71, 2, 2, 192, 194, 7, 83, 2, 2,
126
+	193, 187, 3, 2, 2, 2, 193, 190, 3, 2, 2, 2, 194, 42, 3, 2, 2, 2, 195, 196,
127
+	7, 108, 2, 2, 196, 197, 7, 112, 2, 2, 197, 210, 7, 103, 2, 2, 198, 199,
128
+	7, 76, 2, 2, 199, 200, 7, 80, 2, 2, 200, 210, 7, 71, 2, 2, 201, 202, 7,
129
+	108, 2, 2, 202, 203, 7, 112, 2, 2, 203, 204, 7, 103, 2, 2, 204, 210, 7,
130
+	115, 2, 2, 205, 206, 7, 76, 2, 2, 206, 207, 7, 80, 2, 2, 207, 208, 7, 71,
131
+	2, 2, 208, 210, 7, 83, 2, 2, 209, 195, 3, 2, 2, 2, 209, 198, 3, 2, 2, 2,
132
+	209, 201, 3, 2, 2, 2, 209, 205, 3, 2, 2, 2, 210, 44, 3, 2, 2, 2, 211, 212,
133
+	7, 108, 2, 2, 212, 213, 7, 110, 2, 2, 213, 218, 7, 118, 2, 2, 214, 215,
134
+	7, 76, 2, 2, 215, 216, 7, 78, 2, 2, 216, 218, 7, 86, 2, 2, 217, 211, 3,
135
+	2, 2, 2, 217, 214, 3, 2, 2, 2, 218, 46, 3, 2, 2, 2, 219, 220, 7, 108, 2,
136
+	2, 220, 221, 7, 110, 2, 2, 221, 226, 7, 103, 2, 2, 222, 223, 7, 76, 2,
137
+	2, 223, 224, 7, 78, 2, 2, 224, 226, 7, 71, 2, 2, 225, 219, 3, 2, 2, 2,
138
+	225, 222, 3, 2, 2, 2, 226, 48, 3, 2, 2, 2, 227, 228, 7, 108, 2, 2, 228,
139
+	229, 7, 105, 2, 2, 229, 234, 7, 118, 2, 2, 230, 231, 7, 76, 2, 2, 231,
140
+	232, 7, 73, 2, 2, 232, 234, 7, 86, 2, 2, 233, 227, 3, 2, 2, 2, 233, 230,
141
+	3, 2, 2, 2, 234, 50, 3, 2, 2, 2, 235, 236, 7, 108, 2, 2, 236, 237, 7, 105,
142
+	2, 2, 237, 242, 7, 103, 2, 2, 238, 239, 7, 76, 2, 2, 239, 240, 7, 73, 2,
143
+	2, 240, 242, 7, 71, 2, 2, 241, 235, 3, 2, 2, 2, 241, 238, 3, 2, 2, 2, 242,
144
+	52, 3, 2, 2, 2, 243, 244, 7, 108, 2, 2, 244, 245, 7, 117, 2, 2, 245, 258,
145
+	7, 103, 2, 2, 246, 247, 7, 76, 2, 2, 247, 248, 7, 85, 2, 2, 248, 258, 7,
146
+	71, 2, 2, 249, 250, 7, 108, 2, 2, 250, 251, 7, 117, 2, 2, 251, 252, 7,
147
+	103, 2, 2, 252, 258, 7, 118, 2, 2, 253, 254, 7, 76, 2, 2, 254, 255, 7,
148
+	85, 2, 2, 255, 256, 7, 71, 2, 2, 256, 258, 7, 86, 2, 2, 257, 243, 3, 2,
149
+	2, 2, 257, 246, 3, 2, 2, 2, 257, 249, 3, 2, 2, 2, 257, 253, 3, 2, 2, 2,
150
+	258, 54, 3, 2, 2, 2, 259, 260, 7, 110, 2, 2, 260, 261, 7, 102, 2, 2, 261,
151
+	270, 7, 99, 2, 2, 262, 263, 7, 78, 2, 2, 263, 264, 7, 70, 2, 2, 264, 270,
152
+	7, 67, 2, 2, 265, 266, 7, 110, 2, 2, 266, 270, 7, 102, 2, 2, 267, 268,
153
+	7, 78, 2, 2, 268, 270, 7, 70, 2, 2, 269, 259, 3, 2, 2, 2, 269, 262, 3,
154
+	2, 2, 2, 269, 265, 3, 2, 2, 2, 269, 267, 3, 2, 2, 2, 270, 56, 3, 2, 2,
155
+	2, 271, 272, 7, 110, 2, 2, 272, 273, 7, 102, 2, 2, 273, 278, 7, 122, 2,
156
+	2, 274, 275, 7, 78, 2, 2, 275, 276, 7, 70, 2, 2, 276, 278, 7, 90, 2, 2,
157
+	277, 271, 3, 2, 2, 2, 277, 274, 3, 2, 2, 2, 278, 58, 3, 2, 2, 2, 279, 280,
158
+	7, 110, 2, 2, 280, 281, 7, 102, 2, 2, 281, 286, 7, 100, 2, 2, 282, 283,
159
+	7, 78, 2, 2, 283, 284, 7, 70, 2, 2, 284, 286, 7, 68, 2, 2, 285, 279, 3,
160
+	2, 2, 2, 285, 282, 3, 2, 2, 2, 286, 60, 3, 2, 2, 2, 287, 288, 7, 110, 2,
161
+	2, 288, 289, 7, 102, 2, 2, 289, 294, 7, 106, 2, 2, 290, 291, 7, 78, 2,
162
+	2, 291, 292, 7, 70, 2, 2, 292, 294, 7, 74, 2, 2, 293, 287, 3, 2, 2, 2,
163
+	293, 290, 3, 2, 2, 2, 294, 62, 3, 2, 2, 2, 295, 296, 7, 117, 2, 2, 296,
164
+	297, 7, 118, 2, 2, 297, 306, 7, 99, 2, 2, 298, 299, 7, 85, 2, 2, 299, 300,
165
+	7, 86, 2, 2, 300, 306, 7, 67, 2, 2, 301, 302, 7, 117, 2, 2, 302, 306, 7,
166
+	118, 2, 2, 303, 304, 7, 85, 2, 2, 304, 306, 7, 86, 2, 2, 305, 295, 3, 2,
167
+	2, 2, 305, 298, 3, 2, 2, 2, 305, 301, 3, 2, 2, 2, 305, 303, 3, 2, 2, 2,
168
+	306, 64, 3, 2, 2, 2, 307, 308, 7, 117, 2, 2, 308, 309, 7, 118, 2, 2, 309,
169
+	314, 7, 122, 2, 2, 310, 311, 7, 85, 2, 2, 311, 312, 7, 86, 2, 2, 312, 314,
170
+	7, 90, 2, 2, 313, 307, 3, 2, 2, 2, 313, 310, 3, 2, 2, 2, 314, 66, 3, 2,
171
+	2, 2, 315, 316, 7, 118, 2, 2, 316, 317, 7, 99, 2, 2, 317, 322, 7, 122,
172
+	2, 2, 318, 319, 7, 86, 2, 2, 319, 320, 7, 67, 2, 2, 320, 322, 7, 90, 2,
173
+	2, 321, 315, 3, 2, 2, 2, 321, 318, 3, 2, 2, 2, 322, 68, 3, 2, 2, 2, 323,
174
+	324, 7, 118, 2, 2, 324, 325, 7, 122, 2, 2, 325, 330, 7, 99, 2, 2, 326,
175
+	327, 7, 86, 2, 2, 327, 328, 7, 90, 2, 2, 328, 330, 7, 67, 2, 2, 329, 323,
176
+	3, 2, 2, 2, 329, 326, 3, 2, 2, 2, 330, 70, 3, 2, 2, 2, 331, 332, 7, 112,
177
+	2, 2, 332, 333, 7, 103, 2, 2, 333, 338, 7, 105, 2, 2, 334, 335, 7, 80,
178
+	2, 2, 335, 336, 7, 71, 2, 2, 336, 338, 7, 73, 2, 2, 337, 331, 3, 2, 2,
179
+	2, 337, 334, 3, 2, 2, 2, 338, 72, 3, 2, 2, 2, 339, 340, 7, 116, 2, 2, 340,
180
+	341, 7, 103, 2, 2, 341, 346, 7, 118, 2, 2, 342, 343, 7, 84, 2, 2, 343,
181
+	344, 7, 71, 2, 2, 344, 346, 7, 86, 2, 2, 345, 339, 3, 2, 2, 2, 345, 342,
182
+	3, 2, 2, 2, 346, 74, 3, 2, 2, 2, 347, 348, 7, 50, 2, 2, 348, 349, 7, 100,
183
+	2, 2, 349, 351, 3, 2, 2, 2, 350, 352, 9, 2, 2, 2, 351, 350, 3, 2, 2, 2,
184
+	352, 353, 3, 2, 2, 2, 353, 351, 3, 2, 2, 2, 353, 354, 3, 2, 2, 2, 354,
185
+	372, 3, 2, 2, 2, 355, 356, 7, 50, 2, 2, 356, 357, 7, 122, 2, 2, 357, 359,
186
+	3, 2, 2, 2, 358, 360, 9, 3, 2, 2, 359, 358, 3, 2, 2, 2, 360, 361, 3, 2,
187
+	2, 2, 361, 359, 3, 2, 2, 2, 361, 362, 3, 2, 2, 2, 362, 372, 3, 2, 2, 2,
188
+	363, 365, 7, 47, 2, 2, 364, 363, 3, 2, 2, 2, 364, 365, 3, 2, 2, 2, 365,
189
+	367, 3, 2, 2, 2, 366, 368, 9, 4, 2, 2, 367, 366, 3, 2, 2, 2, 368, 369,
190
+	3, 2, 2, 2, 369, 367, 3, 2, 2, 2, 369, 370, 3, 2, 2, 2, 370, 372, 3, 2,
191
+	2, 2, 371, 347, 3, 2, 2, 2, 371, 355, 3, 2, 2, 2, 371, 364, 3, 2, 2, 2,
192
+	372, 76, 3, 2, 2, 2, 373, 377, 7, 61, 2, 2, 374, 376, 10, 5, 2, 2, 375,
193
+	374, 3, 2, 2, 2, 376, 379, 3, 2, 2, 2, 377, 375, 3, 2, 2, 2, 377, 378,
194
+	3, 2, 2, 2, 378, 380, 3, 2, 2, 2, 379, 377, 3, 2, 2, 2, 380, 381, 8, 39,
195
+	2, 2, 381, 78, 3, 2, 2, 2, 382, 384, 9, 6, 2, 2, 383, 382, 3, 2, 2, 2,
196
+	384, 385, 3, 2, 2, 2, 385, 383, 3, 2, 2, 2, 385, 386, 3, 2, 2, 2, 386,
197
+	80, 3, 2, 2, 2, 387, 389, 9, 7, 2, 2, 388, 387, 3, 2, 2, 2, 389, 390, 3,
198
+	2, 2, 2, 390, 388, 3, 2, 2, 2, 390, 391, 3, 2, 2, 2, 391, 392, 3, 2, 2,
199
+	2, 392, 393, 8, 41, 2, 2, 393, 82, 3, 2, 2, 2, 394, 395, 9, 8, 2, 2, 395,
200
+	84, 3, 2, 2, 2, 396, 397, 9, 9, 2, 2, 397, 86, 3, 2, 2, 2, 39, 2, 109,
201
+	117, 125, 133, 141, 149, 155, 163, 171, 179, 185, 193, 209, 217, 225, 233,
202
+	241, 257, 269, 277, 285, 293, 305, 313, 321, 329, 337, 345, 353, 361, 364,
203
+	369, 371, 377, 385, 390, 3, 8, 2, 2,
204
+}
205
+
206
+var lexerDeserializer = antlr.NewATNDeserializer(nil)
207
+var lexerAtn = lexerDeserializer.DeserializeFromUInt16(serializedLexerAtn)
208
+
209
+var lexerChannelNames = []string{
210
+	"DEFAULT_TOKEN_CHANNEL", "HIDDEN",
211
+}
212
+
213
+var lexerModeNames = []string{
214
+	"DEFAULT_MODE",
215
+}
216
+
217
+var lexerLiteralNames = []string{
218
+	"", "':'", "','", "'#'", "'['", "'x'", "'+'", "']'", "'r'",
219
+}
220
+
221
+var lexerSymbolicNames = []string{
222
+	"", "", "", "", "", "", "", "", "", "ADD", "SUB", "MUL", "DIV", "MOD",
223
+	"AND", "OR", "XOR", "LSH", "RSH", "JA", "JEQ", "JNE", "JLT", "JLE", "JGT",
224
+	"JGE", "JSE", "LDA", "LDX", "LDB", "LDH", "STA", "STX", "TAX", "TXA", "NEG",
225
+	"RET", "NUMBER", "COMMENT", "IDENTIFIER", "WHITESPACE", "REGA", "REGX",
226
+}
227
+
228
+var lexerRuleNames = []string{
229
+	"T__0", "T__1", "T__2", "T__3", "T__4", "T__5", "T__6", "T__7", "ADD",
230
+	"SUB", "MUL", "DIV", "MOD", "AND", "OR", "XOR", "LSH", "RSH", "JA", "JEQ",
231
+	"JNE", "JLT", "JLE", "JGT", "JGE", "JSE", "LDA", "LDX", "LDB", "LDH", "STA",
232
+	"STX", "TAX", "TXA", "NEG", "RET", "NUMBER", "COMMENT", "IDENTIFIER", "WHITESPACE",
233
+	"REGA", "REGX",
234
+}
235
+
236
+type BPFLexer struct {
237
+	*antlr.BaseLexer
238
+	channelNames []string
239
+	modeNames    []string
240
+	// TODO: EOF string
241
+}
242
+
243
+var lexerDecisionToDFA = make([]*antlr.DFA, len(lexerAtn.DecisionToState))
244
+
245
+func init() {
246
+	for index, ds := range lexerAtn.DecisionToState {
247
+		lexerDecisionToDFA[index] = antlr.NewDFA(ds, index)
248
+	}
249
+}
250
+
251
+func NewBPFLexer(input antlr.CharStream) *BPFLexer {
252
+
253
+	l := new(BPFLexer)
254
+
255
+	l.BaseLexer = antlr.NewBaseLexer(input)
256
+	l.Interpreter = antlr.NewLexerATNSimulator(l, lexerAtn, lexerDecisionToDFA, antlr.NewPredictionContextCache())
257
+
258
+	l.channelNames = lexerChannelNames
259
+	l.modeNames = lexerModeNames
260
+	l.RuleNames = lexerRuleNames
261
+	l.LiteralNames = lexerLiteralNames
262
+	l.SymbolicNames = lexerSymbolicNames
263
+	l.GrammarFileName = "BPF.g4"
264
+	// TODO: l.EOF = antlr.TokenEOF
265
+
266
+	return l
267
+}
268
+
269
+// BPFLexer tokens.
270
+const (
271
+	BPFLexerT__0       = 1
272
+	BPFLexerT__1       = 2
273
+	BPFLexerT__2       = 3
274
+	BPFLexerT__3       = 4
275
+	BPFLexerT__4       = 5
276
+	BPFLexerT__5       = 6
277
+	BPFLexerT__6       = 7
278
+	BPFLexerT__7       = 8
279
+	BPFLexerADD        = 9
280
+	BPFLexerSUB        = 10
281
+	BPFLexerMUL        = 11
282
+	BPFLexerDIV        = 12
283
+	BPFLexerMOD        = 13
284
+	BPFLexerAND        = 14
285
+	BPFLexerOR         = 15
286
+	BPFLexerXOR        = 16
287
+	BPFLexerLSH        = 17
288
+	BPFLexerRSH        = 18
289
+	BPFLexerJA         = 19
290
+	BPFLexerJEQ        = 20
291
+	BPFLexerJNE        = 21
292
+	BPFLexerJLT        = 22
293
+	BPFLexerJLE        = 23
294
+	BPFLexerJGT        = 24
295
+	BPFLexerJGE        = 25
296
+	BPFLexerJSE        = 26
297
+	BPFLexerLDA        = 27
298
+	BPFLexerLDX        = 28
299
+	BPFLexerLDB        = 29
300
+	BPFLexerLDH        = 30
301
+	BPFLexerSTA        = 31
302
+	BPFLexerSTX        = 32
303
+	BPFLexerTAX        = 33
304
+	BPFLexerTXA        = 34
305
+	BPFLexerNEG        = 35
306
+	BPFLexerRET        = 36
307
+	BPFLexerNUMBER     = 37
308
+	BPFLexerCOMMENT    = 38
309
+	BPFLexerIDENTIFIER = 39
310
+	BPFLexerWHITESPACE = 40
311
+	BPFLexerREGA       = 41
312
+	BPFLexerREGX       = 42
313
+)

+ 171
- 0
parser/bpf_listener.go View File

@@ -0,0 +1,171 @@
1
+// Code generated from parser/BPF.g4 by ANTLR 4.7.2. DO NOT EDIT.
2
+
3
+package parser // BPF
4
+import "github.com/antlr/antlr4/runtime/Go/antlr"
5
+
6
+// BPFListener is a complete listener for a parse tree produced by BPFParser.
7
+type BPFListener interface {
8
+	antlr.ParseTreeListener
9
+
10
+	// EnterProgram is called when entering the program production.
11
+	EnterProgram(c *ProgramContext)
12
+
13
+	// EnterLabelDefinition is called when entering the labelDefinition production.
14
+	EnterLabelDefinition(c *LabelDefinitionContext)
15
+
16
+	// EnterLabel is called when entering the label production.
17
+	EnterLabel(c *LabelContext)
18
+
19
+	// EnterComment is called when entering the comment production.
20
+	EnterComment(c *CommentContext)
21
+
22
+	// EnterInstruction is called when entering the instruction production.
23
+	EnterInstruction(c *InstructionContext)
24
+
25
+	// EnterAluOperation is called when entering the aluOperation production.
26
+	EnterAluOperation(c *AluOperationContext)
27
+
28
+	// EnterAluOperator is called when entering the aluOperator production.
29
+	EnterAluOperator(c *AluOperatorContext)
30
+
31
+	// EnterJumpOperation is called when entering the jumpOperation production.
32
+	EnterJumpOperation(c *JumpOperationContext)
33
+
34
+	// EnterJumpOperator is called when entering the jumpOperator production.
35
+	EnterJumpOperator(c *JumpOperatorContext)
36
+
37
+	// EnterJumpConditionalOperation is called when entering the jumpConditionalOperation production.
38
+	EnterJumpConditionalOperation(c *JumpConditionalOperationContext)
39
+
40
+	// EnterJumpConditionalOperator is called when entering the jumpConditionalOperator production.
41
+	EnterJumpConditionalOperator(c *JumpConditionalOperatorContext)
42
+
43
+	// EnterIfTrue is called when entering the ifTrue production.
44
+	EnterIfTrue(c *IfTrueContext)
45
+
46
+	// EnterIfFalse is called when entering the ifFalse production.
47
+	EnterIfFalse(c *IfFalseContext)
48
+
49
+	// EnterLoadOperation is called when entering the loadOperation production.
50
+	EnterLoadOperation(c *LoadOperationContext)
51
+
52
+	// EnterLoadOperator is called when entering the loadOperator production.
53
+	EnterLoadOperator(c *LoadOperatorContext)
54
+
55
+	// EnterStoreOperation is called when entering the storeOperation production.
56
+	EnterStoreOperation(c *StoreOperationContext)
57
+
58
+	// EnterStoreOperator is called when entering the storeOperator production.
59
+	EnterStoreOperator(c *StoreOperatorContext)
60
+
61
+	// EnterSimpleOperation is called when entering the simpleOperation production.
62
+	EnterSimpleOperation(c *SimpleOperationContext)
63
+
64
+	// EnterReturnOperation is called when entering the returnOperation production.
65
+	EnterReturnOperation(c *ReturnOperationContext)
66
+
67
+	// EnterNumber is called when entering the number production.
68
+	EnterNumber(c *NumberContext)
69
+
70
+	// EnterLiteralNumber is called when entering the literalNumber production.
71
+	EnterLiteralNumber(c *LiteralNumberContext)
72
+
73
+	// EnterIndirectX is called when entering the indirectX production.
74
+	EnterIndirectX(c *IndirectXContext)
75
+
76
+	// EnterAbsoluteNumber is called when entering the absoluteNumber production.
77
+	EnterAbsoluteNumber(c *AbsoluteNumberContext)
78
+
79
+	// EnterRegisterA is called when entering the registerA production.
80
+	EnterRegisterA(c *RegisterAContext)
81
+
82
+	// EnterRegisterX is called when entering the registerX production.
83
+	EnterRegisterX(c *RegisterXContext)
84
+
85
+	// EnterRegisterR is called when entering the registerR production.
86
+	EnterRegisterR(c *RegisterRContext)
87
+
88
+	// EnterExtension is called when entering the extension production.
89
+	EnterExtension(c *ExtensionContext)
90
+
91
+	// ExitProgram is called when exiting the program production.
92
+	ExitProgram(c *ProgramContext)
93
+
94
+	// ExitLabelDefinition is called when exiting the labelDefinition production.
95
+	ExitLabelDefinition(c *LabelDefinitionContext)
96
+
97
+	// ExitLabel is called when exiting the label production.
98
+	ExitLabel(c *LabelContext)
99
+
100
+	// ExitComment is called when exiting the comment production.
101
+	ExitComment(c *CommentContext)
102
+
103
+	// ExitInstruction is called when exiting the instruction production.
104
+	ExitInstruction(c *InstructionContext)
105
+
106
+	// ExitAluOperation is called when exiting the aluOperation production.
107
+	ExitAluOperation(c *AluOperationContext)
108
+
109
+	// ExitAluOperator is called when exiting the aluOperator production.
110
+	ExitAluOperator(c *AluOperatorContext)
111
+
112
+	// ExitJumpOperation is called when exiting the jumpOperation production.
113
+	ExitJumpOperation(c *JumpOperationContext)
114
+
115
+	// ExitJumpOperator is called when exiting the jumpOperator production.
116
+	ExitJumpOperator(c *JumpOperatorContext)
117
+
118
+	// ExitJumpConditionalOperation is called when exiting the jumpConditionalOperation production.
119
+	ExitJumpConditionalOperation(c *JumpConditionalOperationContext)
120
+
121
+	// ExitJumpConditionalOperator is called when exiting the jumpConditionalOperator production.
122
+	ExitJumpConditionalOperator(c *JumpConditionalOperatorContext)
123
+
124
+	// ExitIfTrue is called when exiting the ifTrue production.
125
+	ExitIfTrue(c *IfTrueContext)
126
+
127
+	// ExitIfFalse is called when exiting the ifFalse production.
128
+	ExitIfFalse(c *IfFalseContext)
129
+
130
+	// ExitLoadOperation is called when exiting the loadOperation production.
131
+	ExitLoadOperation(c *LoadOperationContext)
132
+
133
+	// ExitLoadOperator is called when exiting the loadOperator production.
134
+	ExitLoadOperator(c *LoadOperatorContext)
135
+
136
+	// ExitStoreOperation is called when exiting the storeOperation production.
137
+	ExitStoreOperation(c *StoreOperationContext)
138
+
139
+	// ExitStoreOperator is called when exiting the storeOperator production.
140
+	ExitStoreOperator(c *StoreOperatorContext)
141
+
142
+	// ExitSimpleOperation is called when exiting the simpleOperation production.
143
+	ExitSimpleOperation(c *SimpleOperationContext)
144
+
145
+	// ExitReturnOperation is called when exiting the returnOperation production.
146
+	ExitReturnOperation(c *ReturnOperationContext)
147
+
148
+	// ExitNumber is called when exiting the number production.
149
+	ExitNumber(c *NumberContext)
150
+
151
+	// ExitLiteralNumber is called when exiting the literalNumber production.
152
+	ExitLiteralNumber(c *LiteralNumberContext)
153
+
154
+	// ExitIndirectX is called when exiting the indirectX production.
155
+	ExitIndirectX(c *IndirectXContext)
156
+
157
+	// ExitAbsoluteNumber is called when exiting the absoluteNumber production.
158
+	ExitAbsoluteNumber(c *AbsoluteNumberContext)
159
+
160
+	// ExitRegisterA is called when exiting the registerA production.
161
+	ExitRegisterA(c *RegisterAContext)
162
+
163
+	// ExitRegisterX is called when exiting the registerX production.
164
+	ExitRegisterX(c *RegisterXContext)
165
+
166
+	// ExitRegisterR is called when exiting the registerR production.
167
+	ExitRegisterR(c *RegisterRContext)
168
+
169
+	// ExitExtension is called when exiting the extension production.
170
+	ExitExtension(c *ExtensionContext)
171
+}

+ 3667
- 0
parser/bpf_parser.go
File diff suppressed because it is too large
View File


+ 90
- 0
parser/bpf_visitor.go View File

@@ -0,0 +1,90 @@
1
+// Code generated from parser/BPF.g4 by ANTLR 4.7.2. DO NOT EDIT.
2
+
3
+package parser // BPF
4
+import "github.com/antlr/antlr4/runtime/Go/antlr"
5
+
6
+// A complete Visitor for a parse tree produced by BPFParser.
7
+type BPFVisitor interface {
8
+	antlr.ParseTreeVisitor
9
+
10
+	// Visit a parse tree produced by BPFParser#program.
11
+	VisitProgram(ctx *ProgramContext) interface{}
12
+
13
+	// Visit a parse tree produced by BPFParser#labelDefinition.
14
+	VisitLabelDefinition(ctx *LabelDefinitionContext) interface{}
15
+
16
+	// Visit a parse tree produced by BPFParser#label.
17
+	VisitLabel(ctx *LabelContext) interface{}
18
+
19
+	// Visit a parse tree produced by BPFParser#comment.
20
+	VisitComment(ctx *CommentContext) interface{}
21
+
22
+	// Visit a parse tree produced by BPFParser#instruction.
23
+	VisitInstruction(ctx *InstructionContext) interface{}
24
+
25
+	// Visit a parse tree produced by BPFParser#aluOperation.
26
+	VisitAluOperation(ctx *AluOperationContext) interface{}
27
+
28
+	// Visit a parse tree produced by BPFParser#aluOperator.
29
+	VisitAluOperator(ctx *AluOperatorContext) interface{}
30
+
31
+	// Visit a parse tree produced by BPFParser#jumpOperation.
32
+	VisitJumpOperation(ctx *JumpOperationContext) interface{}
33
+
34
+	// Visit a parse tree produced by BPFParser#jumpOperator.
35
+	VisitJumpOperator(ctx *JumpOperatorContext) interface{}
36
+
37
+	// Visit a parse tree produced by BPFParser#jumpConditionalOperation.
38
+	VisitJumpConditionalOperation(ctx *JumpConditionalOperationContext) interface{}
39
+
40
+	// Visit a parse tree produced by BPFParser#jumpConditionalOperator.
41
+	VisitJumpConditionalOperator(ctx *JumpConditionalOperatorContext) interface{}
42
+
43
+	// Visit a parse tree produced by BPFParser#ifTrue.
44
+	VisitIfTrue(ctx *IfTrueContext) interface{}
45
+
46
+	// Visit a parse tree produced by BPFParser#ifFalse.
47
+	VisitIfFalse(ctx *IfFalseContext) interface{}
48
+
49
+	// Visit a parse tree produced by BPFParser#loadOperation.
50
+	VisitLoadOperation(ctx *LoadOperationContext) interface{}
51
+
52
+	// Visit a parse tree produced by BPFParser#loadOperator.
53
+	VisitLoadOperator(ctx *LoadOperatorContext) interface{}
54
+
55
+	// Visit a parse tree produced by BPFParser#storeOperation.
56
+	VisitStoreOperation(ctx *StoreOperationContext) interface{}
57
+
58
+	// Visit a parse tree produced by BPFParser#storeOperator.
59
+	VisitStoreOperator(ctx *StoreOperatorContext) interface{}
60
+
61
+	// Visit a parse tree produced by BPFParser#simpleOperation.
62
+	VisitSimpleOperation(ctx *SimpleOperationContext) interface{}
63
+
64
+	// Visit a parse tree produced by BPFParser#returnOperation.
65
+	VisitReturnOperation(ctx *ReturnOperationContext) interface{}
66
+
67
+	// Visit a parse tree produced by BPFParser#number.
68
+	VisitNumber(ctx *NumberContext) interface{}
69
+
70
+	// Visit a parse tree produced by BPFParser#literalNumber.
71
+	VisitLiteralNumber(ctx *LiteralNumberContext) interface{}
72
+
73
+	// Visit a parse tree produced by BPFParser#indirectX.
74
+	VisitIndirectX(ctx *IndirectXContext) interface{}
75
+
76
+	// Visit a parse tree produced by BPFParser#absoluteNumber.
77
+	VisitAbsoluteNumber(ctx *AbsoluteNumberContext) interface{}
78
+
79
+	// Visit a parse tree produced by BPFParser#registerA.
80
+	VisitRegisterA(ctx *RegisterAContext) interface{}
81
+
82
+	// Visit a parse tree produced by BPFParser#registerX.
83
+	VisitRegisterX(ctx *RegisterXContext) interface{}
84
+
85
+	// Visit a parse tree produced by BPFParser#registerR.
86
+	VisitRegisterR(ctx *RegisterRContext) interface{}
87
+
88
+	// Visit a parse tree produced by BPFParser#extension.
89
+	VisitExtension(ctx *ExtensionContext) interface{}
90
+}

+ 4
- 0
testdata/example1.asm View File

@@ -0,0 +1,4 @@
1
+ldh [12]
2
+jneq #2054,1
3
+ret #4096
4
+ret #0

+ 4
- 0
testdata/example2.asm View File

@@ -0,0 +1,4 @@
1
+ld 		rand
2
+jlt 	#2,0
3
+ret 	#4096
4
+ret 	#0

+ 17
- 0
testdata/example3.asm View File

@@ -0,0 +1,17 @@
1
+;SECCOMP filter example
2
+
3
+		ld 		[4]                 ;  offsetof(struct seccomp_data, arch)
4
+		jne 	#0xc000003e, bad    ;  AUDIT_ARCH_X86_64
5
+		ld 		[0]                 ;  offsetof(struct seccomp_data, nr)
6
+		jeq		#15, good           ;  __NR_rt_sigreturn
7
+		jeq		#231, good          ;  __NR_exit_group
8
+		jeq		#60, good           ;  __NR_exit
9
+		jeq		#0, good            ;  __NR_read
10
+		jeq		#1, good            ;  __NR_write
11
+		jeq		#5, good            ;  __NR_fstat
12
+		jeq		#9, good            ;  __NR_mmap
13
+		jeq		#14, good           ;  __NR_rt_sigprocmask
14
+		jeq		#13, good           ;  __NR_rt_sigaction
15
+		jeq		#35, good           ;  __NR_nanosleep
16
+bad: 	ret		#0             		;  SECCOMP_RET_KILL_THREAD
17
+good: 	ret		#0x7fff0000   		;  SECCOMP_RET_ALLOW

+ 11
- 0
testdata/example4.asm View File

@@ -0,0 +1,11 @@
1
+; icmp random packet sampling, 1 in 4
2
+		ldh 	[12]
3
+		jne 	#0x800, drop
4
+		ldb 	[23]
5
+		jneq 	#1, drop
6
+		; get a random uint32 number
7
+		ld 		rand
8
+		mod 	#4
9
+		jneq 	#1, drop
10
+		ret 	#-1
11
+drop: 	ret 	#0

Loading…
Cancel
Save