QEMU.js: i kēia manawa koʻikoʻi a me WASM

I kekahi manawa ua hoʻoholo wau no ka leʻaleʻa e hōʻoia i ka hoʻololi o ke kaʻina hana a aʻo i ka hana ʻana i ka JavaScript (ʻoi aku ka pololei, Asm.js) mai ka helu mīkini. Ua koho ʻia ʻo QEMU no ka hoʻokolohua, a ma hope mai ua kākau ʻia kahi ʻatikala ma Habr. Ma nā ʻōlelo ua ʻōlelo ʻia iaʻu e hana hou i ka papahana ma WebAssembly, a haʻalele iaʻu iho kokoke pau ʻAʻole wau i makemake i ka papahana ... Ke hele nei ka hana, akā lohi loa, a i kēia manawa, i kēia manawa ua puka mai kēlā ʻatikala. ka manaʻo ma ke kumuhana "Pehea i pau ai?" I ka pane ʻana i kaʻu pane kikoʻī, lohe au "Me he ʻatikala kēia." ʻAe, inā hiki iā ʻoe, aia kahi ʻatikala. Malia paha e loaʻa i kekahi mea pono. Mai ia mea e aʻo ai ka mea heluhelu i kekahi mau ʻoiaʻiʻo e pili ana i ka hoʻolālā ʻana o ka QEMU code generation backends, a me pehea e kākau ai i kahi mea hōʻuluʻulu Just-in-Time no kahi noi pūnaewele.

hana

No ka mea ua aʻo mua au i ka "how" port QEMU i JavaScript, i kēia manawa ua hoʻoholo ʻia e hana me ke akamai a ʻaʻole e hana hou i nā hewa kahiko.

Helu helu ʻekahi: lālā mai ka hoʻokuʻu kiko

ʻO kaʻu hewa mua, ʻo ia ka ʻoki ʻana i kaʻu mana mai ka mana o luna 2.4.1. A laila, manaʻo maikaʻi ia iaʻu: inā loaʻa ka hoʻokuʻu kiko, a laila ʻoi aku ka paʻa ma mua o ka 2.4 maʻalahi, a ʻoi aku hoʻi ka lālā. master. A no koʻu hoʻolālā ʻana e hoʻohui i ka nui kūpono o kaʻu mau pōpoki ponoʻī, ʻaʻole pono wau i nā mea ʻē aʻe. Pēlā paha ka hopena. Akā, eia ka mea: ʻAʻole kū mālie ʻo QEMU, a i kekahi manawa ua hoʻolaha lākou i ka optimization o ke code i hana ʻia e ka pākēneka 10. "ʻAe, i kēia manawa e hoʻokuʻu wau," noʻonoʻo wau a wāwahi. Maʻaneʻi, pono mākou e hana i kahi digression: ma muli o ke ʻano o ka QEMU.js i hoʻokahi-threaded a me ka ʻoiaʻiʻo o ka QEMU kumu ʻaʻole i hōʻike i ka nele o ka multi-threading (ʻo ia hoʻi, ka hiki ke hana i kekahi mau ala code pili ʻole, a ʻAʻole wale "hoʻohana i nā kernels āpau") he mea koʻikoʻi no ia, ʻo nā hana nui o nā kaula aʻu i "hoʻohuli" i hiki ke kelepona mai waho. Ua hana kēia i kekahi mau pilikia kūlohelohe i ka wā o ka hui ʻana. Eia naʻe, ʻo ka ʻoiaʻiʻo o kekahi o nā hoʻololi mai ka lālā master, ka mea aʻu i ho'āʻo ai e hoʻohui i kaʻu code, ua koho ʻia nō hoʻi nā cherry i ka hoʻokuʻu ʻana (a no laila i loko o koʻu lālā) ʻaʻole paha i hoʻohui i ka ʻoluʻolu.

Ma keʻano laulā, ua hoʻoholo wau he mea kūpono ke hoʻolei aku i ka prototype, hoʻokaʻawale iā ia no nā ʻāpana a kūkulu i kahi mana hou mai ka ʻōpala e pili ana i kahi mea hou aʻe mai kēia manawa. master.

Helu helu ʻelua: ke ʻano TLP

ʻO ka mea nui, ʻaʻole kēia he kuhi, ma ke ʻano holoʻokoʻa, he hiʻohiʻona wale nō ia o ka hoʻokumu ʻana i kahi papahana i nā kūlana o ka hoʻomaopopo piha ʻole ʻana o "kahi a pehea e neʻe ai?" A ma ka laulā "e hiki mākou i laila?" Ma keia mau kulana ka hoʻopololei ʻana he koho kūpono, akā, ʻoiaʻiʻo, ʻaʻole wau makemake e hana hou me ka pono ʻole. I kēia manawa makemake wau e hana me ke akamai: hana atomic, hoʻololi i nā code conscious (a ʻaʻole "ka hoʻopaʻa ʻana i nā huaʻōlelo random a hiki i ka hui ʻana (me nā ʻōlelo aʻo)", e like me kā Linus Torvalds i ʻōlelo ai e pili ana i kekahi, e like me Wikiquote), etc.

