Extended Berkeley Packet Filter (eBPF) assembler and virtual machine
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

234 lines
5.1KB

  1. package ebpf
  2. import (
  3. "fmt"
  4. )
  5. type ALUOp uint16
  6. func (op ALUOp) CString() string {
  7. switch op {
  8. case ALUOpAdd:
  9. return "+"
  10. case ALUOpSub:
  11. return "-"
  12. case ALUOpMul:
  13. return "*"
  14. case ALUOpDiv:
  15. return "/"
  16. case ALUOpOr:
  17. return "|"
  18. case ALUOpAnd:
  19. return "&"
  20. case ALUOpShiftLeft:
  21. return "<<"
  22. case ALUOpShiftRight:
  23. return ">>"
  24. case aluOpNegate:
  25. return "!"
  26. case ALUOpMod:
  27. return "%"
  28. case ALUOpXor:
  29. return "^"
  30. default:
  31. return ""
  32. }
  33. }
  34. func (op ALUOp) Mnemoic() string {
  35. switch op {
  36. case ALUOpAdd:
  37. return "add"
  38. case ALUOpSub:
  39. return "sub"
  40. case ALUOpMul:
  41. return "mul"
  42. case ALUOpDiv:
  43. return "div"
  44. case ALUOpOr:
  45. return "or"
  46. case ALUOpAnd:
  47. return "and"
  48. case ALUOpShiftLeft:
  49. return "lsh"
  50. case ALUOpShiftRight:
  51. return "rsh"
  52. case aluOpNegate:
  53. return "neg"
  54. case ALUOpMod:
  55. return "mod"
  56. case ALUOpXor:
  57. return "xor"
  58. case ALUOpMove:
  59. return "mov"
  60. case ALUOpArithmicShiftRight:
  61. return "arsh"
  62. default:
  63. return fmt.Sprintf("# invalid operand %#02x", uint8(op))
  64. }
  65. }
  66. const (
  67. ALUOpAdd ALUOp = iota << 4 // 0x00
  68. ALUOpSub // 0x10
  69. ALUOpMul // 0x20
  70. ALUOpDiv // 0x30
  71. ALUOpOr // 0x40
  72. ALUOpAnd // 0x50
  73. ALUOpShiftLeft // 0x60
  74. ALUOpShiftRight // 0x70
  75. aluOpNegate // 0x80
  76. ALUOpMod // 0x90
  77. ALUOpXor // 0xa0
  78. ALUOpMove // 0xb0
  79. ALUOpArithmicShiftRight // 0xc0
  80. aluOpByteSwap // 0xd0
  81. )
  82. // ALUOpConstant executes Dst = Dst <Op> Value.
  83. type ALUOpConstant struct {
  84. Op ALUOp
  85. Dst Register
  86. Value uint32
  87. }
  88. // Assemble implements the Instruction Assemble method.
  89. func (a ALUOpConstant) Assemble() (RawInstruction, error) {
  90. return RawInstruction{
  91. Op: opClassALU | aluSourceImmediate | Opcode(a.Op),
  92. Dst: a.Dst,
  93. Immediate: uint64(a.Value),
  94. }, nil
  95. }
  96. func (a ALUOpConstant) String() string {
  97. return fmt.Sprintf("%s32 %s, %#x", a.Op.Mnemoic(), a.Dst, a.Value)
  98. }
  99. func (a ALUOpConstant) CString() string {
  100. return fmt.Sprintf("%s %s= (uint32_t)(%x);", a.Dst, a.Op.CString(), a.Value)
  101. }
  102. // ALUOpRegister executes Dst = Dst <Op> Src.
  103. type ALUOpRegister struct {
  104. Op ALUOp
  105. Dst Register
  106. Src Register
  107. }
  108. // Assemble implements the Instruction Assemble method.
  109. func (a ALUOpRegister) Assemble() (RawInstruction, error) {
  110. return RawInstruction{
  111. Op: opClassALU | aluSourceX | Opcode(a.Op),
  112. Dst: a.Dst,
  113. Src: a.Src,
  114. }, nil
  115. }
  116. func (a ALUOpRegister) String() string {
  117. return fmt.Sprintf("%s32 %s, %s", a.Op.Mnemoic(), a.Dst, a.Src)
  118. }
  119. func (a ALUOpRegister) CString() string {
  120. return fmt.Sprintf("%s %s= %x;", a.Dst, a.Op.CString(), a.Src)
  121. }
  122. // Negate executes Dst = !Dst.
  123. type Negate struct {
  124. Dst Register
  125. }
  126. // Assemble implements the Instruction Assemble method.
  127. func (a Negate) Assemble() (RawInstruction, error) {
  128. return RawInstruction{
  129. Op: opClassALU | aluSourceImmediate | Opcode(aluOpNegate),
  130. Dst: a.Dst,
  131. }, nil
  132. }
  133. func (a Negate) String() string {
  134. return fmt.Sprintf("neg32 %s", a.Dst)
  135. }
  136. func (a Negate) CString() string {
  137. return fmt.Sprintf("%s = (uint32_t)(!%s);", a.Dst, a.Dst)
  138. }
  139. // ALU64OpConstant executes Dst = Dst <Op> Value.
  140. type ALU64OpConstant struct {
  141. Op ALUOp
  142. Dst Register
  143. Value uint32
  144. }
  145. // Assemble implements the Instruction Assemble method.
  146. func (a ALU64OpConstant) Assemble() (RawInstruction, error) {
  147. return RawInstruction{
  148. Op: opClassALU64 | aluSourceImmediate | Opcode(a.Op),
  149. Dst: a.Dst,
  150. Immediate: uint64(a.Value),
  151. }, nil
  152. }
  153. func (a ALU64OpConstant) String() string {
  154. return fmt.Sprintf("%s %s, %#x", a.Op.Mnemoic(), a.Dst, a.Value)
  155. }
  156. func (a ALU64OpConstant) CString() string {
  157. return fmt.Sprintf("%s %s= %#x;", a.Dst, a.Op.CString(), a.Value)
  158. }
  159. // ALU64OpRegister executes Dst = Dst <Op> Src.
  160. type ALU64OpRegister struct {
  161. Op ALUOp
  162. Dst Register
  163. Src Register
  164. }
  165. // Assemble implements the Instruction Assemble method.
  166. func (a ALU64OpRegister) Assemble() (RawInstruction, error) {
  167. return RawInstruction{
  168. Op: opClassALU64 | aluSourceX | Opcode(a.Op),
  169. Dst: a.Dst,
  170. Src: a.Src,
  171. }, nil
  172. }
  173. func (a ALU64OpRegister) String() string {
  174. return fmt.Sprintf("%s %s, %s", a.Op.Mnemoic(), a.Dst, a.Src)
  175. }
  176. func (a ALU64OpRegister) CString() string {
  177. return fmt.Sprintf("%s %s= %s", a.Dst, a.Op.CString(), a.Src)
  178. }
  179. // Negate64 executes Dst = !Dst.
  180. type Negate64 struct {
  181. Dst Register
  182. }
  183. // Assemble implements the Instruction Assemble method.
  184. func (a Negate64) Assemble() (RawInstruction, error) {
  185. return RawInstruction{
  186. Op: opClassALU64 | aluSourceImmediate | Opcode(aluOpNegate),
  187. Dst: a.Dst,
  188. }, nil
  189. }
  190. func (a Negate64) String() string {
  191. return fmt.Sprintf("neg %s", a.Dst)
  192. }
  193. func (a Negate64) CString() string {
  194. return fmt.Sprintf("%s = !%s", a.Dst, a.Dst)
  195. }
  196. var (
  197. _ Instruction = (*ALUOpConstant)(nil)
  198. _ Instruction = (*ALUOpRegister)(nil)
  199. _ Instruction = (*Negate)(nil)
  200. _ Instruction = (*ALU64OpConstant)(nil)
  201. _ Instruction = (*ALU64OpRegister)(nil)
  202. _ Instruction = (*Negate64)(nil)
  203. )