A dynamic tracer for Linux

ir.h 3.5KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. #ifndef _PLY_IR_H
  2. #define _PLY_IR_H
  3. #include <stdint.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <bits/wordsize.h>
  7. #include <linux/bpf.h>
  8. #define INSN(_code, _dst, _src, _off, _imm) \
  9. ((struct bpf_insn) { \
  10. .code = _code, \
  11. .dst_reg = _dst, \
  12. .src_reg = _src, \
  13. .off = _off, \
  14. .imm = _imm \
  15. })
  16. #define MOV32 INSN(BPF_ALU | BPF_MOV | BPF_X, 0, 0, 0, 0)
  17. #define MOV32_IMM(_imm) INSN(BPF_ALU | BPF_MOV | BPF_K, 0, 0, 0, _imm)
  18. #define MOV64 INSN(BPF_ALU64 | BPF_MOV | BPF_X, 0, 0, 0, 0)
  19. #define MOV64_IMM(_imm) INSN(BPF_ALU64 | BPF_MOV | BPF_K, 0, 0, 0, _imm)
  20. #define EXIT INSN(BPF_JMP | BPF_EXIT, 0, 0, 0, 0)
  21. #define CALL(_imm) INSN(BPF_JMP | BPF_CALL, 0, 0, 0, _imm)
  22. #define JMP(_op, _off) INSN(BPF_JMP | BPF_OP((_op)) | BPF_X, 0, 0, _off, 0)
  23. #define JMP_IMM(_op, _imm, _off) INSN(BPF_JMP | BPF_OP((_op)) | BPF_K, 0, 0, _off, _imm)
  24. #define ALU32(_op) INSN(BPF_ALU | BPF_OP((_op)) | BPF_X, 0, 0, 0, 0)
  25. #define ALU32_IMM(_op, _imm) INSN(BPF_ALU | BPF_OP((_op)) | BPF_K, 0, 0, 0, _imm)
  26. #define ALU64(_op) INSN(BPF_ALU64 | BPF_OP((_op)) | BPF_X, 0, 0, 0, 0)
  27. #define ALU64_IMM(_op, _imm) INSN(BPF_ALU64 | BPF_OP((_op)) | BPF_K, 0, 0, 0, _imm)
  28. #define ST_IMM(_width, _off, _imm) INSN(BPF_ST | BPF_SIZE(_width) | BPF_MEM, 0, 0, _off, _imm)
  29. #define STX(_width, _off) INSN(BPF_STX | BPF_SIZE(_width) | BPF_MEM, 0, 0, _off, 0)
  30. #define LDX(_width, _off) INSN(BPF_LDX | BPF_SIZE(_width) | BPF_MEM, 0, 0, _off, 0)
  31. #if __WORDSIZE == 64
  32. # define MOV MOV64
  33. # define MOV_IMM MOV64_IMM
  34. # define ALU ALU64
  35. # define ALU_IMM ALU64_IMM
  36. #else
  37. # define MOV MOV32
  38. # define MOV_IMM MOV32_IMM
  39. # define ALU ALU32
  40. # define ALU_IMM ALU32_IMM
  41. #endif
  42. #define BPF_REG_BP BPF_REG_10
  43. static inline int bpf_width(size_t size)
  44. {
  45. switch (size) {
  46. case 1: return BPF_B;
  47. case 2: return BPF_H;
  48. case 4: return BPF_W;
  49. case 8: return BPF_DW;
  50. }
  51. return -1;
  52. }
  53. struct sym;
  54. struct type;
  55. enum vitype {
  56. VI_INSN,
  57. VI_LDMAP,
  58. VI_LABEL,
  59. VI_REG_GET,
  60. VI_REG_PUT,
  61. };
  62. struct vinsn {
  63. enum vitype vitype;
  64. union {
  65. struct {
  66. struct bpf_insn bpf;
  67. uint16_t dst;
  68. uint16_t src;
  69. } insn;
  70. int16_t label;
  71. uint16_t reg;
  72. struct {
  73. uint16_t reg;
  74. struct sym *sym;
  75. } map;
  76. };
  77. };
  78. struct ir {
  79. struct vinsn *vi;
  80. size_t len;
  81. int16_t next_label;
  82. uint16_t next_reg;
  83. ssize_t sp;
  84. };
  85. enum irloc {
  86. LOC_IMM = (1 << 0),
  87. LOC_REG = (1 << 1),
  88. LOC_STACK = (1 << 2),
  89. };
  90. struct irstate {
  91. int loc;
  92. size_t size;
  93. int32_t stack;
  94. int32_t imm;
  95. uint16_t reg;
  96. struct {
  97. int dot:1;
  98. int lval:1;
  99. int stack:1;
  100. } hint;
  101. };
  102. void insn_dump(struct bpf_insn insn, FILE *fp);
  103. void vinsn_dump(struct vinsn *vi, FILE *fp);
  104. void ir_dump(struct ir *ir, FILE *fp);
  105. int16_t ir_alloc_label (struct ir *ir);
  106. void ir_init_irs(struct ir *ir, struct irstate *irs, struct type *t);
  107. void ir_init_sym(struct ir *ir, struct sym *sym);
  108. void ir_emit_insn (struct ir *ir, struct bpf_insn bpf, uint16_t dst, uint16_t src);
  109. void ir_emit_ldmap (struct ir *ir, uint16_t dst, struct sym *map);
  110. void ir_emit_label (struct ir *ir, int16_t label);
  111. void ir_emit_sym_to_reg(struct ir *ir, uint16_t dst, struct sym *src);
  112. void ir_emit_reg_to_sym(struct ir *ir, struct sym *dst, uint16_t src);
  113. void ir_emit_sym_to_stack(struct ir *ir, ssize_t offset, struct sym *src);
  114. void ir_emit_read_to_sym(struct ir *ir, struct sym *dst, uint16_t src);
  115. void ir_emit_memcpy(struct ir *ir, ssize_t dst, ssize_t src, size_t size);
  116. void ir_emit_bzero(struct ir *ir, ssize_t offset, size_t size);
  117. struct ir *ir_new(void);
  118. #endif /* _PLY_IR_H */