ʻO ka hewa helu ʻekolu: ke komo ʻana i ka wai me ka ʻike ʻole i ke ala

ʻAʻole naʻe au i hoʻopau loa i kēia, akā i kēia manawa ua hoʻoholo wau ʻaʻole e hahai i ke ala o ke kūʻē liʻiliʻi loa, a e hana "ma ke ʻano he kanaka makua," ʻo ia hoʻi, e kākau i kaʻu TCG backend mai ka wā ʻōpala, i ʻole e ʻōlelo ma hope, "ʻAe, ʻoiaʻiʻo nō kēia, lohi, akā ʻaʻole hiki iaʻu ke hoʻomalu i nā mea āpau - ʻo ia ke ʻano o ka kākau ʻana o TCI ..." Eia kekahi, ʻike ʻia kēia ma mua he hopena maopopo, ʻoiai Hoʻopuka wau i ke code binary. E like me kā lākou e ʻōlelo nei, “Ua hui ʻo Ghentу, akā ʻaʻole kēlā ": ʻo ke code, ʻoiaʻiʻo, binary, akā ʻaʻole hiki ke hoʻololi wale ʻia ka mana iā ia - pono e hoʻokuʻu ʻia i loko o ka polokalamu kele no ka hoʻohui ʻana, e hopena i kekahi mea mai ka honua JS, e pono mau ana. e hoolaia ma kahi. Eia nō naʻe, ma nā hale hoʻolālā RISC maʻamau, e like me kaʻu e hoʻomaopopo ai, ʻo kahi kūlana maʻamau ka pono e hoʻonohonoho hou i ka cache aʻo no ka code regenerated - inā ʻaʻole kēia ka mea e pono ai mākou, a laila, i kekahi hihia, kokoke. Eia kekahi, mai ka'u ho'āʻo hope loa, ua aʻo au ʻaʻole e hoʻoneʻe ʻia ka mana i ka waena o ka poloka unuhi, no laila ʻaʻole pono mākou i ka bytecode i unuhi ʻia mai kekahi offset, a hiki iā mākou ke hoʻopuka mai ka hana ma TB .

Hele mai lakou a kikeke

ʻOiai ua hoʻomaka wau e kākau hou i ke code i Iulai, ua ʻike ʻole ʻia kahi kiki kilokilo: ʻo ka maʻamau nā leka mai GitHub e hōʻea mai i nā leka e pili ana i nā pane i nā pilikia a me nā noi huki, akā eia, hikiwawe haʻi ʻia ma ka pae ʻO Binaryen ma ke ʻano he qemu hope i loko o ka pōʻaiapili, "Ua hana ʻo ia i mea like, malia paha e ʻōlelo ʻo ia i kekahi mea." Ke kamaʻilio nei mākou e pili ana i ka hoʻohana ʻana i ka waihona pili ʻo Emscripten Binaryen e hana i ka WASM JIT. ʻAe, ua ʻōlelo wau he laikini Apache 2.0 kāu ma laila, a ua māhele ʻia ʻo QEMU holoʻokoʻa ma lalo o GPLv2, a ʻaʻole kūpono loa lākou. Ua hiki koke mai ka laikini hoʻoponopono i kekahi mea (ʻAʻole au i ʻike: hoʻololi paha, ʻelua laikini paha, ʻokoʻa paha ...). ʻO kēia, ʻoiaʻiʻo, ua hauʻoli wau, no ka mea ma ia manawa ua nānā pono wau hōʻano binary WebAssembly, a ua kaumaha au a hiki ʻole ke hoʻomaopopo. Aia kekahi hale waihona puke e ʻai i nā poloka kumu me ka pakuhi hoʻololi, hana i ka bytecode, a holo pū i loko o ka unuhi ʻōlelo ponoʻī, inā pono.

A laila ua nui aku he leka ma ka papa inoa leka uila QEMU, akā ʻoi aku kēia e pili ana i ka nīnau, "ʻO wai ka mea e pono ai?" A ʻo ia nō hikiwawe, ua ikeia he pono. Ma ka liʻiliʻi loa, hiki iā ʻoe ke ʻohi i nā mea hiki ke hoʻohana ʻia, inā ʻoi aku ka wikiwiki a i ʻole ka wikiwiki.

  • ka hoʻomaka ʻana i kahi mea hoʻonaʻauao me ka ʻole o ka hoʻokomo ʻana
  • virtualization ma iOS, kahi, e like me ka lono, ʻo ka noi wale nō i loaʻa ke kuleana e code generation ma ka lele ʻana he mīkini JS (ʻoiaʻiʻo anei kēia?)
  • hōʻike o ka mini-OS - hoʻokahi-floppy, kūkulu ʻia, nā ʻano firmware āpau, etc.

