cranelift.rs 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254
  1. // SPDX-License-Identifier: (Apache-2.0 OR MIT)
  2. #![cfg_attr(feature = "cargo-clippy", allow(clippy::unreadable_literal))]
  3. #![cfg(feature = "cranelift")]
  4. extern crate rbpf;
  5. mod common;
  6. use rbpf::{assembler::assemble, helpers};
  7. use crate::common::{TCP_SACK_ASM, TCP_SACK_MATCH, TCP_SACK_NOMATCH};
  8. macro_rules! test_cranelift {
  9. ($name:ident, $prog:expr, $expected:expr) => {
  10. #[test]
  11. fn $name() {
  12. let prog = assemble($prog).unwrap();
  13. let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
  14. assert_eq!(vm.execute_cranelift().unwrap(), $expected);
  15. }
  16. };
  17. ($name:ident, $prog:expr, $mem:expr, $expected:expr) => {
  18. #[test]
  19. fn $name() {
  20. let prog = assemble($prog).unwrap();
  21. let mem = &mut $mem;
  22. let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
  23. assert_eq!(vm.execute_cranelift(mem).unwrap(), $expected);
  24. }
  25. };
  26. }
  27. test_cranelift!(
  28. test_cranelift_add,
  29. "
  30. mov32 r0, 0
  31. mov32 r1, 2
  32. add32 r0, 1
  33. add32 r0, r1
  34. exit
  35. ",
  36. 0x3
  37. );
  38. test_cranelift!(
  39. test_cranelift_alu64_arith,
  40. "
  41. mov r0, 0
  42. mov r1, 1
  43. mov r2, 2
  44. mov r3, 3
  45. mov r4, 4
  46. mov r5, 5
  47. mov r6, 6
  48. mov r7, 7
  49. mov r8, 8
  50. mov r9, 9
  51. add r0, 23
  52. add r0, r7
  53. sub r0, 13
  54. sub r0, r1
  55. mul r0, 7
  56. mul r0, r3
  57. div r0, 2
  58. div r0, r4
  59. exit
  60. ",
  61. 0x2a
  62. );
  63. test_cranelift!(
  64. test_cranelift_alu64_bit,
  65. "
  66. mov r0, 0
  67. mov r1, 1
  68. mov r2, 2
  69. mov r3, 3
  70. mov r4, 4
  71. mov r5, 5
  72. mov r6, 6
  73. mov r7, 7
  74. mov r8, 8
  75. or r0, r5
  76. or r0, 0xa0
  77. and r0, 0xa3
  78. mov r9, 0x91
  79. and r0, r9
  80. lsh r0, 32
  81. lsh r0, 22
  82. lsh r0, r8
  83. rsh r0, 32
  84. rsh r0, 19
  85. rsh r0, r7
  86. xor r0, 0x03
  87. xor r0, r2
  88. exit
  89. ",
  90. 0x11
  91. );
  92. test_cranelift!(
  93. test_cranelift_alu_arith,
  94. "
  95. mov32 r0, 0
  96. mov32 r1, 1
  97. mov32 r2, 2
  98. mov32 r3, 3
  99. mov32 r4, 4
  100. mov32 r5, 5
  101. mov32 r6, 6
  102. mov32 r7, 7
  103. mov32 r8, 8
  104. mov32 r9, 9
  105. add32 r0, 23
  106. add32 r0, r7
  107. sub32 r0, 13
  108. sub32 r0, r1
  109. mul32 r0, 7
  110. mul32 r0, r3
  111. div32 r0, 2
  112. div32 r0, r4
  113. exit
  114. ",
  115. 0x2a
  116. );
  117. test_cranelift!(
  118. test_cranelift_alu_bit,
  119. "
  120. mov32 r0, 0
  121. mov32 r1, 1
  122. mov32 r2, 2
  123. mov32 r3, 3
  124. mov32 r4, 4
  125. mov32 r5, 5
  126. mov32 r6, 6
  127. mov32 r7, 7
  128. mov32 r8, 8
  129. or32 r0, r5
  130. or32 r0, 0xa0
  131. and32 r0, 0xa3
  132. mov32 r9, 0x91
  133. and32 r0, r9
  134. lsh32 r0, 22
  135. lsh32 r0, r8
  136. rsh32 r0, 19
  137. rsh32 r0, r7
  138. xor32 r0, 0x03
  139. xor32 r0, r2
  140. exit
  141. ",
  142. 0x11
  143. );
  144. test_cranelift!(
  145. test_cranelift_arsh32_high_shift,
  146. "
  147. mov r0, 8
  148. lddw r1, 0x100000001
  149. arsh32 r0, r1
  150. exit
  151. ",
  152. 0x4
  153. );
  154. test_cranelift!(
  155. test_cranelift_arsh,
  156. "
  157. mov32 r0, 0xf8
  158. lsh32 r0, 28
  159. arsh32 r0, 16
  160. exit
  161. ",
  162. 0xffff8000
  163. );
  164. test_cranelift!(
  165. test_cranelift_arsh64,
  166. "
  167. mov32 r0, 1
  168. lsh r0, 63
  169. arsh r0, 55
  170. mov32 r1, 5
  171. arsh r0, r1
  172. exit
  173. ",
  174. 0xfffffffffffffff8
  175. );
  176. test_cranelift!(
  177. test_cranelift_arsh_reg,
  178. "
  179. mov32 r0, 0xf8
  180. mov32 r1, 16
  181. lsh32 r0, 28
  182. arsh32 r0, r1
  183. exit
  184. ",
  185. 0xffff8000
  186. );
  187. test_cranelift!(
  188. test_cranelift_be16,
  189. "
  190. ldxh r0, [r1]
  191. be16 r0
  192. exit
  193. ",
  194. [0x11, 0x22],
  195. 0x1122
  196. );
  197. test_cranelift!(
  198. test_cranelift_be16_high,
  199. "
  200. ldxdw r0, [r1]
  201. be16 r0
  202. exit
  203. ",
  204. [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88],
  205. 0x1122
  206. );
  207. test_cranelift!(
  208. test_cranelift_be32,
  209. "
  210. ldxw r0, [r1]
  211. be32 r0
  212. exit
  213. ",
  214. [0x11, 0x22, 0x33, 0x44],
  215. 0x11223344
  216. );
  217. test_cranelift!(
  218. test_cranelift_be32_high,
  219. "
  220. ldxdw r0, [r1]
  221. be32 r0
  222. exit
  223. ",
  224. [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88],
  225. 0x11223344
  226. );
  227. test_cranelift!(
  228. test_cranelift_be64,
  229. "
  230. ldxdw r0, [r1]
  231. be64 r0
  232. exit
  233. ",
  234. [0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88],
  235. 0x1122334455667788
  236. );
  237. #[test]
  238. fn test_cranelift_call() {
  239. let prog = assemble(
  240. "
  241. mov r1, 1
  242. mov r2, 2
  243. mov r3, 3
  244. mov r4, 4
  245. mov r5, 5
  246. call 0
  247. exit",
  248. )
  249. .unwrap();
  250. let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
  251. vm.register_helper(0, helpers::gather_bytes).unwrap();
  252. assert_eq!(vm.execute_cranelift().unwrap(), 0x0102030405);
  253. }
  254. #[test]
  255. #[should_panic(expected = "[CRANELIFT] Error: unknown helper function (id: 0x3f)")]
  256. fn test_cranelift_err_call_unreg() {
  257. let prog = assemble("
  258. mov r1, 1
  259. mov r2, 2
  260. mov r3, 3
  261. mov r4, 4
  262. mov r5, 5
  263. call 63
  264. exit
  265. ").unwrap();
  266. let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
  267. vm.execute_cranelift().unwrap();
  268. }
  269. #[test]
  270. fn test_cranelift_call_memfrob() {
  271. let prog = assemble(
  272. "
  273. mov r6, r1
  274. add r1, 2
  275. mov r2, 4
  276. call 1
  277. ldxdw r0, [r6]
  278. be64 r0
  279. exit",
  280. )
  281. .unwrap();
  282. let mut vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
  283. vm.register_helper(1, helpers::memfrob).unwrap();
  284. let mem = &mut [0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08];
  285. assert_eq!(vm.execute_cranelift(mem).unwrap(), 0x102292e2f2c0708);
  286. }
  287. test_cranelift!(
  288. test_cranelift_div32_high_divisor,
  289. "
  290. mov r0, 12
  291. lddw r1, 0x100000004
  292. div32 r0, r1
  293. exit
  294. ",
  295. 0x3
  296. );
  297. test_cranelift!(
  298. test_cranelift_div32_imm,
  299. "
  300. lddw r0, 0x10000000c
  301. div32 r0, 4
  302. exit
  303. ",
  304. 0x3
  305. );
  306. test_cranelift!(
  307. test_cranelift_div32_reg,
  308. "
  309. lddw r0, 0x10000000c
  310. mov r1, 4
  311. div32 r0, r1
  312. exit
  313. ",
  314. 0x3
  315. );
  316. test_cranelift!(
  317. test_cranelift_div64_imm,
  318. "
  319. mov r0, 0xc
  320. lsh r0, 32
  321. div r0, 4
  322. exit
  323. ",
  324. 0x300000000
  325. );
  326. test_cranelift!(
  327. test_cranelift_div64_reg,
  328. "
  329. mov r0, 0xc
  330. lsh r0, 32
  331. mov r1, 4
  332. div r0, r1
  333. exit
  334. ",
  335. 0x300000000
  336. );
  337. test_cranelift!(
  338. test_cranelift_div64_by_zero_imm,
  339. "
  340. mov32 r0, 1
  341. div r0, 0
  342. exit
  343. ",
  344. 0x0
  345. );
  346. test_cranelift!(
  347. test_cranelift_div_by_zero_imm,
  348. "
  349. mov32 r0, 1
  350. div32 r0, 0
  351. exit
  352. ",
  353. 0x0
  354. );
  355. test_cranelift!(
  356. test_cranelift_mod64_by_zero_imm,
  357. "
  358. mov32 r0, 1
  359. mod r0, 0
  360. exit
  361. ",
  362. 0x1
  363. );
  364. test_cranelift!(
  365. test_cranelift_mod_by_zero_imm,
  366. "
  367. mov32 r0, 1
  368. mod32 r0, 0
  369. exit
  370. ",
  371. 0x1
  372. );
  373. test_cranelift!(
  374. test_cranelift_div64_by_zero_reg,
  375. "
  376. mov32 r0, 1
  377. mov32 r1, 0
  378. div r0, r1
  379. exit
  380. ",
  381. 0x0
  382. );
  383. test_cranelift!(
  384. test_cranelift_div_by_zero_reg,
  385. "
  386. mov32 r0, 1
  387. mov32 r1, 0
  388. div32 r0, r1
  389. exit
  390. ",
  391. 0x0
  392. );
  393. test_cranelift!(
  394. test_cranelift_mod64_by_zero_reg,
  395. "
  396. mov32 r0, 1
  397. mov32 r1, 0
  398. mod r0, r1
  399. exit
  400. ",
  401. 0x1
  402. );
  403. test_cranelift!(
  404. test_cranelift_mod_by_zero_reg,
  405. "
  406. mov32 r0, 1
  407. mov32 r1, 0
  408. mod32 r0, r1
  409. exit
  410. ",
  411. 0x1
  412. );
  413. #[test]
  414. // #[should_panic(expected = "Error: out of bounds memory store (insn #1)")]
  415. #[ignore = "We have stack OOB checks, but we don't yet catch the trap code and convert it into a panic"]
  416. fn test_cranelift_err_stack_out_of_bound() {
  417. let prog = [
  418. 0x72, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  419. 0x00,
  420. ];
  421. let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
  422. vm.execute_cranelift().unwrap();
  423. }
  424. test_cranelift!(
  425. test_cranelift_exit,
  426. "
  427. mov r0, 0
  428. exit
  429. ",
  430. 0x0
  431. );
  432. test_cranelift!(
  433. test_cranelift_lddw,
  434. "
  435. lddw r0, 0x1122334455667788
  436. exit
  437. ",
  438. 0x1122334455667788
  439. );
  440. test_cranelift!(
  441. test_cranelift_lddw2,
  442. "
  443. lddw r0, 0x0000000080000000
  444. exit
  445. ",
  446. 0x80000000
  447. );
  448. test_cranelift!(
  449. test_cranelift_ldxb_all,
  450. "
  451. mov r0, r1
  452. ldxb r9, [r0+0]
  453. lsh r9, 0
  454. ldxb r8, [r0+1]
  455. lsh r8, 4
  456. ldxb r7, [r0+2]
  457. lsh r7, 8
  458. ldxb r6, [r0+3]
  459. lsh r6, 12
  460. ldxb r5, [r0+4]
  461. lsh r5, 16
  462. ldxb r4, [r0+5]
  463. lsh r4, 20
  464. ldxb r3, [r0+6]
  465. lsh r3, 24
  466. ldxb r2, [r0+7]
  467. lsh r2, 28
  468. ldxb r1, [r0+8]
  469. lsh r1, 32
  470. ldxb r0, [r0+9]
  471. lsh r0, 36
  472. or r0, r1
  473. or r0, r2
  474. or r0, r3
  475. or r0, r4
  476. or r0, r5
  477. or r0, r6
  478. or r0, r7
  479. or r0, r8
  480. or r0, r9
  481. exit
  482. ",
  483. [0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09],
  484. 0x9876543210
  485. );
  486. test_cranelift!(
  487. test_cranelift_ldxb,
  488. "
  489. ldxb r0, [r1+2]
  490. exit
  491. ",
  492. [0xaa, 0xbb, 0x11, 0xcc, 0xdd],
  493. 0x11
  494. );
  495. test_cranelift!(
  496. test_cranelift_ldxdw,
  497. "
  498. ldxdw r0, [r1+2]
  499. exit
  500. ",
  501. [0xaa, 0xbb, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0xcc, 0xdd],
  502. 0x8877665544332211
  503. );
  504. test_cranelift!(
  505. test_cranelift_ldxh_all,
  506. "
  507. mov r0, r1
  508. ldxh r9, [r0+0]
  509. be16 r9
  510. lsh r9, 0
  511. ldxh r8, [r0+2]
  512. be16 r8
  513. lsh r8, 4
  514. ldxh r7, [r0+4]
  515. be16 r7
  516. lsh r7, 8
  517. ldxh r6, [r0+6]
  518. be16 r6
  519. lsh r6, 12
  520. ldxh r5, [r0+8]
  521. be16 r5
  522. lsh r5, 16
  523. ldxh r4, [r0+10]
  524. be16 r4
  525. lsh r4, 20
  526. ldxh r3, [r0+12]
  527. be16 r3
  528. lsh r3, 24
  529. ldxh r2, [r0+14]
  530. be16 r2
  531. lsh r2, 28
  532. ldxh r1, [r0+16]
  533. be16 r1
  534. lsh r1, 32
  535. ldxh r0, [r0+18]
  536. be16 r0
  537. lsh r0, 36
  538. or r0, r1
  539. or r0, r2
  540. or r0, r3
  541. or r0, r4
  542. or r0, r5
  543. or r0, r6
  544. or r0, r7
  545. or r0, r8
  546. or r0, r9
  547. exit
  548. ",
  549. [
  550. 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04, 0x00, 0x05, 0x00, 0x06, 0x00,
  551. 0x07, 0x00, 0x08, 0x00, 0x09
  552. ],
  553. 0x9876543210
  554. );
  555. test_cranelift!(
  556. test_cranelift_ldxh_all2,
  557. "
  558. mov r0, r1
  559. ldxh r9, [r0+0]
  560. be16 r9
  561. ldxh r8, [r0+2]
  562. be16 r8
  563. ldxh r7, [r0+4]
  564. be16 r7
  565. ldxh r6, [r0+6]
  566. be16 r6
  567. ldxh r5, [r0+8]
  568. be16 r5
  569. ldxh r4, [r0+10]
  570. be16 r4
  571. ldxh r3, [r0+12]
  572. be16 r3
  573. ldxh r2, [r0+14]
  574. be16 r2
  575. ldxh r1, [r0+16]
  576. be16 r1
  577. ldxh r0, [r0+18]
  578. be16 r0
  579. or r0, r1
  580. or r0, r2
  581. or r0, r3
  582. or r0, r4
  583. or r0, r5
  584. or r0, r6
  585. or r0, r7
  586. or r0, r8
  587. or r0, r9
  588. exit
  589. ",
  590. [
  591. 0x00, 0x01, 0x00, 0x02, 0x00, 0x04, 0x00, 0x08, 0x00, 0x10, 0x00, 0x20, 0x00, 0x40, 0x00,
  592. 0x80, 0x01, 0x00, 0x02, 0x00
  593. ],
  594. 0x3ff
  595. );
  596. test_cranelift!(
  597. test_cranelift_ldxh,
  598. "
  599. ldxh r0, [r1+2]
  600. exit
  601. ",
  602. [0xaa, 0xbb, 0x11, 0x22, 0xcc, 0xdd],
  603. 0x2211
  604. );
  605. test_cranelift!(
  606. test_cranelift_ldxh_same_reg,
  607. "
  608. mov r0, r1
  609. sth [r0], 0x1234
  610. ldxh r0, [r0]
  611. exit
  612. ",
  613. [0xff, 0xff],
  614. 0x1234
  615. );
  616. test_cranelift!(
  617. test_cranelift_ldxw_all,
  618. "
  619. mov r0, r1
  620. ldxw r9, [r0+0]
  621. be32 r9
  622. ldxw r8, [r0+4]
  623. be32 r8
  624. ldxw r7, [r0+8]
  625. be32 r7
  626. ldxw r6, [r0+12]
  627. be32 r6
  628. ldxw r5, [r0+16]
  629. be32 r5
  630. ldxw r4, [r0+20]
  631. be32 r4
  632. ldxw r3, [r0+24]
  633. be32 r3
  634. ldxw r2, [r0+28]
  635. be32 r2
  636. ldxw r1, [r0+32]
  637. be32 r1
  638. ldxw r0, [r0+36]
  639. be32 r0
  640. or r0, r1
  641. or r0, r2
  642. or r0, r3
  643. or r0, r4
  644. or r0, r5
  645. or r0, r6
  646. or r0, r7
  647. or r0, r8
  648. or r0, r9
  649. exit
  650. ",
  651. [
  652. 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
  653. 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00,
  654. 0x08, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00
  655. ],
  656. 0x030f0f
  657. );
  658. test_cranelift!(
  659. test_cranelift_ldxw,
  660. "
  661. ldxw r0, [r1+2]
  662. exit
  663. ",
  664. [0xaa, 0xbb, 0x11, 0x22, 0x33, 0x44, 0xcc, 0xdd],
  665. 0x44332211
  666. );
  667. test_cranelift!(
  668. test_cranelift_le16,
  669. "
  670. ldxh r0, [r1]
  671. le16 r0
  672. exit
  673. ",
  674. [0x22, 0x11],
  675. 0x1122
  676. );
  677. test_cranelift!(
  678. test_cranelift_le32,
  679. "
  680. ldxw r0, [r1]
  681. le32 r0
  682. exit
  683. ",
  684. [0x44, 0x33, 0x22, 0x11],
  685. 0x11223344
  686. );
  687. test_cranelift!(
  688. test_cranelift_le64,
  689. "
  690. ldxdw r0, [r1]
  691. le64 r0
  692. exit
  693. ",
  694. [0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11],
  695. 0x1122334455667788
  696. );
  697. test_cranelift!(
  698. test_cranelift_lsh_reg,
  699. "
  700. mov r0, 0x1
  701. mov r7, 4
  702. lsh r0, r7
  703. exit
  704. ",
  705. 0x10
  706. );
  707. test_cranelift!(
  708. test_cranelift_mod,
  709. "
  710. mov32 r0, 5748
  711. mod32 r0, 92
  712. mov32 r1, 13
  713. mod32 r0, r1
  714. exit
  715. ",
  716. 0x5
  717. );
  718. test_cranelift!(
  719. test_cranelift_mod32,
  720. "
  721. lddw r0, 0x100000003
  722. mod32 r0, 3
  723. exit
  724. ",
  725. 0x0
  726. );
  727. test_cranelift!(
  728. test_cranelift_mod64,
  729. "
  730. mov32 r0, -1316649930
  731. lsh r0, 32
  732. or r0, 0x100dc5c8
  733. mov32 r1, 0xdde263e
  734. lsh r1, 32
  735. or r1, 0x3cbef7f3
  736. mod r0, r1
  737. mod r0, 0x658f1778
  738. exit
  739. ",
  740. 0x30ba5a04
  741. );
  742. test_cranelift!(
  743. test_cranelift_mov,
  744. "
  745. mov32 r1, 1
  746. mov32 r0, r1
  747. exit
  748. ",
  749. 0x1
  750. );
  751. test_cranelift!(
  752. test_cranelift_mul32_imm,
  753. "
  754. mov r0, 3
  755. mul32 r0, 4
  756. exit
  757. ",
  758. 0xc
  759. );
  760. test_cranelift!(
  761. test_cranelift_mul32_reg,
  762. "
  763. mov r0, 3
  764. mov r1, 4
  765. mul32 r0, r1
  766. exit
  767. ",
  768. 0xc
  769. );
  770. test_cranelift!(
  771. test_cranelift_mul32_reg_overflow,
  772. "
  773. mov r0, 0x40000001
  774. mov r1, 4
  775. mul32 r0, r1
  776. exit
  777. ",
  778. 0x4
  779. );
  780. test_cranelift!(
  781. test_cranelift_mul64_imm,
  782. "
  783. mov r0, 0x40000001
  784. mul r0, 4
  785. exit
  786. ",
  787. 0x100000004
  788. );
  789. test_cranelift!(
  790. test_cranelift_mul64_reg,
  791. "
  792. mov r0, 0x40000001
  793. mov r1, 4
  794. mul r0, r1
  795. exit
  796. ",
  797. 0x100000004
  798. );
  799. test_cranelift!(
  800. test_cranelift_neg64,
  801. "
  802. mov32 r0, 2
  803. neg r0
  804. exit
  805. ",
  806. 0xfffffffffffffffe
  807. );
  808. test_cranelift!(
  809. test_cranelift_neg,
  810. "
  811. mov32 r0, 2
  812. neg32 r0
  813. exit
  814. ",
  815. 0xfffffffe
  816. );
  817. test_cranelift!(
  818. test_cranelift_rhs32,
  819. "
  820. xor r0, r0
  821. sub r0, 1
  822. rsh32 r0, 8
  823. exit
  824. ",
  825. 0x00ffffff
  826. );
  827. test_cranelift!(
  828. test_cranelift_rsh_reg,
  829. "
  830. mov r0, 0x10
  831. mov r7, 4
  832. rsh r0, r7
  833. exit
  834. ",
  835. 0x1
  836. );
  837. test_cranelift!(
  838. test_cranelift_stack,
  839. "
  840. mov r1, 51
  841. stdw [r10-16], 0xab
  842. stdw [r10-8], 0xcd
  843. and r1, 1
  844. lsh r1, 3
  845. mov r2, r10
  846. add r2, r1
  847. ldxdw r0, [r2-16]
  848. exit
  849. ",
  850. 0xcd
  851. );
  852. #[test]
  853. fn test_cranelift_stack2() {
  854. let prog = assemble(
  855. "
  856. stb [r10-4], 0x01
  857. stb [r10-3], 0x02
  858. stb [r10-2], 0x03
  859. stb [r10-1], 0x04
  860. mov r1, r10
  861. mov r2, 0x4
  862. sub r1, r2
  863. call 1
  864. mov r1, 0
  865. ldxb r2, [r10-4]
  866. ldxb r3, [r10-3]
  867. ldxb r4, [r10-2]
  868. ldxb r5, [r10-1]
  869. call 0
  870. xor r0, 0x2a2a2a2a
  871. exit",
  872. )
  873. .unwrap();
  874. let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
  875. vm.register_helper(0, helpers::gather_bytes).unwrap();
  876. vm.register_helper(1, helpers::memfrob).unwrap();
  877. assert_eq!(vm.execute_cranelift().unwrap(), 0x01020304);
  878. }
  879. test_cranelift!(
  880. test_cranelift_stb,
  881. "
  882. stb [r1+2], 0x11
  883. ldxb r0, [r1+2]
  884. exit
  885. ",
  886. [0xaa, 0xbb, 0xff, 0xcc, 0xdd],
  887. 0x11
  888. );
  889. test_cranelift!(
  890. test_cranelift_stdw,
  891. "
  892. stdw [r1+2], 0x44332211
  893. ldxdw r0, [r1+2]
  894. exit
  895. ",
  896. [0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd],
  897. 0x44332211
  898. );
  899. test_cranelift!(
  900. test_cranelift_sth,
  901. "
  902. sth [r1+2], 0x2211
  903. ldxh r0, [r1+2]
  904. exit
  905. ",
  906. [0xaa, 0xbb, 0xff, 0xff, 0xcc, 0xdd],
  907. 0x2211
  908. );
  909. #[test]
  910. #[ignore]
  911. fn test_cranelift_string_stack() {
  912. let prog = assemble(
  913. "
  914. mov r1, 0x78636261
  915. stxw [r10-8], r1
  916. mov r6, 0x0
  917. stxb [r10-4], r6
  918. stxb [r10-12], r6
  919. mov r1, 0x79636261
  920. stxw [r10-16], r1
  921. mov r1, r10
  922. add r1, -8
  923. mov r2, r1
  924. call 0x4
  925. mov r1, r0
  926. mov r0, 0x1
  927. lsh r1, 0x20
  928. rsh r1, 0x20
  929. jne r1, 0x0, +11
  930. mov r1, r10
  931. add r1, -8
  932. mov r2, r10
  933. add r2, -16
  934. call 0x4
  935. mov r1, r0
  936. lsh r1, 0x20
  937. rsh r1, 0x20
  938. mov r0, 0x1
  939. jeq r1, r6, +1
  940. mov r0, 0x0
  941. exit",
  942. )
  943. .unwrap();
  944. let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
  945. vm.register_helper(4, helpers::strcmp).unwrap();
  946. assert_eq!(vm.execute_cranelift().unwrap(), 0x0);
  947. }
  948. test_cranelift!(
  949. test_cranelift_stw,
  950. "
  951. stw [r1+2], 0x44332211
  952. ldxw r0, [r1+2]
  953. exit
  954. ",
  955. [0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd],
  956. 0x44332211
  957. );
  958. test_cranelift!(
  959. test_cranelift_stxb,
  960. "
  961. mov32 r2, 0x11
  962. stxb [r1+2], r2
  963. ldxb r0, [r1+2]
  964. exit
  965. ",
  966. [0xaa, 0xbb, 0xff, 0xcc, 0xdd],
  967. 0x11
  968. );
  969. test_cranelift!(
  970. test_cranelift_stxb_all,
  971. "
  972. mov r0, 0xf0
  973. mov r2, 0xf2
  974. mov r3, 0xf3
  975. mov r4, 0xf4
  976. mov r5, 0xf5
  977. mov r6, 0xf6
  978. mov r7, 0xf7
  979. mov r8, 0xf8
  980. stxb [r1], r0
  981. stxb [r1+1], r2
  982. stxb [r1+2], r3
  983. stxb [r1+3], r4
  984. stxb [r1+4], r5
  985. stxb [r1+5], r6
  986. stxb [r1+6], r7
  987. stxb [r1+7], r8
  988. ldxdw r0, [r1]
  989. be64 r0
  990. exit
  991. ",
  992. [0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff],
  993. 0xf0f2f3f4f5f6f7f8
  994. );
  995. test_cranelift!(
  996. test_cranelift_stxb_all2,
  997. "
  998. mov r0, r1
  999. mov r1, 0xf1
  1000. mov r9, 0xf9
  1001. stxb [r0], r1
  1002. stxb [r0+1], r9
  1003. ldxh r0, [r0]
  1004. be16 r0
  1005. exit
  1006. ",
  1007. [0xff, 0xff],
  1008. 0xf1f9
  1009. );
  1010. test_cranelift!(
  1011. test_cranelift_stxb_chain,
  1012. "
  1013. mov r0, r1
  1014. ldxb r9, [r0+0]
  1015. stxb [r0+1], r9
  1016. ldxb r8, [r0+1]
  1017. stxb [r0+2], r8
  1018. ldxb r7, [r0+2]
  1019. stxb [r0+3], r7
  1020. ldxb r6, [r0+3]
  1021. stxb [r0+4], r6
  1022. ldxb r5, [r0+4]
  1023. stxb [r0+5], r5
  1024. ldxb r4, [r0+5]
  1025. stxb [r0+6], r4
  1026. ldxb r3, [r0+6]
  1027. stxb [r0+7], r3
  1028. ldxb r2, [r0+7]
  1029. stxb [r0+8], r2
  1030. ldxb r1, [r0+8]
  1031. stxb [r0+9], r1
  1032. ldxb r0, [r0+9]
  1033. exit
  1034. ",
  1035. [0x2a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00],
  1036. 0x2a
  1037. );
  1038. test_cranelift!(
  1039. test_cranelift_stxdw,
  1040. "
  1041. mov r2, -2005440939
  1042. lsh r2, 32
  1043. or r2, 0x44332211
  1044. stxdw [r1+2], r2
  1045. ldxdw r0, [r1+2]
  1046. exit
  1047. ",
  1048. [0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd],
  1049. 0x8877665544332211
  1050. );
  1051. test_cranelift!(
  1052. test_cranelift_stxh,
  1053. "
  1054. mov32 r2, 0x2211
  1055. stxh [r1+2], r2
  1056. ldxh r0, [r1+2]
  1057. exit
  1058. ",
  1059. [0xaa, 0xbb, 0xff, 0xff, 0xcc, 0xdd],
  1060. 0x2211
  1061. );
  1062. test_cranelift!(
  1063. test_cranelift_stxw,
  1064. "
  1065. mov32 r2, 0x44332211
  1066. stxw [r1+2], r2
  1067. ldxw r0, [r1+2]
  1068. exit
  1069. ",
  1070. [0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd],
  1071. 0x44332211
  1072. );
  1073. const PROG_TCP_PORT_80: [u8; 152] = [
  1074. 0x71, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x13, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
  1075. 0x67, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1076. 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00,
  1077. 0x71, 0x12, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x02, 0x0a, 0x00, 0x06, 0x00, 0x00, 0x00,
  1078. 0x71, 0x12, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
  1079. 0x57, 0x02, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x67, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
  1080. 0x0f, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
  1081. 0x15, 0x02, 0x02, 0x00, 0x00, 0x50, 0x00, 0x00, 0x69, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1082. 0x55, 0x01, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
  1083. 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1084. ];
  1085. #[test]
  1086. #[ignore]
  1087. fn test_cranelift_tcp_port80_match() {
  1088. let mem = &mut [
  1089. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45,
  1090. 0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
  1091. 0xc0, 0xa8, 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1092. 0x00, 0x50, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1093. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1094. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1095. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1096. ];
  1097. let prog = &PROG_TCP_PORT_80;
  1098. let vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
  1099. assert_eq!(vm.execute_cranelift(mem).unwrap(), 0x1);
  1100. }
  1101. #[test]
  1102. #[ignore]
  1103. fn test_cranelift_tcp_port80_nomatch() {
  1104. let mem = &mut [
  1105. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45,
  1106. 0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
  1107. 0xc0, 0xa8, 0x00, 0x02, 0x00, 0x16, 0x27, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1108. 0x00, 0x51, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1109. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1110. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1111. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1112. ];
  1113. let prog = &PROG_TCP_PORT_80;
  1114. let vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
  1115. assert_eq!(vm.execute_cranelift(mem).unwrap(), 0x0);
  1116. }
  1117. #[test]
  1118. #[ignore]
  1119. fn test_cranelift_tcp_port80_nomatch_ethertype() {
  1120. let mem = &mut [
  1121. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x01, 0x45,
  1122. 0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
  1123. 0xc0, 0xa8, 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1124. 0x00, 0x50, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1125. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1126. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1127. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1128. ];
  1129. let prog = &PROG_TCP_PORT_80;
  1130. let vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
  1131. assert_eq!(vm.execute_cranelift(mem).unwrap(), 0x0);
  1132. }
  1133. #[test]
  1134. #[ignore]
  1135. fn test_cranelift_tcp_port80_nomatch_proto() {
  1136. let mem = &mut [
  1137. 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45,
  1138. 0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
  1139. 0xc0, 0xa8, 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
  1140. 0x00, 0x50, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1141. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1142. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1143. 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
  1144. ];
  1145. let prog = &PROG_TCP_PORT_80;
  1146. let vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
  1147. assert_eq!(vm.execute_cranelift(mem).unwrap(), 0x0);
  1148. }
  1149. #[test]
  1150. #[ignore]
  1151. fn test_cranelift_tcp_sack_match() {
  1152. let mut mem = TCP_SACK_MATCH.to_vec();
  1153. let prog = assemble(TCP_SACK_ASM).unwrap();
  1154. let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
  1155. assert_eq!(vm.execute_cranelift(mem.as_mut_slice()).unwrap(), 0x1);
  1156. }
  1157. #[test]
  1158. #[ignore]
  1159. fn test_cranelift_tcp_sack_nomatch() {
  1160. let mut mem = TCP_SACK_NOMATCH.to_vec();
  1161. let prog = assemble(TCP_SACK_ASM).unwrap();
  1162. let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
  1163. assert_eq!(vm.execute_cranelift(mem.as_mut_slice()).unwrap(), 0x0);
  1164. }