| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154 |
- #ifndef _PLY_IR_H
- #define _PLY_IR_H
- #include <stdint.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <bits/wordsize.h>
- #include <linux/bpf.h>
- #define INSN(_code, _dst, _src, _off, _imm) \
- ((struct bpf_insn) { \
- .code = _code, \
- .dst_reg = _dst, \
- .src_reg = _src, \
- .off = _off, \
- .imm = _imm \
- })
- #define MOV32 INSN(BPF_ALU | BPF_MOV | BPF_X, 0, 0, 0, 0)
- #define MOV32_IMM(_imm) INSN(BPF_ALU | BPF_MOV | BPF_K, 0, 0, 0, _imm)
- #define MOV64 INSN(BPF_ALU64 | BPF_MOV | BPF_X, 0, 0, 0, 0)
- #define MOV64_IMM(_imm) INSN(BPF_ALU64 | BPF_MOV | BPF_K, 0, 0, 0, _imm)
- #define EXIT INSN(BPF_JMP | BPF_EXIT, 0, 0, 0, 0)
- #define CALL(_imm) INSN(BPF_JMP | BPF_CALL, 0, 0, 0, _imm)
- #define JMP(_op, _off) INSN(BPF_JMP | BPF_OP((_op)) | BPF_X, 0, 0, _off, 0)
- #define JMP_IMM(_op, _imm, _off) INSN(BPF_JMP | BPF_OP((_op)) | BPF_K, 0, 0, _off, _imm)
- #define ALU32(_op) INSN(BPF_ALU | BPF_OP((_op)) | BPF_X, 0, 0, 0, 0)
- #define ALU32_IMM(_op, _imm) INSN(BPF_ALU | BPF_OP((_op)) | BPF_K, 0, 0, 0, _imm)
- #define ALU64(_op) INSN(BPF_ALU64 | BPF_OP((_op)) | BPF_X, 0, 0, 0, 0)
- #define ALU64_IMM(_op, _imm) INSN(BPF_ALU64 | BPF_OP((_op)) | BPF_K, 0, 0, 0, _imm)
- #define ST_IMM(_width, _off, _imm) INSN(BPF_ST | BPF_SIZE(_width) | BPF_MEM, 0, 0, _off, _imm)
- #define STX(_width, _off) INSN(BPF_STX | BPF_SIZE(_width) | BPF_MEM, 0, 0, _off, 0)
- #define LDX(_width, _off) INSN(BPF_LDX | BPF_SIZE(_width) | BPF_MEM, 0, 0, _off, 0)
- #if __WORDSIZE == 64
- # define MOV MOV64
- # define MOV_IMM MOV64_IMM
- # define ALU ALU64
- # define ALU_IMM ALU64_IMM
- #else
- # define MOV MOV32
- # define MOV_IMM MOV32_IMM
- # define ALU ALU32
- # define ALU_IMM ALU32_IMM
- #endif
- #define BPF_REG_BP BPF_REG_10
- static inline int bpf_width(size_t size)
- {
- switch (size) {
- case 1: return BPF_B;
- case 2: return BPF_H;
- case 4: return BPF_W;
- case 8: return BPF_DW;
- }
- return -1;
- }
- struct sym;
- struct type;
- enum vitype {
- VI_INSN,
- VI_LDMAP,
- VI_LABEL,
- VI_REG_GET,
- VI_REG_PUT,
- };
- struct vinsn {
- enum vitype vitype;
- union {
- struct {
- struct bpf_insn bpf;
- uint16_t dst;
- uint16_t src;
- } insn;
- int16_t label;
- uint16_t reg;
- struct {
- uint16_t reg;
- struct sym *sym;
- } map;
- };
- };
- struct ir {
- struct vinsn *vi;
- size_t len;
- int16_t next_label;
- uint16_t next_reg;
- ssize_t sp;
- };
- enum irloc {
- LOC_IMM = (1 << 0),
- LOC_REG = (1 << 1),
- LOC_STACK = (1 << 2),
- };
- struct irstate {
- int loc;
- size_t size;
- int32_t stack;
- int32_t imm;
- uint16_t reg;
- struct {
- int dot:1;
- int lval:1;
- int stack:1;
- } hint;
- };
- void insn_dump(struct bpf_insn insn, FILE *fp);
- void vinsn_dump(struct vinsn *vi, FILE *fp);
- void ir_dump(struct ir *ir, FILE *fp);
- int16_t ir_alloc_label (struct ir *ir);
- void ir_init_irs(struct ir *ir, struct irstate *irs, struct type *t);
- void ir_init_sym(struct ir *ir, struct sym *sym);
- void ir_emit_insn (struct ir *ir, struct bpf_insn bpf, uint16_t dst, uint16_t src);
- void ir_emit_ldmap (struct ir *ir, uint16_t dst, struct sym *map);
- void ir_emit_label (struct ir *ir, int16_t label);
- void ir_emit_sym_to_reg(struct ir *ir, uint16_t dst, struct sym *src);
- void ir_emit_reg_to_sym(struct ir *ir, struct sym *dst, uint16_t src);
- void ir_emit_sym_to_stack(struct ir *ir, ssize_t offset, struct sym *src);
- void ir_emit_memcpy(struct ir *ir, ssize_t dst, ssize_t src, size_t size);
- void ir_emit_bzero(struct ir *ir, ssize_t offset, size_t size);
- struct ir *ir_new(void);
- #endif /* _PLY_IR_H */
|