Nā hiʻohiʻona o ka polokalamu kele pūnaewele

E like me kaʻu i ʻōlelo ai, pili ʻo QEMU i ka multithreading, akā ʻaʻole i loaʻa i ka polokalamu kele pūnaewele. ʻAe, ʻo ia hoʻi, ʻaʻole ... I ka wā mua ʻaʻole loa ia, a laila ua ʻike ʻia nā WebWorkers - i koʻu hoʻomaopopo ʻana, he multithreading kēia e pili ana i ka hele ʻana o ka memo. me ka ʻole o nā mea hoʻololi like ʻole. ʻO ka mea maʻamau, hana kēia i nā pilikia koʻikoʻi i ka lawe ʻana i nā code i loaʻa ma muli o ke kumu hoʻomanaʻo like. A laila, ma lalo o ke kaomi lehulehu, ua hoʻokō ʻia ma lalo o ka inoa SharedArrayBuffers. Ua hoʻolauna mālie ia, hoʻolauleʻa lākou i kona hoʻomaka ʻana i nā polokalamu kele pūnaewele ʻē aʻe, a laila hoʻolauleʻa lākou i ka New Year, a laila Meltdown ... Ma hope o lākou i hele mai ai i ka hopena o ka coarse a i ʻole ke ana o ka manawa, akā me ke kōkua o ka hoʻomanaʻo ʻana a me kahi. ʻo ka milo e hoʻonui ana i ka counter, ua like nā mea a pau e hana pololei ana. No laila ua hoʻopau mākou i ka multithreading me ka hoʻomanaʻo like. Me he mea lā ua hoʻohuli hou lākou iā ia ma hope, akā, e like me ka mea i maopopo mai ka hoʻokolohua mua, aia ke ola me ka ʻole, a inā pēlā, e hoʻāʻo mākou e hana me ka hilinaʻi ʻole i ka multithreading.

ʻO ka lua o ka hiʻohiʻona ʻo ka hiki ʻole o nā manipulations haʻahaʻa haʻahaʻa me ka waihona: ʻaʻole hiki iā ʻoe ke lawe wale, mālama i ka pōʻaiapili o kēia manawa a hoʻololi i kahi mea hou me kahi waihona hou. Hoʻokele ʻia ka waihona kelepona e ka mīkini virtual JS. Me he mea lā, he aha ka pilikia, ʻoiai ua hoʻoholo mākou e hoʻokele i nā kahe mua me ka lima? ʻO ka ʻoiaʻiʻo, ua hoʻokō ʻia ka poloka I/O ma QEMU ma o nā coroutines, a ʻo ia kahi e hiki ai i nā manipulations haʻahaʻa haʻahaʻa. ʻO ka mea pōmaikaʻi, ua loaʻa iā Emscipten kahi hana no nā hana asynchronous, ʻelua: Asyncify и Emterpreter. Hoʻohana ka mea mua ma o ka bloat nui i ka code JavaScript i hana ʻia a ʻaʻole kākoʻo hou ʻia. ʻO ka lua ka "ala pololei" o kēia manawa a hana ʻia ma o ka hanauna bytecode no ka unuhi ʻōlelo maoli. Ke hana nei, ʻoiaʻiʻo, lohi, akā ʻaʻole ia e hoʻoulu i ke code. ʻOiaʻiʻo, pono e hāʻawi kūʻokoʻa ʻia ke kākoʻo no nā coroutines no kēia mīkini (ua loaʻa i nā coroutines i kākau ʻia no Asyncify a aia kahi hoʻokō o ka API like no Emterpreter, pono ʻoe e hoʻopili iā lākou).

I kēia manawa, ʻaʻole hiki iaʻu ke hoʻokaʻawale i ke code i hoʻokahi i hōʻuluʻulu ʻia ma WASM a unuhi ʻia me ka hoʻohana ʻana iā Emterpreter, no laila ʻaʻole hana nā mea poloka (e ʻike i ka moʻolelo aʻe, e like me kā lākou e ʻōlelo nei ...). ʻO ia hoʻi, i ka hopena, pono ʻoe e kiʻi i kahi mea e like me kēia mea ʻakaʻaka.

  • unuhi ʻia ka poloka I/O. ʻAe, ua manaʻo maoli ʻoe i ka NVMe emulated me ka hana maoli? 🙂
  • ʻO ka helu QEMU nui i hoʻohui pū ʻia me ka statically (unuhi, nā mea hoʻohana ʻē aʻe, etc.)
  • i hōʻuluʻulu ikaika i ka helu malihini i WASM

Nā hiʻohiʻona o nā kumu QEMU

