ubpf_vm.rs 38 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611
  1. // Converted from the tests for uBPF <https://github.com/iovisor/ubpf>
  2. // Copyright 2015 Big Switch Networks, Inc
  3. // Copyright 2016 6WIND S.A. <quentin.monnet@6wind.com>
  4. //
  5. // Licensed under the Apache License, Version 2.0 <http://www.apache.org/licenses/LICENSE-2.0> or
  6. // the MIT license <http://opensource.org/licenses/MIT>, at your option. This file may not be
  7. // copied, modified, or distributed except according to those terms.
  8. // The tests contained in this file are extracted from the unit tests of uBPF software. Each test
  9. // in this file has a name in the form `test_vm_<name>`, and corresponds to the (human-readable)
  10. // code in `ubpf/tree/master/tests/<name>`, available at
  11. // <https://github.com/iovisor/ubpf/tree/master/tests> (hyphen had to be replaced with underscores
  12. // as Rust will not accept them in function names). It is strongly advised to refer to the uBPF
  13. // version to understand what these program do.
  14. //
  15. // Each program was assembled from the uBPF version with the assembler provided by uBPF itself, and
  16. // available at <https://github.com/iovisor/ubpf/tree/master/ubpf>.
  17. // The very few modifications that have been realized should be indicated.
  18. // These are unit tests for the eBPF interpreter.
  19. #![cfg_attr(feature = "cargo-clippy", allow(unreadable_literal))]
  20. extern crate rbpf;
  21. mod common;
  22. use rbpf::helpers;
  23. use rbpf::assembler::assemble;
  24. use common::{TCP_SACK_ASM, TCP_SACK_MATCH, TCP_SACK_NOMATCH};
  25. #[test]
  26. fn test_vm_add() {
  27. let prog = assemble("
  28. mov32 r0, 0
  29. mov32 r1, 2
  30. add32 r0, 1
  31. add32 r0, r1
  32. exit").unwrap();
  33. let vm = rbpf::EbpfVmNoData::new(&prog);
  34. assert_eq!(vm.prog_exec(), 0x3);
  35. }
  36. #[test]
  37. fn test_vm_alu64_arith() {
  38. let prog = assemble("
  39. mov r0, 0
  40. mov r1, 1
  41. mov r2, 2
  42. mov r3, 3
  43. mov r4, 4
  44. mov r5, 5
  45. mov r6, 6
  46. mov r7, 7
  47. mov r8, 8
  48. mov r9, 9
  49. add r0, 23
  50. add r0, r7
  51. sub r0, 13
  52. sub r0, r1
  53. mul r0, 7
  54. mul r0, r3
  55. div r0, 2
  56. div r0, r4
  57. exit").unwrap();
  58. let vm = rbpf::EbpfVmNoData::new(&prog);
  59. assert_eq!(vm.prog_exec(), 0x2a);
  60. }
  61. #[test]
  62. fn test_vm_alu64_bit() {
  63. let prog = assemble("
  64. mov r0, 0
  65. mov r1, 1
  66. mov r2, 2
  67. mov r3, 3
  68. mov r4, 4
  69. mov r5, 5
  70. mov r6, 6
  71. mov r7, 7
  72. mov r8, 8
  73. or r0, r5
  74. or r0, 0xa0
  75. and r0, 0xa3
  76. mov r9, 0x91
  77. and r0, r9
  78. lsh r0, 32
  79. lsh r0, 22
  80. lsh r0, r8
  81. rsh r0, 32
  82. rsh r0, 19
  83. rsh r0, r7
  84. xor r0, 0x03
  85. xor r0, r2
  86. exit").unwrap();
  87. let vm = rbpf::EbpfVmNoData::new(&prog);
  88. assert_eq!(vm.prog_exec(), 0x11);
  89. }
  90. #[test]
  91. fn test_vm_alu_arith() {
  92. let prog = assemble("
  93. mov32 r0, 0
  94. mov32 r1, 1
  95. mov32 r2, 2
  96. mov32 r3, 3
  97. mov32 r4, 4
  98. mov32 r5, 5
  99. mov32 r6, 6
  100. mov32 r7, 7
  101. mov32 r8, 8
  102. mov32 r9, 9
  103. add32 r0, 23
  104. add32 r0, r7
  105. sub32 r0, 13
  106. sub32 r0, r1
  107. mul32 r0, 7
  108. mul32 r0, r3
  109. div32 r0, 2
  110. div32 r0, r4
  111. exit").unwrap();
  112. let vm = rbpf::EbpfVmNoData::new(&prog);
  113. assert_eq!(vm.prog_exec(), 0x2a);
  114. }
  115. #[test]
  116. fn test_vm_alu_bit() {
  117. let prog = assemble("
  118. mov32 r0, 0
  119. mov32 r1, 1
  120. mov32 r2, 2
  121. mov32 r3, 3
  122. mov32 r4, 4
  123. mov32 r5, 5
  124. mov32 r6, 6
  125. mov32 r7, 7
  126. mov32 r8, 8
  127. or32 r0, r5
  128. or32 r0, 0xa0
  129. and32 r0, 0xa3
  130. mov32 r9, 0x91
  131. and32 r0, r9
  132. lsh32 r0, 22
  133. lsh32 r0, r8
  134. rsh32 r0, 19
  135. rsh32 r0, r7
  136. xor32 r0, 0x03
  137. xor32 r0, r2
  138. exit").unwrap();
  139. let vm = rbpf::EbpfVmNoData::new(&prog);
  140. assert_eq!(vm.prog_exec(), 0x11);
  141. }
  142. #[test]
  143. fn test_vm_arsh32_high_shift() {
  144. let prog = assemble("
  145. mov r0, 8
  146. lddw r1, 0x100000001
  147. arsh32 r0, r1
  148. exit").unwrap();
  149. let vm = rbpf::EbpfVmNoData::new(&prog);
  150. assert_eq!(vm.prog_exec(), 0x4);
  151. }
  152. #[test]
  153. fn test_vm_arsh() {
  154. let prog = assemble("
  155. mov32 r0, 0xf8
  156. lsh32 r0, 28
  157. arsh32 r0, 16
  158. exit").unwrap();
  159. let vm = rbpf::EbpfVmNoData::new(&prog);
  160. assert_eq!(vm.prog_exec(), 0xffff8000);
  161. }
  162. #[test]
  163. fn test_vm_arsh64() {
  164. let prog = assemble("
  165. mov32 r0, 1
  166. lsh r0, 63
  167. arsh r0, 55
  168. mov32 r1, 5
  169. arsh r0, r1
  170. exit").unwrap();
  171. let vm = rbpf::EbpfVmNoData::new(&prog);
  172. assert_eq!(vm.prog_exec(), 0xfffffffffffffff8);
  173. }
  174. #[test]
  175. fn test_vm_arsh_reg() {
  176. let prog = assemble("
  177. mov32 r0, 0xf8
  178. mov32 r1, 16
  179. lsh32 r0, 28
  180. arsh32 r0, r1
  181. exit").unwrap();
  182. let vm = rbpf::EbpfVmNoData::new(&prog);
  183. assert_eq!(vm.prog_exec(), 0xffff8000);
  184. }
  185. #[test]
  186. fn test_vm_be16() {
  187. let prog = assemble("
  188. ldxh r0, [r1]
  189. be16 r0
  190. exit").unwrap();
  191. let mem = &mut [
  192. 0x11, 0x22
  193. ];
  194. let vm = rbpf::EbpfVmRaw::new(&prog);
  195. assert_eq!(vm.prog_exec(mem), 0x1122);
  196. }
  197. #[test]
  198. fn test_vm_be16_high() {
  199. let prog = assemble("
  200. ldxdw r0, [r1]
  201. be16 r0
  202. exit").unwrap();
  203. let mem = &mut [
  204. 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88
  205. ];
  206. let vm = rbpf::EbpfVmRaw::new(&prog);
  207. assert_eq!(vm.prog_exec(mem), 0x1122);
  208. }
  209. #[test]
  210. fn test_vm_be32() {
  211. let prog = assemble("
  212. ldxw r0, [r1]
  213. be32 r0
  214. exit").unwrap();
  215. let mem = &mut [
  216. 0x11, 0x22, 0x33, 0x44
  217. ];
  218. let vm = rbpf::EbpfVmRaw::new(&prog);
  219. assert_eq!(vm.prog_exec(mem), 0x11223344);
  220. }
  221. #[test]
  222. fn test_vm_be32_high() {
  223. let prog = assemble("
  224. ldxdw r0, [r1]
  225. be32 r0
  226. exit").unwrap();
  227. let mem = &mut [
  228. 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88
  229. ];
  230. let vm = rbpf::EbpfVmRaw::new(&prog);
  231. assert_eq!(vm.prog_exec(mem), 0x11223344);
  232. }
  233. #[test]
  234. fn test_vm_be64() {
  235. let prog = assemble("
  236. ldxdw r0, [r1]
  237. be64 r0
  238. exit").unwrap();
  239. let mem = &mut [
  240. 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88
  241. ];
  242. let vm = rbpf::EbpfVmRaw::new(&prog);
  243. assert_eq!(vm.prog_exec(mem), 0x1122334455667788);
  244. }
  245. #[test]
  246. fn test_vm_call() {
  247. let prog = assemble("
  248. mov r1, 1
  249. mov r2, 2
  250. mov r3, 3
  251. mov r4, 4
  252. mov r5, 5
  253. call 0
  254. exit").unwrap();
  255. let mut vm = rbpf::EbpfVmNoData::new(&prog);
  256. vm.register_helper(0, helpers::gather_bytes);
  257. assert_eq!(vm.prog_exec(), 0x0102030405);
  258. }
  259. #[test]
  260. fn test_vm_call_memfrob() {
  261. let prog = assemble("
  262. mov r6, r1
  263. add r1, 2
  264. mov r2, 4
  265. call 1
  266. ldxdw r0, [r6]
  267. be64 r0
  268. exit").unwrap();
  269. let mem = &mut [
  270. 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08
  271. ];
  272. let mut vm = rbpf::EbpfVmRaw::new(&prog);
  273. vm.register_helper(1, helpers::memfrob);
  274. assert_eq!(vm.prog_exec(mem), 0x102292e2f2c0708);
  275. }
  276. // TODO: helpers::trash_registers needs asm!().
  277. // Try this again once asm!() is available in stable.
  278. //#[test]
  279. //fn test_vm_call_save() {
  280. //let prog = &[
  281. //0xb7, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
  282. //0xb7, 0x07, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00,
  283. //0xb7, 0x08, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00,
  284. //0xb7, 0x09, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00,
  285. //0x85, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
  286. //0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  287. //0x4f, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  288. //0x4f, 0x70, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  289. //0x4f, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  290. //0x4f, 0x90, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  291. //0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  292. //];
  293. //let mut vm = rbpf::EbpfVmNoData::new(prog);
  294. //vm.register_helper(2, helpers::trash_registers);
  295. //assert_eq!(vm.prog_exec(), 0x4321);
  296. //}
  297. #[test]
  298. fn test_vm_div32_high_divisor() {
  299. let prog = assemble("
  300. mov r0, 12
  301. lddw r1, 0x100000004
  302. div32 r0, r1
  303. exit").unwrap();
  304. let vm = rbpf::EbpfVmNoData::new(&prog);
  305. assert_eq!(vm.prog_exec(), 0x3);
  306. }
  307. #[test]
  308. fn test_vm_div32_imm() {
  309. let prog = assemble("
  310. lddw r0, 0x10000000c
  311. div32 r0, 4
  312. exit").unwrap();
  313. let vm = rbpf::EbpfVmNoData::new(&prog);
  314. assert_eq!(vm.prog_exec(), 0x3);
  315. }
  316. #[test]
  317. fn test_vm_div32_reg() {
  318. let prog = assemble("
  319. lddw r0, 0x10000000c
  320. mov r1, 4
  321. div32 r0, r1
  322. exit").unwrap();
  323. let vm = rbpf::EbpfVmNoData::new(&prog);
  324. assert_eq!(vm.prog_exec(), 0x3);
  325. }
  326. #[test]
  327. fn test_vm_div64_imm() {
  328. let prog = assemble("
  329. mov r0, 0xc
  330. lsh r0, 32
  331. div r0, 4
  332. exit").unwrap();
  333. let vm = rbpf::EbpfVmNoData::new(&prog);
  334. assert_eq!(vm.prog_exec(), 0x300000000);
  335. }
  336. #[test]
  337. fn test_vm_div64_reg() {
  338. let prog = assemble("
  339. mov r0, 0xc
  340. lsh r0, 32
  341. mov r1, 4
  342. div r0, r1
  343. exit").unwrap();
  344. let vm = rbpf::EbpfVmNoData::new(&prog);
  345. assert_eq!(vm.prog_exec(), 0x300000000);
  346. }
  347. #[test]
  348. fn test_vm_early_exit() {
  349. let prog = assemble("
  350. mov r0, 3
  351. exit
  352. mov r0, 4
  353. exit").unwrap();
  354. let vm = rbpf::EbpfVmNoData::new(&prog);
  355. assert_eq!(vm.prog_exec(), 0x3);
  356. }
  357. // uBPF limits the number of user functions at 64. We don't.
  358. //#[test]
  359. //fn test_vm_err_call_bad_imm() {
  360. //}
  361. #[test]
  362. #[should_panic(expected = "Error: unknown helper function (id: 0x3f)")]
  363. fn test_vm_err_call_unreg() {
  364. let prog = assemble("
  365. mov r1, 1
  366. mov r2, 2
  367. mov r3, 3
  368. mov r4, 4
  369. mov r5, 5
  370. call 63
  371. exit").unwrap();
  372. let vm = rbpf::EbpfVmNoData::new(&prog);
  373. vm.prog_exec();
  374. }
  375. #[test]
  376. #[should_panic(expected = "Error: division by 0")]
  377. fn test_vm_err_div64_by_zero_reg() {
  378. let prog = assemble("
  379. mov32 r0, 1
  380. mov32 r1, 0
  381. div r0, r1
  382. exit").unwrap();
  383. let vm = rbpf::EbpfVmNoData::new(&prog);
  384. vm.prog_exec();
  385. }
  386. #[test]
  387. #[should_panic(expected = "Error: division by 0")]
  388. fn test_vm_err_div_by_zero_reg() {
  389. let prog = assemble("
  390. mov32 r0, 1
  391. mov32 r1, 0
  392. div32 r0, r1
  393. exit").unwrap();
  394. let vm = rbpf::EbpfVmNoData::new(&prog);
  395. vm.prog_exec();
  396. }
  397. #[test]
  398. #[should_panic(expected = "Error: division by 0")]
  399. fn test_vm_err_mod64_by_zero_reg() {
  400. let prog = assemble("
  401. mov32 r0, 1
  402. mov32 r1, 0
  403. mod r0, r1
  404. exit").unwrap();
  405. let vm = rbpf::EbpfVmNoData::new(&prog);
  406. vm.prog_exec();
  407. }
  408. #[test]
  409. #[should_panic(expected = "Error: division by 0")]
  410. fn test_vm_err_mod_by_zero_reg() {
  411. let prog = assemble("
  412. mov32 r0, 1
  413. mov32 r1, 0
  414. mod32 r0, r1
  415. exit").unwrap();
  416. let vm = rbpf::EbpfVmNoData::new(&prog);
  417. vm.prog_exec();
  418. }
  419. #[test]
  420. #[should_panic(expected = "Error: out of bounds memory store (insn #1)")]
  421. fn test_vm_err_stack_out_of_bound() {
  422. let prog = assemble("
  423. stb [r10], 0
  424. exit").unwrap();
  425. let vm = rbpf::EbpfVmNoData::new(&prog);
  426. vm.prog_exec();
  427. }
  428. #[test]
  429. fn test_vm_exit() {
  430. let prog = assemble("
  431. mov r0, 0
  432. exit").unwrap();
  433. let vm = rbpf::EbpfVmNoData::new(&prog);
  434. assert_eq!(vm.prog_exec(), 0x0);
  435. }
  436. #[test]
  437. fn test_vm_ja() {
  438. let prog = assemble("
  439. mov r0, 1
  440. ja +1
  441. mov r0, 2
  442. exit").unwrap();
  443. let vm = rbpf::EbpfVmNoData::new(&prog);
  444. assert_eq!(vm.prog_exec(), 0x1);
  445. }
  446. #[test]
  447. fn test_vm_jeq_imm() {
  448. let prog = assemble("
  449. mov32 r0, 0
  450. mov32 r1, 0xa
  451. jeq r1, 0xb, +4
  452. mov32 r0, 1
  453. mov32 r1, 0xb
  454. jeq r1, 0xb, +1
  455. mov32 r0, 2
  456. exit").unwrap();
  457. let vm = rbpf::EbpfVmNoData::new(&prog);
  458. assert_eq!(vm.prog_exec(), 0x1);
  459. }
  460. #[test]
  461. fn test_vm_jeq_reg() {
  462. let prog = assemble("
  463. mov32 r0, 0
  464. mov32 r1, 0xa
  465. mov32 r2, 0xb
  466. jeq r1, r2, +4
  467. mov32 r0, 1
  468. mov32 r1, 0xb
  469. jeq r1, r2, +1
  470. mov32 r0, 2
  471. exit").unwrap();
  472. let vm = rbpf::EbpfVmNoData::new(&prog);
  473. assert_eq!(vm.prog_exec(), 0x1);
  474. }
  475. #[test]
  476. fn test_vm_jge_imm() {
  477. let prog = assemble("
  478. mov32 r0, 0
  479. mov32 r1, 0xa
  480. jge r1, 0xb, +4
  481. mov32 r0, 1
  482. mov32 r1, 0xc
  483. jge r1, 0xb, +1
  484. mov32 r0, 2
  485. exit").unwrap();
  486. let vm = rbpf::EbpfVmNoData::new(&prog);
  487. assert_eq!(vm.prog_exec(), 0x1);
  488. }
  489. #[test]
  490. fn test_vm_jgt_imm() {
  491. let prog = assemble("
  492. mov32 r0, 0
  493. mov32 r1, 5
  494. jgt r1, 6, +2
  495. jgt r1, 5, +1
  496. jgt r1, 4, +1
  497. exit
  498. mov32 r0, 1
  499. exit").unwrap();
  500. let vm = rbpf::EbpfVmNoData::new(&prog);
  501. assert_eq!(vm.prog_exec(), 0x1);
  502. }
  503. #[test]
  504. fn test_vm_jgt_reg() {
  505. let prog = assemble("
  506. mov r0, 0
  507. mov r1, 5
  508. mov r2, 6
  509. mov r3, 4
  510. jgt r1, r2, +2
  511. jgt r1, r1, +1
  512. jgt r1, r3, +1
  513. exit
  514. mov r0, 1
  515. exit").unwrap();
  516. let vm = rbpf::EbpfVmNoData::new(&prog);
  517. assert_eq!(vm.prog_exec(), 0x1);
  518. }
  519. #[test]
  520. fn test_vm_jit_bounce() {
  521. let prog = assemble("
  522. mov r0, 1
  523. mov r6, r0
  524. mov r7, r6
  525. mov r8, r7
  526. mov r9, r8
  527. mov r0, r9
  528. exit").unwrap();
  529. let vm = rbpf::EbpfVmNoData::new(&prog);
  530. assert_eq!(vm.prog_exec(), 0x1);
  531. }
  532. #[test]
  533. fn test_vm_jne_reg() {
  534. let prog = assemble("
  535. mov32 r0, 0
  536. mov32 r1, 0xb
  537. mov32 r2, 0xb
  538. jne r1, r2, +4
  539. mov32 r0, 1
  540. mov32 r1, 0xa
  541. jne r1, r2, +1
  542. mov32 r0, 2
  543. exit").unwrap();
  544. let vm = rbpf::EbpfVmNoData::new(&prog);
  545. assert_eq!(vm.prog_exec(), 0x1);
  546. }
  547. #[test]
  548. fn test_vm_jset_imm() {
  549. let prog = assemble("
  550. mov32 r0, 0
  551. mov32 r1, 0x7
  552. jset r1, 0x8, +4
  553. mov32 r0, 1
  554. mov32 r1, 0x9
  555. jset r1, 0x8, +1
  556. mov32 r0, 2
  557. exit").unwrap();
  558. let vm = rbpf::EbpfVmNoData::new(&prog);
  559. assert_eq!(vm.prog_exec(), 0x1);
  560. }
  561. #[test]
  562. fn test_vm_jset_reg() {
  563. let prog = assemble("
  564. mov32 r0, 0
  565. mov32 r1, 0x7
  566. mov32 r2, 0x8
  567. jset r1, r2, +4
  568. mov32 r0, 1
  569. mov32 r1, 0x9
  570. jset r1, r2, +1
  571. mov32 r0, 2
  572. exit").unwrap();
  573. let vm = rbpf::EbpfVmNoData::new(&prog);
  574. assert_eq!(vm.prog_exec(), 0x1);
  575. }
  576. #[test]
  577. fn test_vm_jsge_imm() {
  578. let prog = assemble("
  579. mov32 r0, 0
  580. mov r1, -2
  581. jsge r1, -1, +5
  582. jsge r1, 0, +4
  583. mov32 r0, 1
  584. mov r1, -1
  585. jsge r1, -1, +1
  586. mov32 r0, 2
  587. exit").unwrap();
  588. let vm = rbpf::EbpfVmNoData::new(&prog);
  589. assert_eq!(vm.prog_exec(), 0x1);
  590. }
  591. #[test]
  592. fn test_vm_jsge_reg() {
  593. let prog = assemble("
  594. mov32 r0, 0
  595. mov r1, -2
  596. mov r2, -1
  597. mov32 r3, 0
  598. jsge r1, r2, +5
  599. jsge r1, r3, +4
  600. mov32 r0, 1
  601. mov r1, r2
  602. jsge r1, r2, +1
  603. mov32 r0, 2
  604. exit").unwrap();
  605. let vm = rbpf::EbpfVmNoData::new(&prog);
  606. assert_eq!(vm.prog_exec(), 0x1);
  607. }
  608. #[test]
  609. fn test_vm_jsgt_imm() {
  610. let prog = assemble("
  611. mov32 r0, 0
  612. mov r1, -2
  613. jsgt r1, -1, +4
  614. mov32 r0, 1
  615. mov32 r1, 0
  616. jsgt r1, -1, +1
  617. mov32 r0, 2
  618. exit").unwrap();
  619. let vm = rbpf::EbpfVmNoData::new(&prog);
  620. assert_eq!(vm.prog_exec(), 0x1);
  621. }
  622. #[test]
  623. fn test_vm_jsgt_reg() {
  624. let prog = assemble("
  625. mov32 r0, 0
  626. mov r1, -2
  627. mov r2, -1
  628. jsgt r1, r2, +4
  629. mov32 r0, 1
  630. mov32 r1, 0
  631. jsgt r1, r2, +1
  632. mov32 r0, 2
  633. exit").unwrap();
  634. let vm = rbpf::EbpfVmNoData::new(&prog);
  635. assert_eq!(vm.prog_exec(), 0x1);
  636. }
  637. #[test]
  638. fn test_vm_lddw() {
  639. let prog = assemble("lddw r0, 0x1122334455667788
  640. exit").unwrap();
  641. let vm = rbpf::EbpfVmNoData::new(&prog);
  642. assert_eq!(vm.prog_exec(), 0x1122334455667788);
  643. }
  644. #[test]
  645. fn test_vm_lddw2() {
  646. let prog = assemble("
  647. lddw r0, 0x0000000080000000
  648. exit").unwrap();
  649. let vm = rbpf::EbpfVmNoData::new(&prog);
  650. assert_eq!(vm.prog_exec(), 0x80000000);
  651. }
  652. #[test]
  653. fn test_vm_ldxb_all() {
  654. let prog = assemble("
  655. mov r0, r1
  656. ldxb r9, [r0+0]
  657. lsh r9, 0
  658. ldxb r8, [r0+1]
  659. lsh r8, 4
  660. ldxb r7, [r0+2]
  661. lsh r7, 8
  662. ldxb r6, [r0+3]
  663. lsh r6, 12
  664. ldxb r5, [r0+4]
  665. lsh r5, 16
  666. ldxb r4, [r0+5]
  667. lsh r4, 20
  668. ldxb r3, [r0+6]
  669. lsh r3, 24
  670. ldxb r2, [r0+7]
  671. lsh r2, 28
  672. ldxb r1, [r0+8]
  673. lsh r1, 32
  674. ldxb r0, [r0+9]
  675. lsh r0, 36
  676. or r0, r1
  677. or r0, r2
  678. or r0, r3
  679. or r0, r4
  680. or r0, r5
  681. or r0, r6
  682. or r0, r7
  683. or r0, r8
  684. or r0, r9
  685. exit").unwrap();
  686. let mem = &mut [
  687. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
  688. 0x08, 0x09
  689. ];
  690. let vm = rbpf::EbpfVmRaw::new(&prog);
  691. assert_eq!(vm.prog_exec(mem), 0x9876543210);
  692. }
  693. #[test]
  694. fn test_vm_ldxb() {
  695. let prog = assemble("
  696. ldxb r0, [r1+2]
  697. exit").unwrap();
  698. let mem = &mut [
  699. 0xaa, 0xbb, 0x11, 0xcc, 0xdd
  700. ];
  701. let vm = rbpf::EbpfVmRaw::new(&prog);
  702. assert_eq!(vm.prog_exec(mem), 0x11);
  703. }
  704. #[test]
  705. fn test_vm_ldxdw() {
  706. let prog = assemble("
  707. ldxdw r0, [r1+2]
  708. exit").unwrap();
  709. let mem = &mut [
  710. 0xaa, 0xbb, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66,
  711. 0x77, 0x88, 0xcc, 0xdd
  712. ];
  713. let vm = rbpf::EbpfVmRaw::new(&prog);
  714. assert_eq!(vm.prog_exec(mem), 0x8877665544332211);
  715. }
  716. #[test]
  717. fn test_vm_ldxh_all() {
  718. let prog = assemble("
  719. mov r0, r1
  720. ldxh r9, [r0+0]
  721. be16 r9
  722. lsh r9, 0
  723. ldxh r8, [r0+2]
  724. be16 r8
  725. lsh r8, 4
  726. ldxh r7, [r0+4]
  727. be16 r7
  728. lsh r7, 8
  729. ldxh r6, [r0+6]
  730. be16 r6
  731. lsh r6, 12
  732. ldxh r5, [r0+8]
  733. be16 r5
  734. lsh r5, 16
  735. ldxh r4, [r0+10]
  736. be16 r4
  737. lsh r4, 20
  738. ldxh r3, [r0+12]
  739. be16 r3
  740. lsh r3, 24
  741. ldxh r2, [r0+14]
  742. be16 r2
  743. lsh r2, 28
  744. ldxh r1, [r0+16]
  745. be16 r1
  746. lsh r1, 32
  747. ldxh r0, [r0+18]
  748. be16 r0
  749. lsh r0, 36
  750. or r0, r1
  751. or r0, r2
  752. or r0, r3
  753. or r0, r4
  754. or r0, r5
  755. or r0, r6
  756. or r0, r7
  757. or r0, r8
  758. or r0, r9
  759. exit").unwrap();
  760. let mem = &mut [
  761. 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03,
  762. 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00, 0x07,
  763. 0x00, 0x08, 0x00, 0x09
  764. ];
  765. let vm = rbpf::EbpfVmRaw::new(&prog);
  766. assert_eq!(vm.prog_exec(mem), 0x9876543210);
  767. }
  768. #[test]
  769. fn test_vm_ldxh_all2() {
  770. let prog = assemble("
  771. mov r0, r1
  772. ldxh r9, [r0+0]
  773. be16 r9
  774. ldxh r8, [r0+2]
  775. be16 r8
  776. ldxh r7, [r0+4]
  777. be16 r7
  778. ldxh r6, [r0+6]
  779. be16 r6
  780. ldxh r5, [r0+8]
  781. be16 r5
  782. ldxh r4, [r0+10]
  783. be16 r4
  784. ldxh r3, [r0+12]
  785. be16 r3
  786. ldxh r2, [r0+14]
  787. be16 r2
  788. ldxh r1, [r0+16]
  789. be16 r1
  790. ldxh r0, [r0+18]
  791. be16 r0
  792. or r0, r1
  793. or r0, r2
  794. or r0, r3
  795. or r0, r4
  796. or r0, r5
  797. or r0, r6
  798. or r0, r7
  799. or r0, r8
  800. or r0, r9
  801. exit").unwrap();
  802. let mem = &mut [
  803. 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08,
  804. 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00, 0x80,
  805. 0x01, 0x00, 0x02, 0x00
  806. ];
  807. let vm = rbpf::EbpfVmRaw::new(&prog);
  808. assert_eq!(vm.prog_exec(mem), 0x3ff);
  809. }
  810. #[test]
  811. fn test_vm_ldxh() {
  812. let prog = assemble("
  813. ldxh r0, [r1+2]
  814. exit").unwrap();
  815. let mem = &mut [
  816. 0xaa, 0xbb, 0x11, 0x22, 0xcc, 0xdd
  817. ];
  818. let vm = rbpf::EbpfVmRaw::new(&prog);
  819. assert_eq!(vm.prog_exec(mem), 0x2211);
  820. }
  821. #[test]
  822. fn test_vm_ldxh_same_reg() {
  823. let prog = assemble("
  824. mov r0, r1
  825. sth [r0], 0x1234
  826. ldxh r0, [r0]
  827. exit").unwrap();
  828. let mem = &mut [
  829. 0xff, 0xff
  830. ];
  831. let vm = rbpf::EbpfVmRaw::new(&prog);
  832. assert_eq!(vm.prog_exec(mem), 0x1234);
  833. }
  834. #[test]
  835. fn test_vm_ldxw_all() {
  836. let prog = assemble("
  837. mov r0, r1
  838. ldxw r9, [r0+0]
  839. be32 r9
  840. ldxw r8, [r0+4]
  841. be32 r8
  842. ldxw r7, [r0+8]
  843. be32 r7
  844. ldxw r6, [r0+12]
  845. be32 r6
  846. ldxw r5, [r0+16]
  847. be32 r5
  848. ldxw r4, [r0+20]
  849. be32 r4
  850. ldxw r3, [r0+24]
  851. be32 r3
  852. ldxw r2, [r0+28]
  853. be32 r2
  854. ldxw r1, [r0+32]
  855. be32 r1
  856. ldxw r0, [r0+36]
  857. be32 r0
  858. or r0, r1
  859. or r0, r2
  860. or r0, r3
  861. or r0, r4
  862. or r0, r5
  863. or r0, r6
  864. or r0, r7
  865. or r0, r8
  866. or r0, r9
  867. exit").unwrap();
  868. let mem = &mut [
  869. 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02,
  870. 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08,
  871. 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00,
  872. 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00,
  873. 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00
  874. ];
  875. let vm = rbpf::EbpfVmRaw::new(&prog);
  876. assert_eq!(vm.prog_exec(mem), 0x030f0f);
  877. }
  878. #[test]
  879. fn test_vm_ldxw() {
  880. let prog = assemble("
  881. ldxw r0, [r1+2]
  882. exit").unwrap();
  883. let mem = &mut [
  884. 0xaa, 0xbb, 0x11, 0x22, 0x33, 0x44, 0xcc, 0xdd
  885. ];
  886. let vm = rbpf::EbpfVmRaw::new(&prog);
  887. assert_eq!(vm.prog_exec(mem), 0x44332211);
  888. }
  889. #[test]
  890. fn test_vm_le16() {
  891. let prog = assemble("
  892. ldxh r0, [r1]
  893. le16 r0
  894. exit").unwrap();
  895. let mem = &mut [
  896. 0x22, 0x11
  897. ];
  898. let vm = rbpf::EbpfVmRaw::new(&prog);
  899. assert_eq!(vm.prog_exec(mem), 0x1122);
  900. }
  901. #[test]
  902. fn test_vm_le32() {
  903. let prog = assemble("
  904. ldxw r0, [r1]
  905. le32 r0
  906. exit").unwrap();
  907. let mem = &mut [
  908. 0x44, 0x33, 0x22, 0x11
  909. ];
  910. let vm = rbpf::EbpfVmRaw::new(&prog);
  911. assert_eq!(vm.prog_exec(mem), 0x11223344);
  912. }
  913. #[test]
  914. fn test_vm_le64() {
  915. let prog = assemble("
  916. ldxdw r0, [r1]
  917. le64 r0
  918. exit").unwrap();
  919. let mem = &mut [
  920. 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11
  921. ];
  922. let vm = rbpf::EbpfVmRaw::new(&prog);
  923. assert_eq!(vm.prog_exec(mem), 0x1122334455667788);
  924. }
  925. #[test]
  926. fn test_vm_lsh_reg() {
  927. let prog = assemble("
  928. mov r0, 0x1
  929. mov r7, 4
  930. lsh r0, r7
  931. exit").unwrap();
  932. let vm = rbpf::EbpfVmNoData::new(&prog);
  933. assert_eq!(vm.prog_exec(), 0x10);
  934. }
  935. #[test]
  936. fn test_vm_mod() {
  937. let prog = assemble("
  938. mov32 r0, 5748
  939. mod32 r0, 92
  940. mov32 r1, 13
  941. mod32 r0, r1
  942. exit").unwrap();
  943. let vm = rbpf::EbpfVmNoData::new(&prog);
  944. assert_eq!(vm.prog_exec(), 0x5);
  945. }
  946. #[test]
  947. fn test_vm_mod32() {
  948. let prog = assemble("
  949. lddw r0, 0x100000003
  950. mod32 r0, 3
  951. exit").unwrap();
  952. let vm = rbpf::EbpfVmNoData::new(&prog);
  953. assert_eq!(vm.prog_exec(), 0x0);
  954. }
  955. #[test]
  956. fn test_vm_mod64() {
  957. let prog = assemble("
  958. mov32 r0, -1316649930
  959. lsh r0, 32
  960. or r0, 0x100dc5c8
  961. mov32 r1, 0xdde263e
  962. lsh r1, 32
  963. or r1, 0x3cbef7f3
  964. mod r0, r1
  965. mod r0, 0x658f1778
  966. exit").unwrap();
  967. let vm = rbpf::EbpfVmNoData::new(&prog);
  968. assert_eq!(vm.prog_exec(), 0x30ba5a04);
  969. }
  970. #[test]
  971. fn test_vm_mov() {
  972. let prog = assemble("
  973. mov32 r1, 1
  974. mov32 r0, r1
  975. exit").unwrap();
  976. let vm = rbpf::EbpfVmNoData::new(&prog);
  977. assert_eq!(vm.prog_exec(), 0x1);
  978. }
  979. #[test]
  980. fn test_vm_mul32_imm() {
  981. let prog = assemble("
  982. mov r0, 3
  983. mul32 r0, 4
  984. exit").unwrap();
  985. let vm = rbpf::EbpfVmNoData::new(&prog);
  986. assert_eq!(vm.prog_exec(), 0xc);
  987. }
  988. #[test]
  989. fn test_vm_mul32_reg() {
  990. let prog = assemble("
  991. mov r0, 3
  992. mov r1, 4
  993. mul32 r0, r1
  994. exit").unwrap();
  995. let vm = rbpf::EbpfVmNoData::new(&prog);
  996. assert_eq!(vm.prog_exec(), 0xc);
  997. }
  998. #[test]
  999. fn test_vm_mul32_reg_overflow() {
  1000. let prog = assemble("
  1001. mov r0, 0x40000001
  1002. mov r1, 4
  1003. mul32 r0, r1
  1004. exit").unwrap();
  1005. let vm = rbpf::EbpfVmNoData::new(&prog);
  1006. assert_eq!(vm.prog_exec(), 0x4);
  1007. }
  1008. #[test]
  1009. fn test_vm_mul64_imm() {
  1010. let prog = assemble("
  1011. mov r0, 0x40000001
  1012. mul r0, 4
  1013. exit").unwrap();
  1014. let vm = rbpf::EbpfVmNoData::new(&prog);
  1015. assert_eq!(vm.prog_exec(), 0x100000004);
  1016. }
  1017. #[test]
  1018. fn test_vm_mul64_reg() {
  1019. let prog = assemble("
  1020. mov r0, 0x40000001
  1021. mov r1, 4
  1022. mul r0, r1
  1023. exit").unwrap();
  1024. let vm = rbpf::EbpfVmNoData::new(&prog);
  1025. assert_eq!(vm.prog_exec(), 0x100000004);
  1026. }
  1027. #[test]
  1028. fn test_vm_mul_loop() {
  1029. let prog = assemble("
  1030. mov r0, 0x7
  1031. add r1, 0xa
  1032. lsh r1, 0x20
  1033. rsh r1, 0x20
  1034. jeq r1, 0x0, +4
  1035. mov r0, 0x7
  1036. mul r0, 0x7
  1037. add r1, -1
  1038. jne r1, 0x0, -3
  1039. exit").unwrap();
  1040. let vm = rbpf::EbpfVmNoData::new(&prog);
  1041. assert_eq!(vm.prog_exec(), 0x75db9c97);
  1042. }
  1043. #[test]
  1044. fn test_vm_neg64() {
  1045. let prog = assemble("
  1046. mov32 r0, 2
  1047. neg r0
  1048. exit").unwrap();
  1049. let vm = rbpf::EbpfVmNoData::new(&prog);
  1050. assert_eq!(vm.prog_exec(), 0xfffffffffffffffe);
  1051. }
  1052. #[test]
  1053. fn test_vm_neg() {
  1054. let prog = assemble("
  1055. mov32 r0, 2
  1056. neg32 r0
  1057. exit").unwrap();
  1058. let vm = rbpf::EbpfVmNoData::new(&prog);
  1059. assert_eq!(vm.prog_exec(), 0xfffffffe);
  1060. }
  1061. #[test]
  1062. fn test_vm_prime() {
  1063. let prog = assemble("
  1064. mov r1, 67
  1065. mov r0, 0x1
  1066. mov r2, 0x2
  1067. jgt r1, 0x2, +4
  1068. ja +10
  1069. add r2, 0x1
  1070. mov r0, 0x1
  1071. jge r2, r1, +7
  1072. mov r3, r1
  1073. div r3, r2
  1074. mul r3, r2
  1075. mov r4, r1
  1076. sub r4, r3
  1077. mov r0, 0x0
  1078. jne r4, 0x0, -10
  1079. exit").unwrap();
  1080. let vm = rbpf::EbpfVmNoData::new(&prog);
  1081. assert_eq!(vm.prog_exec(), 0x1);
  1082. }
  1083. #[test]
  1084. fn test_vm_rhs32() {
  1085. let prog = assemble("
  1086. xor r0, r0
  1087. sub r0, 1
  1088. rsh32 r0, 8
  1089. exit").unwrap();
  1090. let vm = rbpf::EbpfVmNoData::new(&prog);
  1091. assert_eq!(vm.prog_exec(), 0x00ffffff);
  1092. }
  1093. #[test]
  1094. fn test_vm_rsh_reg() {
  1095. let prog = assemble("
  1096. mov r0, 0x10
  1097. mov r7, 4
  1098. rsh r0, r7
  1099. exit").unwrap();
  1100. let vm = rbpf::EbpfVmNoData::new(&prog);
  1101. assert_eq!(vm.prog_exec(), 0x1);
  1102. }
  1103. #[test]
  1104. fn test_vm_stack() {
  1105. let prog = assemble("
  1106. mov r1, 51
  1107. stdw [r10-16], 0xab
  1108. stdw [r10-8], 0xcd
  1109. and r1, 1
  1110. lsh r1, 3
  1111. mov r2, r10
  1112. add r2, r1
  1113. ldxdw r0, [r2-16]
  1114. exit").unwrap();
  1115. let vm = rbpf::EbpfVmNoData::new(&prog);
  1116. assert_eq!(vm.prog_exec(), 0xcd);
  1117. }
  1118. #[test]
  1119. fn test_vm_stack2() {
  1120. let prog = assemble("
  1121. stb [r10-4], 0x01
  1122. stb [r10-3], 0x02
  1123. stb [r10-2], 0x03
  1124. stb [r10-1], 0x04
  1125. mov r1, r10
  1126. mov r2, 0x4
  1127. sub r1, r2
  1128. call 1
  1129. mov r1, 0
  1130. ldxb r2, [r10-4]
  1131. ldxb r3, [r10-3]
  1132. ldxb r4, [r10-2]
  1133. ldxb r5, [r10-1]
  1134. call 0
  1135. xor r0, 0x2a2a2a2a
  1136. exit").unwrap();
  1137. let mut vm = rbpf::EbpfVmNoData::new(&prog);
  1138. vm.register_helper(0, helpers::gather_bytes);
  1139. vm.register_helper(1, helpers::memfrob);
  1140. assert_eq!(vm.prog_exec(), 0x01020304);
  1141. }
  1142. #[test]
  1143. fn test_vm_stb() {
  1144. let prog = assemble("
  1145. stb [r1+2], 0x11
  1146. ldxb r0, [r1+2]
  1147. exit").unwrap();
  1148. let mem = &mut [
  1149. 0xaa, 0xbb, 0xff, 0xcc, 0xdd
  1150. ];
  1151. let vm = rbpf::EbpfVmRaw::new(&prog);
  1152. assert_eq!(vm.prog_exec(mem), 0x11);
  1153. }
  1154. #[test]
  1155. fn test_vm_stdw() {
  1156. let prog = assemble("
  1157. stdw [r1+2], 0x44332211
  1158. ldxdw r0, [r1+2]
  1159. exit").unwrap();
  1160. let mem = &mut [
  1161. 0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  1162. 0xff, 0xff, 0xcc, 0xdd
  1163. ];
  1164. let vm = rbpf::EbpfVmRaw::new(&prog);
  1165. assert_eq!(vm.prog_exec(mem), 0x44332211);
  1166. }
  1167. #[test]
  1168. fn test_vm_sth() {
  1169. let prog = assemble("
  1170. sth [r1+2], 0x2211
  1171. ldxh r0, [r1+2]
  1172. exit").unwrap();
  1173. let mem = &mut [
  1174. 0xaa, 0xbb, 0xff, 0xff, 0xcc, 0xdd
  1175. ];
  1176. let vm = rbpf::EbpfVmRaw::new(&prog);
  1177. assert_eq!(vm.prog_exec(mem), 0x2211);
  1178. }
  1179. #[test]
  1180. fn test_vm_string_stack() {
  1181. let prog = assemble("
  1182. mov r1, 0x78636261
  1183. stxw [r10-8], r1
  1184. mov r6, 0x0
  1185. stxb [r10-4], r6
  1186. stxb [r10-12], r6
  1187. mov r1, 0x79636261
  1188. stxw [r10-16], r1
  1189. mov r1, r10
  1190. add r1, -8
  1191. mov r2, r1
  1192. call 0x4
  1193. mov r1, r0
  1194. mov r0, 0x1
  1195. lsh r1, 0x20
  1196. rsh r1, 0x20
  1197. jne r1, 0x0, +11
  1198. mov r1, r10
  1199. add r1, -8
  1200. mov r2, r10
  1201. add r2, -16
  1202. call 0x4
  1203. mov r1, r0
  1204. lsh r1, 0x20
  1205. rsh r1, 0x20
  1206. mov r0, 0x1
  1207. jeq r1, r6, +1
  1208. mov r0, 0x0
  1209. exit").unwrap();
  1210. let mut vm = rbpf::EbpfVmNoData::new(&prog);
  1211. vm.register_helper(4, helpers::strcmp);
  1212. assert_eq!(vm.prog_exec(), 0x0);
  1213. }
  1214. #[test]
  1215. fn test_vm_stw() {
  1216. let prog = assemble("
  1217. stw [r1+2], 0x44332211
  1218. ldxw r0, [r1+2]
  1219. exit").unwrap();
  1220. let mem = &mut [
  1221. 0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd
  1222. ];
  1223. let vm = rbpf::EbpfVmRaw::new(&prog);
  1224. assert_eq!(vm.prog_exec(mem), 0x44332211);
  1225. }
  1226. #[test]
  1227. fn test_vm_stxb() {
  1228. let prog = assemble("
  1229. mov32 r2, 0x11
  1230. stxb [r1+2], r2
  1231. ldxb r0, [r1+2]
  1232. exit").unwrap();
  1233. let mem = &mut [
  1234. 0xaa, 0xbb, 0xff, 0xcc, 0xdd
  1235. ];
  1236. let vm = rbpf::EbpfVmRaw::new(&prog);
  1237. assert_eq!(vm.prog_exec(mem), 0x11);
  1238. }
  1239. #[test]
  1240. fn test_vm_stxb_all() {
  1241. let prog = assemble("
  1242. mov r0, 0xf0
  1243. mov r2, 0xf2
  1244. mov r3, 0xf3
  1245. mov r4, 0xf4
  1246. mov r5, 0xf5
  1247. mov r6, 0xf6
  1248. mov r7, 0xf7
  1249. mov r8, 0xf8
  1250. stxb [r1], r0
  1251. stxb [r1+1], r2
  1252. stxb [r1+2], r3
  1253. stxb [r1+3], r4
  1254. stxb [r1+4], r5
  1255. stxb [r1+5], r6
  1256. stxb [r1+6], r7
  1257. stxb [r1+7], r8
  1258. ldxdw r0, [r1]
  1259. be64 r0
  1260. exit").unwrap();
  1261. let mem = &mut [
  1262. 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
  1263. ];
  1264. let vm = rbpf::EbpfVmRaw::new(&prog);
  1265. assert_eq!(vm.prog_exec(mem), 0xf0f2f3f4f5f6f7f8);
  1266. }
  1267. #[test]
  1268. fn test_vm_stxb_all2() {
  1269. let prog = assemble("
  1270. mov r0, r1
  1271. mov r1, 0xf1
  1272. mov r9, 0xf9
  1273. stxb [r0], r1
  1274. stxb [r0+1], r9
  1275. ldxh r0, [r0]
  1276. be16 r0
  1277. exit").unwrap();
  1278. let mem = &mut [
  1279. 0xff, 0xff
  1280. ];
  1281. let vm = rbpf::EbpfVmRaw::new(&prog);
  1282. assert_eq!(vm.prog_exec(mem), 0xf1f9);
  1283. }
  1284. #[test]
  1285. fn test_vm_stxb_chain() {
  1286. let prog = assemble("
  1287. mov r0, r1
  1288. ldxb r9, [r0+0]
  1289. stxb [r0+1], r9
  1290. ldxb r8, [r0+1]
  1291. stxb [r0+2], r8
  1292. ldxb r7, [r0+2]
  1293. stxb [r0+3], r7
  1294. ldxb r6, [r0+3]
  1295. stxb [r0+4], r6
  1296. ldxb r5, [r0+4]
  1297. stxb [r0+5], r5
  1298. ldxb r4, [r0+5]
  1299. stxb [r0+6], r4
  1300. ldxb r3, [r0+6]
  1301. stxb [r0+7], r3
  1302. ldxb r2, [r0+7]
  1303. stxb [r0+8], r2
  1304. ldxb r1, [r0+8]
  1305. stxb [r0+9], r1
  1306. ldxb r0, [r0+9]
  1307. exit").unwrap();
  1308. let mem = &mut [
  1309. 0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1310. 0x00, 0x00
  1311. ];
  1312. let vm = rbpf::EbpfVmRaw::new(&prog);
  1313. assert_eq!(vm.prog_exec(mem), 0x2a);
  1314. }
  1315. #[test]
  1316. fn test_vm_stxdw() {
  1317. let prog = assemble("
  1318. mov r2, -2005440939
  1319. lsh r2, 32
  1320. or r2, 0x44332211
  1321. stxdw [r1+2], r2
  1322. ldxdw r0, [r1+2]
  1323. exit").unwrap();
  1324. let mem = &mut [
  1325. 0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
  1326. 0xff, 0xff, 0xcc, 0xdd
  1327. ];
  1328. let vm = rbpf::EbpfVmRaw::new(&prog);
  1329. assert_eq!(vm.prog_exec(mem), 0x8877665544332211);
  1330. }
  1331. #[test]
  1332. fn test_vm_stxh() {
  1333. let prog = assemble("
  1334. mov32 r2, 0x2211
  1335. stxh [r1+2], r2
  1336. ldxh r0, [r1+2]
  1337. exit").unwrap();
  1338. let mem = &mut [
  1339. 0xaa, 0xbb, 0xff, 0xff, 0xcc, 0xdd
  1340. ];
  1341. let vm = rbpf::EbpfVmRaw::new(&prog);
  1342. assert_eq!(vm.prog_exec(mem), 0x2211);
  1343. }
  1344. #[test]
  1345. fn test_vm_stxw() {
  1346. let prog = assemble("
  1347. mov32 r2, 0x44332211
  1348. stxw [r1+2], r2
  1349. ldxw r0, [r1+2]
  1350. exit").unwrap();
  1351. let mem = &mut [
  1352. 0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd
  1353. ];
  1354. let vm = rbpf::EbpfVmRaw::new(&prog);
  1355. assert_eq!(vm.prog_exec(mem), 0x44332211);
  1356. }
  1357. #[test]
  1358. fn test_vm_subnet() {
  1359. let prog = assemble("
  1360. mov r2, 0xe
  1361. ldxh r3, [r1+12]
  1362. jne r3, 0x81, +2
  1363. mov r2, 0x12
  1364. ldxh r3, [r1+16]
  1365. and r3, 0xffff
  1366. jne r3, 0x8, +5
  1367. add r1, r2
  1368. mov r0, 0x1
  1369. ldxw r1, [r1+16]
  1370. and r1, 0xffffff
  1371. jeq r1, 0x1a8c0, +1
  1372. mov r0, 0x0
  1373. exit").unwrap();
  1374. let mem = &mut [
  1375. 0x00, 0x00, 0xc0, 0x9f, 0xa0, 0x97, 0x00, 0xa0,
  1376. 0xcc, 0x3b, 0xbf, 0xfa, 0x08, 0x00, 0x45, 0x10,
  1377. 0x00, 0x3c, 0x46, 0x3c, 0x40, 0x00, 0x40, 0x06,
  1378. 0x73, 0x1c, 0xc0, 0xa8, 0x01, 0x02, 0xc0, 0xa8,
  1379. 0x01, 0x01, 0x06, 0x0e, 0x00, 0x17, 0x99, 0xc5,
  1380. 0xa0, 0xec, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x02,
  1381. 0x7d, 0x78, 0xe0, 0xa3, 0x00, 0x00, 0x02, 0x04,
  1382. 0x05, 0xb4, 0x04, 0x02, 0x08, 0x0a, 0x00, 0x9c,
  1383. 0x27, 0x24, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03,
  1384. 0x03, 0x00
  1385. ];
  1386. let vm = rbpf::EbpfVmRaw::new(&prog);
  1387. assert_eq!(vm.prog_exec(mem), 0x1);
  1388. }
  1389. const PROG_TCP_PORT_80: [u8;152] = [
  1390. 0x71, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00,
  1391. 0x71, 0x13, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
  1392. 0x67, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00,
  1393. 0x4f, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1394. 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1395. 0x55, 0x03, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00,
  1396. 0x71, 0x12, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00,
  1397. 0x55, 0x02, 0x0a, 0x00, 0x06, 0x00, 0x00, 0x00,
  1398. 0x71, 0x12, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00,
  1399. 0x07, 0x01, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
  1400. 0x57, 0x02, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00,
  1401. 0x67, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
  1402. 0x0f, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1403. 0x69, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
  1404. 0x15, 0x02, 0x02, 0x00, 0x00, 0x50, 0x00, 0x00,
  1405. 0x69, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1406. 0x55, 0x01, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00,
  1407. 0xb7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
  1408. 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
  1409. ];
  1410. #[test]
  1411. fn test_vm_tcp_port80_match() {
  1412. let mem = &mut [
  1413. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06,
  1414. 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45, 0x00,
  1415. 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06,
  1416. 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8,
  1417. 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00,
  1418. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02,
  1419. 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44,
  1420. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1421. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1422. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1423. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1424. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1425. 0x44, 0x44, 0x44, 0x44
  1426. ];
  1427. let prog = &PROG_TCP_PORT_80;
  1428. let vm = rbpf::EbpfVmRaw::new(prog);
  1429. assert_eq!(vm.prog_exec(mem), 0x1);
  1430. }
  1431. #[test]
  1432. fn test_vm_tcp_port80_nomatch() {
  1433. let mem = &mut [
  1434. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06,
  1435. 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45, 0x00,
  1436. 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06,
  1437. 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8,
  1438. 0x00, 0x02, 0x00, 0x16, 0x27, 0x10, 0x00, 0x00,
  1439. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x51, 0x02,
  1440. 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44,
  1441. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1442. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1443. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1444. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1445. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1446. 0x44, 0x44, 0x44, 0x44
  1447. ];
  1448. let prog = &PROG_TCP_PORT_80;
  1449. let vm = rbpf::EbpfVmRaw::new(prog);
  1450. assert_eq!(vm.prog_exec(mem), 0x0);
  1451. }
  1452. #[test]
  1453. fn test_vm_tcp_port80_nomatch_ethertype() {
  1454. let mem = &mut [
  1455. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06,
  1456. 0x07, 0x08, 0x09, 0x0a, 0x08, 0x01, 0x45, 0x00,
  1457. 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06,
  1458. 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8,
  1459. 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00,
  1460. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02,
  1461. 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44,
  1462. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1463. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1464. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1465. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1466. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1467. 0x44, 0x44, 0x44, 0x44
  1468. ];
  1469. let prog = &PROG_TCP_PORT_80;
  1470. let vm = rbpf::EbpfVmRaw::new(prog);
  1471. assert_eq!(vm.prog_exec(mem), 0x0);
  1472. }
  1473. #[test]
  1474. fn test_vm_tcp_port80_nomatch_proto() {
  1475. let mem = &mut [
  1476. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06,
  1477. 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45, 0x00,
  1478. 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11,
  1479. 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01, 0xc0, 0xa8,
  1480. 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00,
  1481. 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x50, 0x02,
  1482. 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44,
  1483. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1484. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1485. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1486. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1487. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1488. 0x44, 0x44, 0x44, 0x44
  1489. ];
  1490. let prog = &PROG_TCP_PORT_80;
  1491. let vm = rbpf::EbpfVmRaw::new(prog);
  1492. assert_eq!(vm.prog_exec(mem), 0x0);
  1493. }
  1494. #[test]
  1495. fn test_vm_tcp_sack_match() {
  1496. let mut mem = TCP_SACK_MATCH.to_vec();
  1497. let prog = assemble(TCP_SACK_ASM).unwrap();
  1498. let vm = rbpf::EbpfVmRaw::new(&prog);
  1499. assert_eq!(vm.prog_exec(mem.as_mut_slice()), 0x1);
  1500. }
  1501. #[test]
  1502. fn test_vm_tcp_sack_nomatch() {
  1503. let mut mem = TCP_SACK_NOMATCH.to_vec();
  1504. let prog = assemble(TCP_SACK_ASM).unwrap();
  1505. let vm = rbpf::EbpfVmRaw::new(&prog);
  1506. assert_eq!(vm.prog_exec(mem.as_mut_slice()), 0x0);
  1507. }