18c2ecf20Sopenharmony_ci/* 28c2ecf20Sopenharmony_ci * BPF asm code parser 38c2ecf20Sopenharmony_ci * 48c2ecf20Sopenharmony_ci * This program is free software; you can distribute it and/or modify 58c2ecf20Sopenharmony_ci * it under the terms of the GNU General Public License as published 68c2ecf20Sopenharmony_ci * by the Free Software Foundation; either version 2 of the License, 78c2ecf20Sopenharmony_ci * or (at your option) any later version. 88c2ecf20Sopenharmony_ci * 98c2ecf20Sopenharmony_ci * Syntax kept close to: 108c2ecf20Sopenharmony_ci * 118c2ecf20Sopenharmony_ci * Steven McCanne and Van Jacobson. 1993. The BSD packet filter: a new 128c2ecf20Sopenharmony_ci * architecture for user-level packet capture. In Proceedings of the 138c2ecf20Sopenharmony_ci * USENIX Winter 1993 Conference Proceedings on USENIX Winter 1993 148c2ecf20Sopenharmony_ci * Conference Proceedings (USENIX'93). USENIX Association, Berkeley, 158c2ecf20Sopenharmony_ci * CA, USA, 2-2. 168c2ecf20Sopenharmony_ci * 178c2ecf20Sopenharmony_ci * Copyright 2013 Daniel Borkmann <borkmann@redhat.com> 188c2ecf20Sopenharmony_ci * Licensed under the GNU General Public License, version 2.0 (GPLv2) 198c2ecf20Sopenharmony_ci */ 208c2ecf20Sopenharmony_ci 218c2ecf20Sopenharmony_ci%{ 228c2ecf20Sopenharmony_ci 238c2ecf20Sopenharmony_ci#include <stdio.h> 248c2ecf20Sopenharmony_ci#include <string.h> 258c2ecf20Sopenharmony_ci#include <stdint.h> 268c2ecf20Sopenharmony_ci#include <stdlib.h> 278c2ecf20Sopenharmony_ci#include <stdbool.h> 288c2ecf20Sopenharmony_ci#include <unistd.h> 298c2ecf20Sopenharmony_ci#include <errno.h> 308c2ecf20Sopenharmony_ci#include <assert.h> 318c2ecf20Sopenharmony_ci#include <linux/filter.h> 328c2ecf20Sopenharmony_ci 338c2ecf20Sopenharmony_ci#include "bpf_exp.yacc.h" 348c2ecf20Sopenharmony_ci 358c2ecf20Sopenharmony_cienum jmp_type { JTL, JFL, JKL }; 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ciextern FILE *yyin; 388c2ecf20Sopenharmony_ciextern int yylineno; 398c2ecf20Sopenharmony_ciextern int yylex(void); 408c2ecf20Sopenharmony_ciextern void yyerror(const char *str); 418c2ecf20Sopenharmony_ci 428c2ecf20Sopenharmony_ciextern void bpf_asm_compile(FILE *fp, bool cstyle); 438c2ecf20Sopenharmony_cistatic void bpf_set_curr_instr(uint16_t op, uint8_t jt, uint8_t jf, uint32_t k); 448c2ecf20Sopenharmony_cistatic void bpf_set_curr_label(char *label); 458c2ecf20Sopenharmony_cistatic void bpf_set_jmp_label(char *label, enum jmp_type type); 468c2ecf20Sopenharmony_ci 478c2ecf20Sopenharmony_ci%} 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci%union { 508c2ecf20Sopenharmony_ci char *label; 518c2ecf20Sopenharmony_ci uint32_t number; 528c2ecf20Sopenharmony_ci} 538c2ecf20Sopenharmony_ci 548c2ecf20Sopenharmony_ci%token OP_LDB OP_LDH OP_LD OP_LDX OP_ST OP_STX OP_JMP OP_JEQ OP_JGT OP_JGE 558c2ecf20Sopenharmony_ci%token OP_JSET OP_ADD OP_SUB OP_MUL OP_DIV OP_AND OP_OR OP_XOR OP_LSH OP_RSH 568c2ecf20Sopenharmony_ci%token OP_RET OP_TAX OP_TXA OP_LDXB OP_MOD OP_NEG OP_JNEQ OP_JLT OP_JLE OP_LDI 578c2ecf20Sopenharmony_ci%token OP_LDXI 588c2ecf20Sopenharmony_ci 598c2ecf20Sopenharmony_ci%token K_PKT_LEN 608c2ecf20Sopenharmony_ci 618c2ecf20Sopenharmony_ci%token ':' ',' '[' ']' '(' ')' 'x' 'a' '+' 'M' '*' '&' '#' '%' 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ci%token extension number label 648c2ecf20Sopenharmony_ci 658c2ecf20Sopenharmony_ci%type <label> label 668c2ecf20Sopenharmony_ci%type <number> extension 678c2ecf20Sopenharmony_ci%type <number> number 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci%% 708c2ecf20Sopenharmony_ci 718c2ecf20Sopenharmony_ciprog 728c2ecf20Sopenharmony_ci : line 738c2ecf20Sopenharmony_ci | prog line 748c2ecf20Sopenharmony_ci ; 758c2ecf20Sopenharmony_ci 768c2ecf20Sopenharmony_ciline 778c2ecf20Sopenharmony_ci : instr 788c2ecf20Sopenharmony_ci | labelled_instr 798c2ecf20Sopenharmony_ci ; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_cilabelled_instr 828c2ecf20Sopenharmony_ci : labelled instr 838c2ecf20Sopenharmony_ci ; 848c2ecf20Sopenharmony_ci 858c2ecf20Sopenharmony_ciinstr 868c2ecf20Sopenharmony_ci : ldb 878c2ecf20Sopenharmony_ci | ldh 888c2ecf20Sopenharmony_ci | ld 898c2ecf20Sopenharmony_ci | ldi 908c2ecf20Sopenharmony_ci | ldx 918c2ecf20Sopenharmony_ci | ldxi 928c2ecf20Sopenharmony_ci | st 938c2ecf20Sopenharmony_ci | stx 948c2ecf20Sopenharmony_ci | jmp 958c2ecf20Sopenharmony_ci | jeq 968c2ecf20Sopenharmony_ci | jneq 978c2ecf20Sopenharmony_ci | jlt 988c2ecf20Sopenharmony_ci | jle 998c2ecf20Sopenharmony_ci | jgt 1008c2ecf20Sopenharmony_ci | jge 1018c2ecf20Sopenharmony_ci | jset 1028c2ecf20Sopenharmony_ci | add 1038c2ecf20Sopenharmony_ci | sub 1048c2ecf20Sopenharmony_ci | mul 1058c2ecf20Sopenharmony_ci | div 1068c2ecf20Sopenharmony_ci | mod 1078c2ecf20Sopenharmony_ci | neg 1088c2ecf20Sopenharmony_ci | and 1098c2ecf20Sopenharmony_ci | or 1108c2ecf20Sopenharmony_ci | xor 1118c2ecf20Sopenharmony_ci | lsh 1128c2ecf20Sopenharmony_ci | rsh 1138c2ecf20Sopenharmony_ci | ret 1148c2ecf20Sopenharmony_ci | tax 1158c2ecf20Sopenharmony_ci | txa 1168c2ecf20Sopenharmony_ci ; 1178c2ecf20Sopenharmony_ci 1188c2ecf20Sopenharmony_cilabelled 1198c2ecf20Sopenharmony_ci : label ':' { bpf_set_curr_label($1); } 1208c2ecf20Sopenharmony_ci ; 1218c2ecf20Sopenharmony_ci 1228c2ecf20Sopenharmony_cildb 1238c2ecf20Sopenharmony_ci : OP_LDB '[' 'x' '+' number ']' { 1248c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_B | BPF_IND, 0, 0, $5); } 1258c2ecf20Sopenharmony_ci | OP_LDB '[' '%' 'x' '+' number ']' { 1268c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_B | BPF_IND, 0, 0, $6); } 1278c2ecf20Sopenharmony_ci | OP_LDB '[' number ']' { 1288c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0, $3); } 1298c2ecf20Sopenharmony_ci | OP_LDB extension { 1308c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0, 1318c2ecf20Sopenharmony_ci SKF_AD_OFF + $2); } 1328c2ecf20Sopenharmony_ci ; 1338c2ecf20Sopenharmony_ci 1348c2ecf20Sopenharmony_cildh 1358c2ecf20Sopenharmony_ci : OP_LDH '[' 'x' '+' number ']' { 1368c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_H | BPF_IND, 0, 0, $5); } 1378c2ecf20Sopenharmony_ci | OP_LDH '[' '%' 'x' '+' number ']' { 1388c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_H | BPF_IND, 0, 0, $6); } 1398c2ecf20Sopenharmony_ci | OP_LDH '[' number ']' { 1408c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0, $3); } 1418c2ecf20Sopenharmony_ci | OP_LDH extension { 1428c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0, 1438c2ecf20Sopenharmony_ci SKF_AD_OFF + $2); } 1448c2ecf20Sopenharmony_ci ; 1458c2ecf20Sopenharmony_ci 1468c2ecf20Sopenharmony_cildi 1478c2ecf20Sopenharmony_ci : OP_LDI '#' number { 1488c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_IMM, 0, 0, $3); } 1498c2ecf20Sopenharmony_ci | OP_LDI number { 1508c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_IMM, 0, 0, $2); } 1518c2ecf20Sopenharmony_ci ; 1528c2ecf20Sopenharmony_ci 1538c2ecf20Sopenharmony_cild 1548c2ecf20Sopenharmony_ci : OP_LD '#' number { 1558c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_IMM, 0, 0, $3); } 1568c2ecf20Sopenharmony_ci | OP_LD K_PKT_LEN { 1578c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_W | BPF_LEN, 0, 0, 0); } 1588c2ecf20Sopenharmony_ci | OP_LD extension { 1598c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0, 1608c2ecf20Sopenharmony_ci SKF_AD_OFF + $2); } 1618c2ecf20Sopenharmony_ci | OP_LD 'M' '[' number ']' { 1628c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_MEM, 0, 0, $4); } 1638c2ecf20Sopenharmony_ci | OP_LD '[' 'x' '+' number ']' { 1648c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_W | BPF_IND, 0, 0, $5); } 1658c2ecf20Sopenharmony_ci | OP_LD '[' '%' 'x' '+' number ']' { 1668c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_W | BPF_IND, 0, 0, $6); } 1678c2ecf20Sopenharmony_ci | OP_LD '[' number ']' { 1688c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0, $3); } 1698c2ecf20Sopenharmony_ci ; 1708c2ecf20Sopenharmony_ci 1718c2ecf20Sopenharmony_cildxi 1728c2ecf20Sopenharmony_ci : OP_LDXI '#' number { 1738c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LDX | BPF_IMM, 0, 0, $3); } 1748c2ecf20Sopenharmony_ci | OP_LDXI number { 1758c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LDX | BPF_IMM, 0, 0, $2); } 1768c2ecf20Sopenharmony_ci ; 1778c2ecf20Sopenharmony_ci 1788c2ecf20Sopenharmony_cildx 1798c2ecf20Sopenharmony_ci : OP_LDX '#' number { 1808c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LDX | BPF_IMM, 0, 0, $3); } 1818c2ecf20Sopenharmony_ci | OP_LDX K_PKT_LEN { 1828c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LDX | BPF_W | BPF_LEN, 0, 0, 0); } 1838c2ecf20Sopenharmony_ci | OP_LDX 'M' '[' number ']' { 1848c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LDX | BPF_MEM, 0, 0, $4); } 1858c2ecf20Sopenharmony_ci | OP_LDXB number '*' '(' '[' number ']' '&' number ')' { 1868c2ecf20Sopenharmony_ci if ($2 != 4 || $9 != 0xf) { 1878c2ecf20Sopenharmony_ci fprintf(stderr, "ldxb offset not supported!\n"); 1888c2ecf20Sopenharmony_ci exit(0); 1898c2ecf20Sopenharmony_ci } else { 1908c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LDX | BPF_MSH | BPF_B, 0, 0, $6); } } 1918c2ecf20Sopenharmony_ci | OP_LDX number '*' '(' '[' number ']' '&' number ')' { 1928c2ecf20Sopenharmony_ci if ($2 != 4 || $9 != 0xf) { 1938c2ecf20Sopenharmony_ci fprintf(stderr, "ldxb offset not supported!\n"); 1948c2ecf20Sopenharmony_ci exit(0); 1958c2ecf20Sopenharmony_ci } else { 1968c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_LDX | BPF_MSH | BPF_B, 0, 0, $6); } } 1978c2ecf20Sopenharmony_ci ; 1988c2ecf20Sopenharmony_ci 1998c2ecf20Sopenharmony_cist 2008c2ecf20Sopenharmony_ci : OP_ST 'M' '[' number ']' { 2018c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ST, 0, 0, $4); } 2028c2ecf20Sopenharmony_ci ; 2038c2ecf20Sopenharmony_ci 2048c2ecf20Sopenharmony_cistx 2058c2ecf20Sopenharmony_ci : OP_STX 'M' '[' number ']' { 2068c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_STX, 0, 0, $4); } 2078c2ecf20Sopenharmony_ci ; 2088c2ecf20Sopenharmony_ci 2098c2ecf20Sopenharmony_cijmp 2108c2ecf20Sopenharmony_ci : OP_JMP label { 2118c2ecf20Sopenharmony_ci bpf_set_jmp_label($2, JKL); 2128c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JA, 0, 0, 0); } 2138c2ecf20Sopenharmony_ci ; 2148c2ecf20Sopenharmony_ci 2158c2ecf20Sopenharmony_cijeq 2168c2ecf20Sopenharmony_ci : OP_JEQ '#' number ',' label ',' label { 2178c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JTL); 2188c2ecf20Sopenharmony_ci bpf_set_jmp_label($7, JFL); 2198c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, $3); } 2208c2ecf20Sopenharmony_ci | OP_JEQ 'x' ',' label ',' label { 2218c2ecf20Sopenharmony_ci bpf_set_jmp_label($4, JTL); 2228c2ecf20Sopenharmony_ci bpf_set_jmp_label($6, JFL); 2238c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JEQ | BPF_X, 0, 0, 0); } 2248c2ecf20Sopenharmony_ci | OP_JEQ '%' 'x' ',' label ',' label { 2258c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JTL); 2268c2ecf20Sopenharmony_ci bpf_set_jmp_label($7, JFL); 2278c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JEQ | BPF_X, 0, 0, 0); } 2288c2ecf20Sopenharmony_ci | OP_JEQ '#' number ',' label { 2298c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JTL); 2308c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, $3); } 2318c2ecf20Sopenharmony_ci | OP_JEQ 'x' ',' label { 2328c2ecf20Sopenharmony_ci bpf_set_jmp_label($4, JTL); 2338c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JEQ | BPF_X, 0, 0, 0); } 2348c2ecf20Sopenharmony_ci | OP_JEQ '%' 'x' ',' label { 2358c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JTL); 2368c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JEQ | BPF_X, 0, 0, 0); } 2378c2ecf20Sopenharmony_ci ; 2388c2ecf20Sopenharmony_ci 2398c2ecf20Sopenharmony_cijneq 2408c2ecf20Sopenharmony_ci : OP_JNEQ '#' number ',' label { 2418c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JFL); 2428c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JEQ | BPF_K, 0, 0, $3); } 2438c2ecf20Sopenharmony_ci | OP_JNEQ 'x' ',' label { 2448c2ecf20Sopenharmony_ci bpf_set_jmp_label($4, JFL); 2458c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JEQ | BPF_X, 0, 0, 0); } 2468c2ecf20Sopenharmony_ci | OP_JNEQ '%' 'x' ',' label { 2478c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JFL); 2488c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JEQ | BPF_X, 0, 0, 0); } 2498c2ecf20Sopenharmony_ci ; 2508c2ecf20Sopenharmony_ci 2518c2ecf20Sopenharmony_cijlt 2528c2ecf20Sopenharmony_ci : OP_JLT '#' number ',' label { 2538c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JFL); 2548c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGE | BPF_K, 0, 0, $3); } 2558c2ecf20Sopenharmony_ci | OP_JLT 'x' ',' label { 2568c2ecf20Sopenharmony_ci bpf_set_jmp_label($4, JFL); 2578c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGE | BPF_X, 0, 0, 0); } 2588c2ecf20Sopenharmony_ci | OP_JLT '%' 'x' ',' label { 2598c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JFL); 2608c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGE | BPF_X, 0, 0, 0); } 2618c2ecf20Sopenharmony_ci ; 2628c2ecf20Sopenharmony_ci 2638c2ecf20Sopenharmony_cijle 2648c2ecf20Sopenharmony_ci : OP_JLE '#' number ',' label { 2658c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JFL); 2668c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGT | BPF_K, 0, 0, $3); } 2678c2ecf20Sopenharmony_ci | OP_JLE 'x' ',' label { 2688c2ecf20Sopenharmony_ci bpf_set_jmp_label($4, JFL); 2698c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGT | BPF_X, 0, 0, 0); } 2708c2ecf20Sopenharmony_ci | OP_JLE '%' 'x' ',' label { 2718c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JFL); 2728c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGT | BPF_X, 0, 0, 0); } 2738c2ecf20Sopenharmony_ci ; 2748c2ecf20Sopenharmony_ci 2758c2ecf20Sopenharmony_cijgt 2768c2ecf20Sopenharmony_ci : OP_JGT '#' number ',' label ',' label { 2778c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JTL); 2788c2ecf20Sopenharmony_ci bpf_set_jmp_label($7, JFL); 2798c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGT | BPF_K, 0, 0, $3); } 2808c2ecf20Sopenharmony_ci | OP_JGT 'x' ',' label ',' label { 2818c2ecf20Sopenharmony_ci bpf_set_jmp_label($4, JTL); 2828c2ecf20Sopenharmony_ci bpf_set_jmp_label($6, JFL); 2838c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGT | BPF_X, 0, 0, 0); } 2848c2ecf20Sopenharmony_ci | OP_JGT '%' 'x' ',' label ',' label { 2858c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JTL); 2868c2ecf20Sopenharmony_ci bpf_set_jmp_label($7, JFL); 2878c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGT | BPF_X, 0, 0, 0); } 2888c2ecf20Sopenharmony_ci | OP_JGT '#' number ',' label { 2898c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JTL); 2908c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGT | BPF_K, 0, 0, $3); } 2918c2ecf20Sopenharmony_ci | OP_JGT 'x' ',' label { 2928c2ecf20Sopenharmony_ci bpf_set_jmp_label($4, JTL); 2938c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGT | BPF_X, 0, 0, 0); } 2948c2ecf20Sopenharmony_ci | OP_JGT '%' 'x' ',' label { 2958c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JTL); 2968c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGT | BPF_X, 0, 0, 0); } 2978c2ecf20Sopenharmony_ci ; 2988c2ecf20Sopenharmony_ci 2998c2ecf20Sopenharmony_cijge 3008c2ecf20Sopenharmony_ci : OP_JGE '#' number ',' label ',' label { 3018c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JTL); 3028c2ecf20Sopenharmony_ci bpf_set_jmp_label($7, JFL); 3038c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGE | BPF_K, 0, 0, $3); } 3048c2ecf20Sopenharmony_ci | OP_JGE 'x' ',' label ',' label { 3058c2ecf20Sopenharmony_ci bpf_set_jmp_label($4, JTL); 3068c2ecf20Sopenharmony_ci bpf_set_jmp_label($6, JFL); 3078c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGE | BPF_X, 0, 0, 0); } 3088c2ecf20Sopenharmony_ci | OP_JGE '%' 'x' ',' label ',' label { 3098c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JTL); 3108c2ecf20Sopenharmony_ci bpf_set_jmp_label($7, JFL); 3118c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGE | BPF_X, 0, 0, 0); } 3128c2ecf20Sopenharmony_ci | OP_JGE '#' number ',' label { 3138c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JTL); 3148c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGE | BPF_K, 0, 0, $3); } 3158c2ecf20Sopenharmony_ci | OP_JGE 'x' ',' label { 3168c2ecf20Sopenharmony_ci bpf_set_jmp_label($4, JTL); 3178c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGE | BPF_X, 0, 0, 0); } 3188c2ecf20Sopenharmony_ci | OP_JGE '%' 'x' ',' label { 3198c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JTL); 3208c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JGE | BPF_X, 0, 0, 0); } 3218c2ecf20Sopenharmony_ci ; 3228c2ecf20Sopenharmony_ci 3238c2ecf20Sopenharmony_cijset 3248c2ecf20Sopenharmony_ci : OP_JSET '#' number ',' label ',' label { 3258c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JTL); 3268c2ecf20Sopenharmony_ci bpf_set_jmp_label($7, JFL); 3278c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JSET | BPF_K, 0, 0, $3); } 3288c2ecf20Sopenharmony_ci | OP_JSET 'x' ',' label ',' label { 3298c2ecf20Sopenharmony_ci bpf_set_jmp_label($4, JTL); 3308c2ecf20Sopenharmony_ci bpf_set_jmp_label($6, JFL); 3318c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JSET | BPF_X, 0, 0, 0); } 3328c2ecf20Sopenharmony_ci | OP_JSET '%' 'x' ',' label ',' label { 3338c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JTL); 3348c2ecf20Sopenharmony_ci bpf_set_jmp_label($7, JFL); 3358c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JSET | BPF_X, 0, 0, 0); } 3368c2ecf20Sopenharmony_ci | OP_JSET '#' number ',' label { 3378c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JTL); 3388c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JSET | BPF_K, 0, 0, $3); } 3398c2ecf20Sopenharmony_ci | OP_JSET 'x' ',' label { 3408c2ecf20Sopenharmony_ci bpf_set_jmp_label($4, JTL); 3418c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JSET | BPF_X, 0, 0, 0); } 3428c2ecf20Sopenharmony_ci | OP_JSET '%' 'x' ',' label { 3438c2ecf20Sopenharmony_ci bpf_set_jmp_label($5, JTL); 3448c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_JMP | BPF_JSET | BPF_X, 0, 0, 0); } 3458c2ecf20Sopenharmony_ci ; 3468c2ecf20Sopenharmony_ci 3478c2ecf20Sopenharmony_ciadd 3488c2ecf20Sopenharmony_ci : OP_ADD '#' number { 3498c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_ADD | BPF_K, 0, 0, $3); } 3508c2ecf20Sopenharmony_ci | OP_ADD 'x' { 3518c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_ADD | BPF_X, 0, 0, 0); } 3528c2ecf20Sopenharmony_ci | OP_ADD '%' 'x' { 3538c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_ADD | BPF_X, 0, 0, 0); } 3548c2ecf20Sopenharmony_ci ; 3558c2ecf20Sopenharmony_ci 3568c2ecf20Sopenharmony_cisub 3578c2ecf20Sopenharmony_ci : OP_SUB '#' number { 3588c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_SUB | BPF_K, 0, 0, $3); } 3598c2ecf20Sopenharmony_ci | OP_SUB 'x' { 3608c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_SUB | BPF_X, 0, 0, 0); } 3618c2ecf20Sopenharmony_ci | OP_SUB '%' 'x' { 3628c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_SUB | BPF_X, 0, 0, 0); } 3638c2ecf20Sopenharmony_ci ; 3648c2ecf20Sopenharmony_ci 3658c2ecf20Sopenharmony_cimul 3668c2ecf20Sopenharmony_ci : OP_MUL '#' number { 3678c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_MUL | BPF_K, 0, 0, $3); } 3688c2ecf20Sopenharmony_ci | OP_MUL 'x' { 3698c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_MUL | BPF_X, 0, 0, 0); } 3708c2ecf20Sopenharmony_ci | OP_MUL '%' 'x' { 3718c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_MUL | BPF_X, 0, 0, 0); } 3728c2ecf20Sopenharmony_ci ; 3738c2ecf20Sopenharmony_ci 3748c2ecf20Sopenharmony_cidiv 3758c2ecf20Sopenharmony_ci : OP_DIV '#' number { 3768c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_DIV | BPF_K, 0, 0, $3); } 3778c2ecf20Sopenharmony_ci | OP_DIV 'x' { 3788c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_DIV | BPF_X, 0, 0, 0); } 3798c2ecf20Sopenharmony_ci | OP_DIV '%' 'x' { 3808c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_DIV | BPF_X, 0, 0, 0); } 3818c2ecf20Sopenharmony_ci ; 3828c2ecf20Sopenharmony_ci 3838c2ecf20Sopenharmony_cimod 3848c2ecf20Sopenharmony_ci : OP_MOD '#' number { 3858c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_MOD | BPF_K, 0, 0, $3); } 3868c2ecf20Sopenharmony_ci | OP_MOD 'x' { 3878c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_MOD | BPF_X, 0, 0, 0); } 3888c2ecf20Sopenharmony_ci | OP_MOD '%' 'x' { 3898c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_MOD | BPF_X, 0, 0, 0); } 3908c2ecf20Sopenharmony_ci ; 3918c2ecf20Sopenharmony_ci 3928c2ecf20Sopenharmony_cineg 3938c2ecf20Sopenharmony_ci : OP_NEG { 3948c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_NEG, 0, 0, 0); } 3958c2ecf20Sopenharmony_ci ; 3968c2ecf20Sopenharmony_ci 3978c2ecf20Sopenharmony_ciand 3988c2ecf20Sopenharmony_ci : OP_AND '#' number { 3998c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_AND | BPF_K, 0, 0, $3); } 4008c2ecf20Sopenharmony_ci | OP_AND 'x' { 4018c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_AND | BPF_X, 0, 0, 0); } 4028c2ecf20Sopenharmony_ci | OP_AND '%' 'x' { 4038c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_AND | BPF_X, 0, 0, 0); } 4048c2ecf20Sopenharmony_ci ; 4058c2ecf20Sopenharmony_ci 4068c2ecf20Sopenharmony_cior 4078c2ecf20Sopenharmony_ci : OP_OR '#' number { 4088c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_OR | BPF_K, 0, 0, $3); } 4098c2ecf20Sopenharmony_ci | OP_OR 'x' { 4108c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_OR | BPF_X, 0, 0, 0); } 4118c2ecf20Sopenharmony_ci | OP_OR '%' 'x' { 4128c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_OR | BPF_X, 0, 0, 0); } 4138c2ecf20Sopenharmony_ci ; 4148c2ecf20Sopenharmony_ci 4158c2ecf20Sopenharmony_cixor 4168c2ecf20Sopenharmony_ci : OP_XOR '#' number { 4178c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_XOR | BPF_K, 0, 0, $3); } 4188c2ecf20Sopenharmony_ci | OP_XOR 'x' { 4198c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_XOR | BPF_X, 0, 0, 0); } 4208c2ecf20Sopenharmony_ci | OP_XOR '%' 'x' { 4218c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_XOR | BPF_X, 0, 0, 0); } 4228c2ecf20Sopenharmony_ci ; 4238c2ecf20Sopenharmony_ci 4248c2ecf20Sopenharmony_cilsh 4258c2ecf20Sopenharmony_ci : OP_LSH '#' number { 4268c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_LSH | BPF_K, 0, 0, $3); } 4278c2ecf20Sopenharmony_ci | OP_LSH 'x' { 4288c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_LSH | BPF_X, 0, 0, 0); } 4298c2ecf20Sopenharmony_ci | OP_LSH '%' 'x' { 4308c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_LSH | BPF_X, 0, 0, 0); } 4318c2ecf20Sopenharmony_ci ; 4328c2ecf20Sopenharmony_ci 4338c2ecf20Sopenharmony_cirsh 4348c2ecf20Sopenharmony_ci : OP_RSH '#' number { 4358c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_RSH | BPF_K, 0, 0, $3); } 4368c2ecf20Sopenharmony_ci | OP_RSH 'x' { 4378c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_RSH | BPF_X, 0, 0, 0); } 4388c2ecf20Sopenharmony_ci | OP_RSH '%' 'x' { 4398c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_ALU | BPF_RSH | BPF_X, 0, 0, 0); } 4408c2ecf20Sopenharmony_ci ; 4418c2ecf20Sopenharmony_ci 4428c2ecf20Sopenharmony_ciret 4438c2ecf20Sopenharmony_ci : OP_RET 'a' { 4448c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_RET | BPF_A, 0, 0, 0); } 4458c2ecf20Sopenharmony_ci | OP_RET '%' 'a' { 4468c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_RET | BPF_A, 0, 0, 0); } 4478c2ecf20Sopenharmony_ci | OP_RET 'x' { 4488c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_RET | BPF_X, 0, 0, 0); } 4498c2ecf20Sopenharmony_ci | OP_RET '%' 'x' { 4508c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_RET | BPF_X, 0, 0, 0); } 4518c2ecf20Sopenharmony_ci | OP_RET '#' number { 4528c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_RET | BPF_K, 0, 0, $3); } 4538c2ecf20Sopenharmony_ci ; 4548c2ecf20Sopenharmony_ci 4558c2ecf20Sopenharmony_citax 4568c2ecf20Sopenharmony_ci : OP_TAX { 4578c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_MISC | BPF_TAX, 0, 0, 0); } 4588c2ecf20Sopenharmony_ci ; 4598c2ecf20Sopenharmony_ci 4608c2ecf20Sopenharmony_citxa 4618c2ecf20Sopenharmony_ci : OP_TXA { 4628c2ecf20Sopenharmony_ci bpf_set_curr_instr(BPF_MISC | BPF_TXA, 0, 0, 0); } 4638c2ecf20Sopenharmony_ci ; 4648c2ecf20Sopenharmony_ci 4658c2ecf20Sopenharmony_ci%% 4668c2ecf20Sopenharmony_ci 4678c2ecf20Sopenharmony_cistatic int curr_instr = 0; 4688c2ecf20Sopenharmony_cistatic struct sock_filter out[BPF_MAXINSNS]; 4698c2ecf20Sopenharmony_cistatic char **labels, **labels_jt, **labels_jf, **labels_k; 4708c2ecf20Sopenharmony_ci 4718c2ecf20Sopenharmony_cistatic void bpf_assert_max(void) 4728c2ecf20Sopenharmony_ci{ 4738c2ecf20Sopenharmony_ci if (curr_instr >= BPF_MAXINSNS) { 4748c2ecf20Sopenharmony_ci fprintf(stderr, "only max %u insns allowed!\n", BPF_MAXINSNS); 4758c2ecf20Sopenharmony_ci exit(0); 4768c2ecf20Sopenharmony_ci } 4778c2ecf20Sopenharmony_ci} 4788c2ecf20Sopenharmony_ci 4798c2ecf20Sopenharmony_cistatic void bpf_set_curr_instr(uint16_t code, uint8_t jt, uint8_t jf, 4808c2ecf20Sopenharmony_ci uint32_t k) 4818c2ecf20Sopenharmony_ci{ 4828c2ecf20Sopenharmony_ci bpf_assert_max(); 4838c2ecf20Sopenharmony_ci out[curr_instr].code = code; 4848c2ecf20Sopenharmony_ci out[curr_instr].jt = jt; 4858c2ecf20Sopenharmony_ci out[curr_instr].jf = jf; 4868c2ecf20Sopenharmony_ci out[curr_instr].k = k; 4878c2ecf20Sopenharmony_ci curr_instr++; 4888c2ecf20Sopenharmony_ci} 4898c2ecf20Sopenharmony_ci 4908c2ecf20Sopenharmony_cistatic void bpf_set_curr_label(char *label) 4918c2ecf20Sopenharmony_ci{ 4928c2ecf20Sopenharmony_ci bpf_assert_max(); 4938c2ecf20Sopenharmony_ci labels[curr_instr] = label; 4948c2ecf20Sopenharmony_ci} 4958c2ecf20Sopenharmony_ci 4968c2ecf20Sopenharmony_cistatic void bpf_set_jmp_label(char *label, enum jmp_type type) 4978c2ecf20Sopenharmony_ci{ 4988c2ecf20Sopenharmony_ci bpf_assert_max(); 4998c2ecf20Sopenharmony_ci switch (type) { 5008c2ecf20Sopenharmony_ci case JTL: 5018c2ecf20Sopenharmony_ci labels_jt[curr_instr] = label; 5028c2ecf20Sopenharmony_ci break; 5038c2ecf20Sopenharmony_ci case JFL: 5048c2ecf20Sopenharmony_ci labels_jf[curr_instr] = label; 5058c2ecf20Sopenharmony_ci break; 5068c2ecf20Sopenharmony_ci case JKL: 5078c2ecf20Sopenharmony_ci labels_k[curr_instr] = label; 5088c2ecf20Sopenharmony_ci break; 5098c2ecf20Sopenharmony_ci } 5108c2ecf20Sopenharmony_ci} 5118c2ecf20Sopenharmony_ci 5128c2ecf20Sopenharmony_cistatic int bpf_find_insns_offset(const char *label) 5138c2ecf20Sopenharmony_ci{ 5148c2ecf20Sopenharmony_ci int i, max = curr_instr, ret = -ENOENT; 5158c2ecf20Sopenharmony_ci 5168c2ecf20Sopenharmony_ci for (i = 0; i < max; i++) { 5178c2ecf20Sopenharmony_ci if (labels[i] && !strcmp(label, labels[i])) { 5188c2ecf20Sopenharmony_ci ret = i; 5198c2ecf20Sopenharmony_ci break; 5208c2ecf20Sopenharmony_ci } 5218c2ecf20Sopenharmony_ci } 5228c2ecf20Sopenharmony_ci 5238c2ecf20Sopenharmony_ci if (ret == -ENOENT) { 5248c2ecf20Sopenharmony_ci fprintf(stderr, "no such label \'%s\'!\n", label); 5258c2ecf20Sopenharmony_ci exit(0); 5268c2ecf20Sopenharmony_ci } 5278c2ecf20Sopenharmony_ci 5288c2ecf20Sopenharmony_ci return ret; 5298c2ecf20Sopenharmony_ci} 5308c2ecf20Sopenharmony_ci 5318c2ecf20Sopenharmony_cistatic void bpf_stage_1_insert_insns(void) 5328c2ecf20Sopenharmony_ci{ 5338c2ecf20Sopenharmony_ci yyparse(); 5348c2ecf20Sopenharmony_ci} 5358c2ecf20Sopenharmony_ci 5368c2ecf20Sopenharmony_cistatic void bpf_reduce_k_jumps(void) 5378c2ecf20Sopenharmony_ci{ 5388c2ecf20Sopenharmony_ci int i; 5398c2ecf20Sopenharmony_ci 5408c2ecf20Sopenharmony_ci for (i = 0; i < curr_instr; i++) { 5418c2ecf20Sopenharmony_ci if (labels_k[i]) { 5428c2ecf20Sopenharmony_ci int off = bpf_find_insns_offset(labels_k[i]); 5438c2ecf20Sopenharmony_ci out[i].k = (uint32_t) (off - i - 1); 5448c2ecf20Sopenharmony_ci } 5458c2ecf20Sopenharmony_ci } 5468c2ecf20Sopenharmony_ci} 5478c2ecf20Sopenharmony_ci 5488c2ecf20Sopenharmony_cistatic uint8_t bpf_encode_jt_jf_offset(int off, int i) 5498c2ecf20Sopenharmony_ci{ 5508c2ecf20Sopenharmony_ci int delta = off - i - 1; 5518c2ecf20Sopenharmony_ci 5528c2ecf20Sopenharmony_ci if (delta < 0 || delta > 255) 5538c2ecf20Sopenharmony_ci fprintf(stderr, "warning: insn #%d jumps to insn #%d, " 5548c2ecf20Sopenharmony_ci "which is out of range\n", i, off); 5558c2ecf20Sopenharmony_ci return (uint8_t) delta; 5568c2ecf20Sopenharmony_ci} 5578c2ecf20Sopenharmony_ci 5588c2ecf20Sopenharmony_cistatic void bpf_reduce_jt_jumps(void) 5598c2ecf20Sopenharmony_ci{ 5608c2ecf20Sopenharmony_ci int i; 5618c2ecf20Sopenharmony_ci 5628c2ecf20Sopenharmony_ci for (i = 0; i < curr_instr; i++) { 5638c2ecf20Sopenharmony_ci if (labels_jt[i]) { 5648c2ecf20Sopenharmony_ci int off = bpf_find_insns_offset(labels_jt[i]); 5658c2ecf20Sopenharmony_ci out[i].jt = bpf_encode_jt_jf_offset(off, i); 5668c2ecf20Sopenharmony_ci } 5678c2ecf20Sopenharmony_ci } 5688c2ecf20Sopenharmony_ci} 5698c2ecf20Sopenharmony_ci 5708c2ecf20Sopenharmony_cistatic void bpf_reduce_jf_jumps(void) 5718c2ecf20Sopenharmony_ci{ 5728c2ecf20Sopenharmony_ci int i; 5738c2ecf20Sopenharmony_ci 5748c2ecf20Sopenharmony_ci for (i = 0; i < curr_instr; i++) { 5758c2ecf20Sopenharmony_ci if (labels_jf[i]) { 5768c2ecf20Sopenharmony_ci int off = bpf_find_insns_offset(labels_jf[i]); 5778c2ecf20Sopenharmony_ci out[i].jf = bpf_encode_jt_jf_offset(off, i); 5788c2ecf20Sopenharmony_ci } 5798c2ecf20Sopenharmony_ci } 5808c2ecf20Sopenharmony_ci} 5818c2ecf20Sopenharmony_ci 5828c2ecf20Sopenharmony_cistatic void bpf_stage_2_reduce_labels(void) 5838c2ecf20Sopenharmony_ci{ 5848c2ecf20Sopenharmony_ci bpf_reduce_k_jumps(); 5858c2ecf20Sopenharmony_ci bpf_reduce_jt_jumps(); 5868c2ecf20Sopenharmony_ci bpf_reduce_jf_jumps(); 5878c2ecf20Sopenharmony_ci} 5888c2ecf20Sopenharmony_ci 5898c2ecf20Sopenharmony_cistatic void bpf_pretty_print_c(void) 5908c2ecf20Sopenharmony_ci{ 5918c2ecf20Sopenharmony_ci int i; 5928c2ecf20Sopenharmony_ci 5938c2ecf20Sopenharmony_ci for (i = 0; i < curr_instr; i++) 5948c2ecf20Sopenharmony_ci printf("{ %#04x, %2u, %2u, %#010x },\n", out[i].code, 5958c2ecf20Sopenharmony_ci out[i].jt, out[i].jf, out[i].k); 5968c2ecf20Sopenharmony_ci} 5978c2ecf20Sopenharmony_ci 5988c2ecf20Sopenharmony_cistatic void bpf_pretty_print(void) 5998c2ecf20Sopenharmony_ci{ 6008c2ecf20Sopenharmony_ci int i; 6018c2ecf20Sopenharmony_ci 6028c2ecf20Sopenharmony_ci printf("%u,", curr_instr); 6038c2ecf20Sopenharmony_ci for (i = 0; i < curr_instr; i++) 6048c2ecf20Sopenharmony_ci printf("%u %u %u %u,", out[i].code, 6058c2ecf20Sopenharmony_ci out[i].jt, out[i].jf, out[i].k); 6068c2ecf20Sopenharmony_ci printf("\n"); 6078c2ecf20Sopenharmony_ci} 6088c2ecf20Sopenharmony_ci 6098c2ecf20Sopenharmony_cistatic void bpf_init(void) 6108c2ecf20Sopenharmony_ci{ 6118c2ecf20Sopenharmony_ci memset(out, 0, sizeof(out)); 6128c2ecf20Sopenharmony_ci 6138c2ecf20Sopenharmony_ci labels = calloc(BPF_MAXINSNS, sizeof(*labels)); 6148c2ecf20Sopenharmony_ci assert(labels); 6158c2ecf20Sopenharmony_ci labels_jt = calloc(BPF_MAXINSNS, sizeof(*labels_jt)); 6168c2ecf20Sopenharmony_ci assert(labels_jt); 6178c2ecf20Sopenharmony_ci labels_jf = calloc(BPF_MAXINSNS, sizeof(*labels_jf)); 6188c2ecf20Sopenharmony_ci assert(labels_jf); 6198c2ecf20Sopenharmony_ci labels_k = calloc(BPF_MAXINSNS, sizeof(*labels_k)); 6208c2ecf20Sopenharmony_ci assert(labels_k); 6218c2ecf20Sopenharmony_ci} 6228c2ecf20Sopenharmony_ci 6238c2ecf20Sopenharmony_cistatic void bpf_destroy_labels(void) 6248c2ecf20Sopenharmony_ci{ 6258c2ecf20Sopenharmony_ci int i; 6268c2ecf20Sopenharmony_ci 6278c2ecf20Sopenharmony_ci for (i = 0; i < curr_instr; i++) { 6288c2ecf20Sopenharmony_ci free(labels_jf[i]); 6298c2ecf20Sopenharmony_ci free(labels_jt[i]); 6308c2ecf20Sopenharmony_ci free(labels_k[i]); 6318c2ecf20Sopenharmony_ci free(labels[i]); 6328c2ecf20Sopenharmony_ci } 6338c2ecf20Sopenharmony_ci} 6348c2ecf20Sopenharmony_ci 6358c2ecf20Sopenharmony_cistatic void bpf_destroy(void) 6368c2ecf20Sopenharmony_ci{ 6378c2ecf20Sopenharmony_ci bpf_destroy_labels(); 6388c2ecf20Sopenharmony_ci free(labels_jt); 6398c2ecf20Sopenharmony_ci free(labels_jf); 6408c2ecf20Sopenharmony_ci free(labels_k); 6418c2ecf20Sopenharmony_ci free(labels); 6428c2ecf20Sopenharmony_ci} 6438c2ecf20Sopenharmony_ci 6448c2ecf20Sopenharmony_civoid bpf_asm_compile(FILE *fp, bool cstyle) 6458c2ecf20Sopenharmony_ci{ 6468c2ecf20Sopenharmony_ci yyin = fp; 6478c2ecf20Sopenharmony_ci 6488c2ecf20Sopenharmony_ci bpf_init(); 6498c2ecf20Sopenharmony_ci bpf_stage_1_insert_insns(); 6508c2ecf20Sopenharmony_ci bpf_stage_2_reduce_labels(); 6518c2ecf20Sopenharmony_ci bpf_destroy(); 6528c2ecf20Sopenharmony_ci 6538c2ecf20Sopenharmony_ci if (cstyle) 6548c2ecf20Sopenharmony_ci bpf_pretty_print_c(); 6558c2ecf20Sopenharmony_ci else 6568c2ecf20Sopenharmony_ci bpf_pretty_print(); 6578c2ecf20Sopenharmony_ci 6588c2ecf20Sopenharmony_ci if (fp != stdin) 6598c2ecf20Sopenharmony_ci fclose(yyin); 6608c2ecf20Sopenharmony_ci} 6618c2ecf20Sopenharmony_ci 6628c2ecf20Sopenharmony_civoid yyerror(const char *str) 6638c2ecf20Sopenharmony_ci{ 6648c2ecf20Sopenharmony_ci fprintf(stderr, "error: %s at line %d\n", str, yylineno); 6658c2ecf20Sopenharmony_ci exit(1); 6668c2ecf20Sopenharmony_ci} 667