E like me kāu i manaʻo mua ai, ua hoʻokaʻawale ʻia ke code no ka hoʻohālikelike ʻana i nā hale hoʻokipa malihini a me ke code no ka hoʻokumu ʻana i nā ʻōlelo kuhikuhi mīkini host ma QEMU. ʻOiaʻiʻo, ʻoi aku ka maʻalahi:

  • aia nā hale hoʻokipa malihini
  • ka mea nā mea hoʻokē, ʻo ia hoʻi, KVM no ka virtualization hardware ma Linux (no ka malihini a me nā ʻōnaehana hoʻokipa i kūpono kekahi me kekahi), TCG no ka JIT code generation ma nā wahi āpau. E hoʻomaka ana me QEMU 2.9, ʻike ʻia ke kākoʻo no ka HAXM hardware virtualization standard ma Windows (nā kikoʻī)
  • inā hoʻohana ʻia ʻo TCG a ʻaʻole i ka virtualization hardware, a laila loaʻa iā ia ke kākoʻo hoʻokaʻawale code generation no kēlā me kēia hale hoʻokipa, a me ka unuhi ʻōlelo honua.
  • ... a puni kēia mau mea a pau - nā peripheral i hoʻohālikelike ʻia, ka mea hoʻohana, ka neʻe ʻana, ka hoʻopaʻa ʻana i ka moʻolelo, etc.

Ma ke ala, ua ʻike anei ʻoe: Hiki i ka QEMU ke hoʻohālike i ka lolouila holoʻokoʻa wale nō, akā ʻo ke kaʻina hana no kahi kaʻina hana hoʻohana ʻokoʻa i loko o ka kernel host, i hoʻohana ʻia, no ka laʻana, e ka AFL fuzzer no ka mea hoʻohana binary. Makemake paha kekahi e lawe i kēia ʻano hana o QEMU iā JS? 😉

E like me nā polokalamu manuahi lōʻihi, kūkulu ʻia ʻo QEMU ma o ke kelepona configure и make. E ʻōlelo mākou e hoʻoholo ʻoe e hoʻohui i kekahi mea: kahi backend TCG, hoʻokō thread, kahi mea ʻē aʻe. Mai wikiwiki e hauʻoli/weliweli (e kaha i lalo e like me ke kūpono) i ka manaʻo e kamaʻilio me Autoconf - ʻoiaʻiʻo, configure Ua kākau ʻia ʻo QEMU a ʻaʻole i hana ʻia mai kekahi mea.

Pūnaewele

No laila he aha kēia mea i kapa ʻia ʻo WebAssembly (aka WASM)? He pani kēia no Asm.js, ʻaʻole ia e hoʻohālike hou ana he code JavaScript kūpono. ʻO ka mea ʻē aʻe, ʻo ia wale nō ka binary a hoʻopaʻa ʻia, a ʻo ke kākau wale ʻana i kahi integer i loko o ia mea ʻaʻole maʻalahi loa: no ka compactness, mālama ʻia ia i ke ʻano. LEB128.

Ua lohe paha ʻoe e pili ana i ka algorithm relooping no Asm.js - ʻo kēia ka hoʻihoʻi ʻana i nā ʻōlelo aʻoaʻo kahe "kiʻekiʻe" (ʻo ia hoʻi, inā-a laila, nā puka lou, a me nā mea ʻē aʻe), kahi i hoʻolālā ʻia ai nā mīkini JS, mai ka haʻahaʻa haʻahaʻa LLVM IR, kokoke i ke code mīkini i hoʻokō ʻia e ka mea hana. ʻO ka mea maʻamau, ʻoi aku ka kokoke o ka hōʻike waena o QEMU i ka lua. Me he mea lā eia ʻo ia, bytecode, ka hopena o ka ʻeha ... A laila aia nā poloka, inā-a laila-ē aʻe a me nā puka lou!

A ʻo kēia kekahi kumu e pono ai ʻo Binaryen: hiki iā ia ke ʻae maoli i nā poloka kiʻekiʻe kokoke i ka mea e mālama ʻia ma WASM. Akā hiki iā ia ke hana i ke code mai kahi pakuhi o nā poloka kumu a me nā hoʻololi ma waena o lākou. ʻAe, ua ʻōlelo mua wau e hūnā ia i ka waihona waihona WebAssembly ma hope o ka C/C++ API kūpono.

ʻO TCG (Ka mea hoʻopuka helu liʻiliʻi)

