A dynamic tracer for Linux

ir.h 2.6KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485
  1. #ifndef _PLY_IR_H
  2. #define _PLY_IR_H
  3. #include <stdint.h>
  4. #include <stdlib.h>
  5. #include <linux/bpf.h>
  6. #define INSN(_code, _dst, _src, _off, _imm) \
  7. ((struct bpf_insn) { \
  8. .code = _code, \
  9. .dst_reg = _dst, \
  10. .src_reg = _src, \
  11. .off = _off, \
  12. .imm = _imm \
  13. })
  14. #define MOV(_dst, _src) INSN(BPF_ALU64 | BPF_MOV | BPF_X, _dst, _src, 0, 0)
  15. #define MOV_IMM(_dst, _imm) INSN(BPF_ALU64 | BPF_MOV | BPF_K, _dst, 0, 0, _imm)
  16. #define EXIT INSN(BPF_JMP | BPF_EXIT, 0, 0, 0, 0)
  17. #define CALL(_imm) INSN(BPF_JMP | BPF_CALL, 0, 0, 0, _imm)
  18. #define JMP(_op, _dst, _src, _off) INSN(BPF_JMP | BPF_OP((_op)) | BPF_X, _dst, _src, _off, 0)
  19. #define JMP_IMM(_op, _dst, _imm, _off) INSN(BPF_JMP | BPF_OP((_op)) | BPF_K, _dst, 0, _off, _imm)
  20. #define ALU(_op, _dst, _src) INSN(BPF_ALU64 | BPF_OP((_op)) | BPF_X, _dst, _src, 0, 0)
  21. #define ALU_IMM(_op, _dst, _imm) INSN(BPF_ALU64 | BPF_OP((_op)) | BPF_K, _dst, 0, 0, _imm)
  22. #define STW_IMM(_dst, _off, _imm) INSN(BPF_ST | BPF_SIZE(BPF_W) | BPF_MEM, _dst, 0, _off, _imm)
  23. #define STXB(_dst, _off, _src) INSN(BPF_STX | BPF_SIZE(BPF_B) | BPF_MEM, _dst, _src, _off, 0)
  24. #define STXH(_dst, _off, _src) INSN(BPF_STX | BPF_SIZE(BPF_H) | BPF_MEM, _dst, _src, _off, 0)
  25. #define STXW(_dst, _off, _src) INSN(BPF_STX | BPF_SIZE(BPF_W) | BPF_MEM, _dst, _src, _off, 0)
  26. #define STXDW(_dst, _off, _src) INSN(BPF_STX | BPF_SIZE(BPF_DW) | BPF_MEM, _dst, _src, _off, 0)
  27. #define LDXB(_dst, _off, _src) INSN(BPF_LDX | BPF_SIZE(BPF_B) | BPF_MEM, _dst, _src, _off, 0)
  28. #define LDXH(_dst, _off, _src) INSN(BPF_LDX | BPF_SIZE(BPF_H) | BPF_MEM, _dst, _src, _off, 0)
  29. #define LDXW(_dst, _off, _src) INSN(BPF_LDX | BPF_SIZE(BPF_W) | BPF_MEM, _dst, _src, _off, 0)
  30. #define LDXDW(_dst, _off, _src) INSN(BPF_LDX | BPF_SIZE(BPF_DW) | BPF_MEM, _dst, _src, _off, 0)
  31. typedef enum vitype {
  32. VI_INSN,
  33. VI_LABEL,
  34. VI_REG_GET,
  35. VI_REG_PUT,
  36. } vitype_t;
  37. typedef struct vinsn {
  38. vitype_t vitype;
  39. union {
  40. struct {
  41. struct bpf_insn bpf;
  42. uint16_t dst;
  43. uint16_t src;
  44. } insn;
  45. int16_t label;
  46. uint16_t reg;
  47. };
  48. } vinsn_t;
  49. typedef struct ir {
  50. vinsn_t *vi;
  51. size_t len;
  52. int16_t next_label;
  53. uint16_t next_reg;
  54. } ir_t;
  55. void insn_dump(struct bpf_insn insn, FILE *fp);
  56. void vinsn_dump(vinsn_t *vi, FILE *fp);
  57. void ir_dump(ir_t *ir, FILE *fp);
  58. int16_t ir_alloc_label (ir_t *ir);
  59. uint16_t ir_alloc_register(ir_t *ir);
  60. void ir_emit_insn (ir_t *ir, struct bpf_insn bpf, uint16_t dst, uint16_t src);
  61. void ir_emit_label (ir_t *ir, int16_t label);
  62. void ir_emit_reg_get(ir_t *ir, uint16_t reg);
  63. void ir_emit_reg_put(ir_t *ir, uint16_t reg);
  64. ir_t *ir_new(void);
  65. #endif /* _PLY_IR_H */