A dynamic tracer for Linux

ir.h 3.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  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 MOV(_dst, _src) INSN(BPF_ALU64 | BPF_MOV | BPF_X, _dst, _src, 0, 0)
  17. #define MOV_IMM(_dst, _imm) INSN(BPF_ALU64 | BPF_MOV | BPF_K, _dst, 0, 0, _imm)
  18. #define EXIT INSN(BPF_JMP | BPF_EXIT, 0, 0, 0, 0)
  19. #define CALL(_imm) INSN(BPF_JMP | BPF_CALL, 0, 0, 0, _imm)
  20. #define JMP(_op, _dst, _src, _off) INSN(BPF_JMP | BPF_OP((_op)) | BPF_X, _dst, _src, _off, 0)
  21. #define JMP_IMM(_op, _dst, _imm, _off) INSN(BPF_JMP | BPF_OP((_op)) | BPF_K, _dst, 0, _off, _imm)
  22. #define ALU32(_op, _dst, _src) INSN(BPF_ALU | BPF_OP((_op)) | BPF_X, _dst, _src, 0, 0)
  23. #define ALU32_IMM(_op, _dst, _imm) INSN(BPF_ALU | BPF_OP((_op)) | BPF_K, _dst, 0, 0, _imm)
  24. #define ALU64(_op, _dst, _src) INSN(BPF_ALU64 | BPF_OP((_op)) | BPF_X, _dst, _src, 0, 0)
  25. #define ALU64_IMM(_op, _dst, _imm) INSN(BPF_ALU64 | BPF_OP((_op)) | BPF_K, _dst, 0, 0, _imm)
  26. #define STW_IMM(_dst, _off, _imm) INSN(BPF_ST | BPF_SIZE(BPF_W) | BPF_MEM, _dst, 0, _off, _imm)
  27. #define STXB(_dst, _off, _src) INSN(BPF_STX | BPF_SIZE(BPF_B) | BPF_MEM, _dst, _src, _off, 0)
  28. #define STXH(_dst, _off, _src) INSN(BPF_STX | BPF_SIZE(BPF_H) | BPF_MEM, _dst, _src, _off, 0)
  29. #define STXW(_dst, _off, _src) INSN(BPF_STX | BPF_SIZE(BPF_W) | BPF_MEM, _dst, _src, _off, 0)
  30. #define STXDW(_dst, _off, _src) INSN(BPF_STX | BPF_SIZE(BPF_DW) | BPF_MEM, _dst, _src, _off, 0)
  31. #define LDXB(_dst, _off, _src) INSN(BPF_LDX | BPF_SIZE(BPF_B) | BPF_MEM, _dst, _src, _off, 0)
  32. #define LDXH(_dst, _off, _src) INSN(BPF_LDX | BPF_SIZE(BPF_H) | BPF_MEM, _dst, _src, _off, 0)
  33. #define LDXW(_dst, _off, _src) INSN(BPF_LDX | BPF_SIZE(BPF_W) | BPF_MEM, _dst, _src, _off, 0)
  34. #define LDXDW(_dst, _off, _src) INSN(BPF_LDX | BPF_SIZE(BPF_DW) | BPF_MEM, _dst, _src, _off, 0)
  35. #if __WORDSIZE == 64
  36. # define ALU ALU64
  37. # define ALU_IMM ALU64_IMM
  38. # define STX STXDW
  39. # define LDX LDXDW
  40. #else
  41. # define ALU ALU32
  42. # define ALU_IMM ALU32_IMM
  43. # define STX STXW
  44. # define LDX LDXW
  45. #endif
  46. #define BPF_REG_BP BPF_REG_10
  47. struct sym;
  48. enum vitype {
  49. VI_INSN,
  50. VI_LDMAP,
  51. VI_LABEL,
  52. VI_REG_GET,
  53. VI_REG_PUT,
  54. };
  55. struct vinsn {
  56. enum vitype vitype;
  57. union {
  58. struct {
  59. struct bpf_insn bpf;
  60. uint16_t dst;
  61. uint16_t src;
  62. } insn;
  63. int16_t label;
  64. uint16_t reg;
  65. struct {
  66. uint16_t reg;
  67. struct sym *sym;
  68. } map;
  69. };
  70. };
  71. struct ir {
  72. struct vinsn *vi;
  73. size_t len;
  74. int16_t next_label;
  75. uint16_t next_reg;
  76. ssize_t sp;
  77. };
  78. enum irloc {
  79. LOC_IMM = (1 << 0),
  80. LOC_REG = (1 << 1),
  81. LOC_STACK = (1 << 2),
  82. };
  83. struct irstate {
  84. int loc;
  85. size_t size;
  86. int32_t stack;
  87. int32_t imm;
  88. uint16_t reg;
  89. struct {
  90. int dot:1;
  91. int lval:1;
  92. int stack:1;
  93. } hint;
  94. };
  95. void insn_dump(struct bpf_insn insn, FILE *fp);
  96. void vinsn_dump(struct vinsn *vi, FILE *fp);
  97. void ir_dump(struct ir *ir, FILE *fp);
  98. int16_t ir_alloc_label (struct ir *ir);
  99. uint16_t ir_alloc_register(struct ir *ir);
  100. ssize_t ir_alloc_stack (struct ir *ir, size_t size);
  101. void ir_init_sym(struct ir *ir, struct sym *sym);
  102. void ir_emit_insn (struct ir *ir, struct bpf_insn bpf, uint16_t dst, uint16_t src);
  103. void ir_emit_ldmap (struct ir *ir, uint16_t dst, struct sym *map);
  104. void ir_emit_label (struct ir *ir, int16_t label);
  105. /* void ir_emit_reg_get(struct ir *ir, uint16_t reg); */
  106. /* void ir_emit_reg_put(struct ir *ir, uint16_t reg); */
  107. void ir_emit_sym_to_reg(struct ir *ir, uint16_t dst, struct sym *src);
  108. void ir_emit_reg_to_sym(struct ir *ir, struct sym *dst, uint16_t src);
  109. struct ir *ir_new(void);
  110. #endif /* _PLY_IR_H */