TCG i kinohi backend no ka C compiler. A laila, ʻike ʻia, ʻaʻole hiki iā ia ke kū i ka hoʻokūkū me GCC, akā i ka hopena ua loaʻa kona wahi ma QEMU ma ke ʻano he code generation mechanism no ke kahua hoʻokipa. Aia kekahi backend TCG e hoʻopuka i kekahi bytecode abstract, i hoʻokō koke ʻia e ka unuhi ʻōlelo, akā ua hoʻoholo wau e pale i ka hoʻohana ʻana i kēia manawa. Eia naʻe, ʻo ka ʻoiaʻiʻo ma QEMU ua hiki ke hiki ke hoʻololi i ka TB i hana ʻia ma o ka hana tcg_qemu_tb_exec, ua lilo ia i mea pono loa ia'u.

No ka hoʻohui ʻana i kahi backend TCG hou i QEMU, pono ʻoe e hana i kahi subdirectory tcg/<имя архитектуры> (i kēia hihia, tcg/binaryen), a he ʻelua mau faila: tcg-target.h и tcg-target.inc.c и kuhikuhi e pili ana configure. Hiki iā ʻoe ke waiho i nā faila ʻē aʻe ma laila, akā, e like me kāu e koho ai mai nā inoa o kēia mau mea ʻelua, e hoʻokomo ʻia lāua ʻelua ma kahi: hoʻokahi ma ke ʻano he faila maʻamau (ua komo i loko tcg/tcg.h, a aia kekahi i nā faila ʻē aʻe ma nā papa kuhikuhi tcg, accel a ʻaʻole wale), ʻo kekahi - ma ke ʻano he code snippet in tcg/tcg.c, akā hiki iā ia ke komo i kāna mau hana static.

I ka hoʻoholo ʻana e hoʻolōʻihi wau i ka manawa ma nā noiʻi kikoʻī o ke ʻano o ka hana ʻana, ua kope wale wau i nā "skeletons" o kēia mau faila ʻelua mai kahi hoʻokō hope ʻē aʻe, e hōʻike pololei ana i kēia ma ke poʻo laikini.

waihona tcg-target.h loaʻa nui nā hoʻonohonoho ma ke ʻano #define-s:

  • ehia mau papa inoa a he aha ka laula ma ka hale hoʻolālā pahuhopu (ua loaʻa iā mākou ka nui e like me kā mākou makemake, e like me kā mākou makemake - ʻoi aku ka nīnau e pili ana i ka mea e hoʻopuka ʻia i ke code ʻoi aku ka maikaʻi e ka polokalamu kele ma ka hale hoʻolālā "kūpono piha". ...)
  • alignment o nā ʻōlelo aʻoaʻo: ma x86, a hiki i ka TCI, ʻaʻole i kūlike nā ʻōlelo aʻoaʻo, akā e hoʻokomo wau i loko o ke code buffer ʻaʻole nā ​​ʻōlelo kuhikuhi, akā kuhikuhi i nā hale waihona puke Binaryen, no laila e ʻōlelo wau: 4 bytes
  • he aha nā ʻōlelo aʻoaʻo e hiki ai i ka hope ke hoʻopuka - hoʻokomo mākou i nā mea āpau a mākou e ʻike ai ma Binaryen, e hoʻokaʻawale ka mea hoʻokele i ke koena i nā mea maʻalahi.
  • He aha ka nui o ka waihona TLB i noi ʻia e ka hope. ʻO ka mea ʻoiaʻiʻo ma QEMU he koʻikoʻi nā mea āpau: ʻoiai aia nā hana kōkua e hana i ka ukana / hale kūʻai me ka noʻonoʻo ʻana i ka malihini MMU (i hea mākou me ka ʻole o kēia manawa?), mālama lākou i kā lākou unuhi unuhi ma ke ʻano o kahi hale. ʻO ka hoʻoili ʻana he mea maʻalahi ia e hoʻopili pololei i nā poloka hoʻolaha. ʻO ka nīnau he aha ka offset i loko o kēia hoʻolālā e hana maikaʻi ʻia e kahi liʻiliʻi a wikiwiki hoʻi o nā kauoha?
  • ma aneʻi hiki iā ʻoe ke hoʻololi i ke kumu o hoʻokahi a ʻelua mau papa inoa i mālama ʻia, hiki iā ʻoe ke kāhea iā TB ma o kahi hana a wehewehe i nā mea liʻiliʻi. inline-hana like flush_icache_range (akā ʻaʻole kēia kā mākou hihia)

waihona tcg-target.inc.c, ʻoiaʻiʻo, ʻoi aku ka nui o ka nui a loaʻa kekahi mau hana pono:

  • ka hoʻomaka ʻana, me nā kapu i hiki ke hana i nā ʻōlelo aʻoaʻo ma nā operand. Ua kope kope ʻia e aʻu mai kahi hope ʻē aʻe
  • hana e lawe i hoʻokahi aʻo bytecode kūloko
  • Hiki iā ʻoe ke kau i nā hana kōkua ma aneʻi, a hiki iā ʻoe ke hoʻohana i nā hana static mai tcg/tcg.c

Noʻu iho, ua koho au i kēia hoʻolālā: i nā huaʻōlelo mua o ka poloka unuhi e hiki mai ana, ua kākau au i ʻehā mau kuhikuhi: kahi hōʻailona hoʻomaka (kahi waiwai ma kahi kokoke. 0xFFFFFFFF, ka mea i hoʻoholo i ke kūlana o kēia manawa o ka TB), ka pōʻaiapili, ka module i hana ʻia, a me ka helu kupua no ka hoʻopau ʻana. I ka mua ua kau ʻia ka māka i loko 0xFFFFFFFF - nkahi n - he helu maikaʻi liʻiliʻi, a i kēlā me kēia manawa i hoʻokō ʻia ma o ka unuhi ʻōlelo ua hoʻonui ʻia e 1. 0xFFFFFFFE, hoʻohui ʻia, mālama ʻia ka module i ka papa hana, lawe ʻia i loko o kahi "launcher" liʻiliʻi, kahi i hele ai ka hoʻokō. tcg_qemu_tb_exec, a ua wehe ʻia ka module mai ka hoʻomanaʻo QEMU.

To parphrase the classics, “Crutch, how much is intertwined in this sound for the proger’s heart...”. Eia naʻe, ua lele ka hoʻomanaʻo ma kekahi wahi. Eia kekahi, ua mālama ʻia ia e QEMU! Ua loaʻa iaʻu kahi code i ka wā e kākau ai i ke aʻo aʻe (maikaʻi, ʻo ia hoʻi, kahi kuhikuhi), holoi i ka mea nona ka loulou ma kēia wahi ma mua, akā ʻaʻole kōkua kēia. ʻOiaʻiʻo, ma ka hihia maʻalahi, hoʻokaʻawale ʻo QEMU i ka hoʻomanaʻo i ka hoʻomaka ʻana a kākau i ke code i hana ʻia ma laila. I ka pau ʻana o ka pale, hoʻolei ʻia ke code a hoʻomaka ka mea aʻe e kākau ma kona wahi.

Ma hope o ke aʻo ʻana i ke code, ʻike wau ua ʻae ka hana hoʻopunipuni me ka helu kilokilo iaʻu ʻaʻole e hāʻule i ka luku ʻana i ka puʻu ma ka hoʻokuʻu ʻana i kahi mea hewa ma kahi paʻa uninitialized ma ka hele mua. Akā ʻo wai ka mea kākau hou i ka buffer e kāpae i kaʻu hana ma hope? E like me ka'ōlelo a nā mea hoʻomohala Emscripten, i ka wā i loaʻa ai iaʻu kahi pilikia, ua hoʻihoʻi au i ke code i hoʻi i ka noi maoli, e hoʻonoho iā Mozilla Record-Replay ma luna ... Ma keʻano laulā, i ka hopena uaʻike wau i kahi mea maʻalahi: no kēlā me kēia poloka, a struct TranslationBlock me kona wehewehe. E noʻonoʻo i hea ... Pololei, ma mua pono o ka poloka i loko o ka pale. I ka ʻike ʻana i kēia, ua hoʻoholo wau e haʻalele i ka hoʻohana ʻana i nā koʻokoʻo (ma ka liʻiliʻi o kekahi), a kiola wale aku i ka helu kilokilo, a hoʻololi i nā huaʻōlelo i koe i struct TranslationBlock, ka hana ʻana i kahi papa inoa pili hoʻokahi i hiki ke hele wikiwiki i ka wā e hoʻihoʻi hou ʻia ai ka huna huna unuhi, a hoʻokuʻu i ka hoʻomanaʻo.

Ke waiho nei kekahi mau koʻokoʻo: no ka laʻana, nā kuhikuhi i kaha ʻia i ke code buffer - maʻalahi kekahi o lākou BinaryenExpressionRef, ʻo ia hoʻi, nānā lākou i nā ʻōlelo e pono e hoʻokomo ʻia i loko o ka poloka kumu i hana ʻia, ʻo ka hapa ke kūlana no ka hoʻololi ʻana ma waena o nā BB, kahi ʻāpana kahi e hele ai. ʻAe, aia nā poloka i hoʻomākaukau ʻia no Relooper pono e hoʻopili ʻia e like me nā kūlana. No ka hoʻokaʻawale ʻana iā lākou, ua hoʻohana ʻia ka manaʻo ua hoʻopili ʻia lākou a pau ma ka liʻiliʻi ʻehā bytes, no laila hiki iā ʻoe ke hoʻohana palekana i nā ʻāpana liʻiliʻi ʻelua no ka lepili, pono ʻoe e hoʻomanaʻo e wehe inā pono. Ma ke ala, ua hoʻohana ʻia ia mau lepili ma QEMU e hōʻike i ke kumu o ka haʻalele ʻana i ka loop TCG.

Ke hoʻohana nei iā Binaryen

Loaʻa nā modula ma WebAssembly i nā hana, aia kēlā me kēia me kahi kino, he ʻōlelo ia. ʻO nā huaʻōlelo he hana unary a me nā hana binary, nā poloka i loaʻa i nā papa inoa o nā ʻōlelo ʻē aʻe, ke kahe mana, etc. E like me kaʻu i ʻōlelo ai, ua hoʻonohonoho pololei ʻia ka kahe mana ma ʻaneʻi e like me nā lālā kiʻekiʻe, nā puka lou, nā kelepona hana, etc. ʻAʻole i hāʻawi ʻia nā hoʻopaʻapaʻa i nā hana ma ka waihona, akā maopopo, e like me JS. Aia kekahi mau hoʻololi honua, akā ʻaʻole wau i hoʻohana iā lākou, no laila ʻaʻole wau e haʻi iā ʻoe e pili ana iā lākou.

Loaʻa i nā hana nā mea hoʻololi kūloko, helu ʻia mai ka ʻole, o ke ʻano: int32 / int64 / lana / pālua. I kēia hihia, ʻo nā mea hoʻololi mua n kūloko nā manaʻo i hāʻawi ʻia i ka hana. E ʻoluʻolu e hoʻomaopopo ʻoiai ʻaʻole haʻahaʻa loa nā mea āpau ma ke ʻano o ka kahe mana, ʻaʻole i lawe ʻia nā integer i ke ʻano "kaulima / ʻole": pehea ke ʻano o ka helu e pili ana i ke code hana.

Ma ka ʻōlelo maʻamau, hāʻawi ʻo Binaryen C-API maʻalahi: hana ʻoe i module, i loko ona hana i nā huaʻōlelo - unary, binary, poloka mai nā ʻōlelo ʻē aʻe, kahe mana, etc. A laila hana ʻoe i kahi hana me kahi ʻōlelo e like me kona kino. Inā loaʻa iā ʻoe, e like me aʻu, ka pakuhi hoʻololi haʻahaʻa, e kōkua ka mea relooper iā ʻoe. E like me kaʻu i hoʻomaopopo ai, hiki ke hoʻohana i ka mana kiʻekiʻe o ka hoʻokō kahe i loko o kahi poloka, ʻoiai ʻaʻole ia e hele ma waho o nā palena o ka poloka - ʻo ia hoʻi, hiki ke hana i ke ala wikiwiki i loko / lohi. ala ala i loko o ka TLB i hoʻopaʻa ʻia i ke code hoʻoili cache, akā ʻaʻole e hoʻopilikia i ke kahe mana "waho". Ke hoʻokuʻu ʻoe i kahi relooper, hoʻokuʻu ʻia kāna mau poloka; ke hoʻokuʻu ʻoe i kahi module, nalo nā ʻōlelo, nā hana, a pēlā aku. kahua kahua.

Eia nō naʻe, inā makemake ʻoe e wehewehe i ke code ma ka lele me ka ʻole o ka hana ʻole ʻana a me ka holoi ʻana i kahi ʻano unuhi, pono paha e hoʻokomo i kēia loiloi i loko o kahi faila C++, a mai laila e hoʻokele pololei i ka API C++ holoʻokoʻa o ka hale waihona puke, me ke kāpae ʻana i ka mākaukau- hana ʻia i nā ʻōwili.

No laila e hana i ke code āu e pono ai

// настроить глобальные параметры (можно поменять потом)
BinaryenSetAPITracing(0);

BinaryenSetOptimizeLevel(3);
BinaryenSetShrinkLevel(2);

// создать модуль
BinaryenModuleRef MODULE = BinaryenModuleCreate();

// описать типы функций (как создаваемых, так и вызываемых)
helper_type  BinaryenAddFunctionType(MODULE, "helper-func", BinaryenTypeInt32(), int32_helper_args, ARRAY_SIZE(int32_helper_args));
// (int23_helper_args приоб^Wсоздаются отдельно)

// сконструировать супер-мега выражение
// ... ну тут уж вы как-нибудь сами :)

// потом создать функцию
BinaryenAddFunction(MODULE, "tb_fun", tb_func_type, func_locals, FUNC_LOCALS_COUNT, expr);
BinaryenAddFunctionExport(MODULE, "tb_fun", "tb_fun");
...
BinaryenSetMemory(MODULE, (1 << 15) - 1, -1, NULL, NULL, NULL, NULL, NULL, 0, 0);
BinaryenAddMemoryImport(MODULE, NULL, "env", "memory", 0);
BinaryenAddTableImport(MODULE, NULL, "env", "tb_funcs");

// запросить валидацию и оптимизацию при желании
assert (BinaryenModuleValidate(MODULE));
BinaryenModuleOptimize(MODULE);

... inā ua poina iaʻu i kekahi mea, e kala mai, e hōʻike wale ana kēia i ka unahi, a aia nā kikoʻī i ka palapala.

A i kēia manawa hoʻomaka ka crack-fex-pex, e like me kēia:

static char buf[1 << 20];
BinaryenModuleOptimize(MODULE);
BinaryenSetMemory(MODULE, 0, -1, NULL, NULL, NULL, NULL, NULL, 0, 0);
int sz = BinaryenModuleWrite(MODULE, buf, sizeof(buf));
BinaryenModuleDispose(MODULE);
EM_ASM({
  var module = new WebAssembly.Module(new Uint8Array(wasmMemory.buffer, $0, $1));
  var fptr = $2;
  var instance = new WebAssembly.Instance(module, {
      'env': {
          'memory': wasmMemory,
          // ...
      }
  );
  // и вот уже у вас есть instance!
}, buf, sz);

I mea e hoʻopili ai i ka honua o QEMU a me JS a i ka manawa like e komo koke i nā hana i hōʻuluʻulu ʻia, ua hana ʻia kahi ʻano (kahi papa o nā hana no ka hoʻokomo ʻana i ka mea hoʻolaha), a ua kau ʻia nā hana i hana ʻia ma laila. No ka helu wikiwiki ʻana i ka papa kuhikuhi, ua hoʻohana mua ʻia ka papa kuhikuhi o ka poloka unuhi huaʻōlelo ʻole e like me ia, akā ua hoʻomaka ka helu kuhikuhi i hoʻohana ʻia me kēia ʻano hoʻohālike e hoʻokomo i loko o ke kahua ma struct TranslationBlock.

Ma ke ala, demo (i kēia manawa me ka laikini murky) hana maikaʻi wale nō ma Firefox. ʻO nā mea hoʻomohala Chrome ʻaʻole mākaukau i ka ʻoiaʻiʻo e makemake ana kekahi e hana i ʻoi aku ma mua o hoʻokahi kaukani mau manawa o nā modules WebAssembly, no laila ua hoʻokaʻawale lākou i kahi gigabyte o kahi kikowaena virtual address no kēlā me kēia...

ʻO ia wale nō i kēia manawa. Aia paha kekahi ʻatikala inā makemake kekahi. ʻO ia hoʻi, aia ma kahi liʻiliʻi pololei loa e hana i na mea poloka. Maikaʻi nō paha ka hoʻohui ʻana o nā modules WebAssembly i mea like ʻole, e like me ka mea maʻamau i ka honua JS, no ka mea, aia nō kahi unuhi ʻōlelo hiki ke hana i kēia mau mea a hiki i ka mākaukau ʻana o ka module ʻōiwi.

ʻO ka nane hope loa: ua hōʻuluʻulu ʻoe i kahi binary ma kahi hoʻolālā 32-bit, akā ʻo ke code, ma o nā hana hoʻomanaʻo, piʻi mai Binaryen, ma kahi o ka waihona, a i ʻole ma kahi ʻē aʻe ma ka 2 GB o luna o ka wahi helu 32-bit. ʻO ka pilikia ʻo ia mai ka manaʻo o Binaryen ke komo nei kēia i kahi helu nui loa. Pehea e hele ai a puni kēia?

Ma ke ala o admin

ʻAʻole wau i hoʻopau i ka hoʻāʻo ʻana i kēia, akā ʻo koʻu manaʻo mua "Pehea inā ua hoʻokomo wau i ka 32-bit Linux?" A laila e noho ʻia ka ʻaoʻao o luna o ka wahi kikoʻī e ka kernel. ʻO ka nīnau wale nō ka nui o nā mea e noho ai: 1 a i ʻole 2 Gb.

Ma ke ʻano o ka mea polokalamu (koho no nā mea hoʻomaʻamaʻa)

E puhi kākou i ka ʻōhū ma luna o ka wahi helu wahi. ʻAʻole maopopo iaʻu ke kumu e hana ai - ma laila ua pono he ahu. Akā "he poʻe hoʻomaʻamaʻa mākou: hana nā mea āpau no mākou, akā ʻaʻohe mea i ʻike i ke kumu ..."

// 2gbubble.c
// Usage: LD_PRELOAD=2gbubble.so <program>

#include <sys/mman.h>
#include <assert.h>

void __attribute__((constructor)) constr(void)
{
  assert(MAP_FAILED != mmap(1u >> 31, (1u >> 31) - (1u >> 20), PROT_NONE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
}

... he ʻoiaʻiʻo ʻaʻole kūpono ia me Valgrind, akā, ʻoi aku ka maikaʻi, ʻo Valgrind ponoʻī e hoʻokuke maikaʻi i nā mea āpau mai laila :)

E hāʻawi paha kekahi i ka wehewehe maikaʻi aʻe o ka hana ʻana o kēia code aʻu...

Source: www.habr.com

Pākuʻi i ka manaʻo hoʻopuka