aot_loader.c 162 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627362836293630363136323633363436353636363736383639364036413642364336443645364636473648364936503651365236533654365536563657365836593660366136623663366436653666366736683669367036713672367336743675367636773678367936803681368236833684368536863687368836893690369136923693369436953696369736983699370037013702370337043705370637073708370937103711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780378137823783378437853786378737883789379037913792379337943795379637973798379938003801380238033804380538063807380838093810381138123813381438153816381738183819382038213822382338243825382638273828382938303831383238333834383538363837383838393840384138423843384438453846384738483849385038513852385338543855385638573858385938603861386238633864386538663867386838693870387138723873387438753876387738783879388038813882388338843885388638873888388938903891389238933894389538963897389838993900390139023903390439053906390739083909391039113912391339143915391639173918391939203921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990399139923993399439953996399739983999400040014002400340044005400640074008400940104011401240134014401540164017401840194020402140224023402440254026402740284029403040314032403340344035403640374038403940404041404240434044404540464047404840494050405140524053405440554056405740584059406040614062406340644065406640674068406940704071407240734074407540764077407840794080408140824083408440854086408740884089409040914092409340944095409640974098409941004101410241034104410541064107410841094110411141124113411441154116411741184119412041214122412341244125412641274128412941304131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200420142024203420442054206420742084209421042114212421342144215421642174218421942204221422242234224422542264227422842294230423142324233423442354236423742384239424042414242424342444245424642474248424942504251425242534254425542564257425842594260426142624263426442654266426742684269427042714272427342744275427642774278427942804281428242834284428542864287428842894290429142924293429442954296429742984299430043014302430343044305430643074308430943104311431243134314431543164317431843194320432143224323432443254326432743284329433043314332433343344335433643374338433943404341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410441144124413441444154416441744184419442044214422442344244425442644274428442944304431443244334434443544364437443844394440444144424443444444454446444744484449445044514452445344544455445644574458445944604461446244634464446544664467446844694470447144724473447444754476447744784479448044814482448344844485448644874488448944904491449244934494449544964497449844994500450145024503450445054506450745084509451045114512451345144515451645174518451945204521452245234524452545264527452845294530453145324533453445354536453745384539454045414542454345444545454645474548454945504551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620462146224623462446254626462746284629463046314632463346344635463646374638463946404641464246434644464546464647464846494650465146524653465446554656465746584659466046614662466346644665466646674668466946704671467246734674467546764677467846794680468146824683468446854686468746884689469046914692469346944695469646974698469947004701470247034704470547064707470847094710471147124713471447154716471747184719472047214722472347244725472647274728472947304731473247334734473547364737473847394740474147424743474447454746474747484749475047514752475347544755475647574758475947604761476247634764476547664767
  1. /*
  2. * Copyright (C) 2019 Intel Corporation. All rights reserved.
  3. * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  4. */
  5. #include "aot_runtime.h"
  6. #include "aot_reloc.h"
  7. #include "bh_platform.h"
  8. #include "../common/wasm_runtime_common.h"
  9. #include "../common/wasm_native.h"
  10. #include "../common/wasm_loader_common.h"
  11. #include "../compilation/aot.h"
  12. #if WASM_ENABLE_AOT_VALIDATOR != 0
  13. #include "aot_validator.h"
  14. #endif
  15. #if WASM_ENABLE_DEBUG_AOT != 0
  16. #include "debug/elf_parser.h"
  17. #include "debug/jit_debug.h"
  18. #endif
  19. #if WASM_ENABLE_LINUX_PERF != 0
  20. #include "aot_perf_map.h"
  21. #endif
  22. #define YMM_PLT_PREFIX "__ymm@"
  23. #define XMM_PLT_PREFIX "__xmm@"
  24. #define REAL_PLT_PREFIX "__real@"
  25. static void
  26. set_error_buf(char *error_buf, uint32 error_buf_size, const char *string)
  27. {
  28. if (error_buf != NULL) {
  29. snprintf(error_buf, error_buf_size, "AOT module load failed: %s",
  30. string);
  31. }
  32. }
  33. static void
  34. set_error_buf_v(char *error_buf, uint32 error_buf_size, const char *format, ...)
  35. {
  36. va_list args;
  37. char buf[128];
  38. if (error_buf != NULL) {
  39. va_start(args, format);
  40. vsnprintf(buf, sizeof(buf), format, args);
  41. va_end(args);
  42. snprintf(error_buf, error_buf_size, "AOT module load failed: %s", buf);
  43. }
  44. }
  45. #define exchange_uint8(p_data) (void)0
  46. static void
  47. exchange_uint16(uint8 *p_data)
  48. {
  49. uint8 value = *p_data;
  50. *p_data = *(p_data + 1);
  51. *(p_data + 1) = value;
  52. }
  53. static void
  54. exchange_uint32(uint8 *p_data)
  55. {
  56. uint8 value = *p_data;
  57. *p_data = *(p_data + 3);
  58. *(p_data + 3) = value;
  59. value = *(p_data + 1);
  60. *(p_data + 1) = *(p_data + 2);
  61. *(p_data + 2) = value;
  62. }
  63. static void
  64. exchange_uint64(uint8 *p_data)
  65. {
  66. uint32 value;
  67. value = *(uint32 *)p_data;
  68. *(uint32 *)p_data = *(uint32 *)(p_data + 4);
  69. *(uint32 *)(p_data + 4) = value;
  70. exchange_uint32(p_data);
  71. exchange_uint32(p_data + 4);
  72. }
  73. static union {
  74. int a;
  75. char b;
  76. } __ue = { .a = 1 };
  77. #define is_little_endian() (__ue.b == 1)
  78. static bool
  79. check_buf(const uint8 *buf, const uint8 *buf_end, uint32 length,
  80. char *error_buf, uint32 error_buf_size)
  81. {
  82. if ((uintptr_t)buf + length < (uintptr_t)buf
  83. || (uintptr_t)buf + length > (uintptr_t)buf_end) {
  84. set_error_buf(error_buf, error_buf_size, "unexpected end");
  85. return false;
  86. }
  87. return true;
  88. }
  89. #define CHECK_BUF(buf, buf_end, length) \
  90. do { \
  91. if (!check_buf(buf, buf_end, length, error_buf, error_buf_size)) { \
  92. goto fail; \
  93. } \
  94. } while (0)
  95. static uint8 *
  96. align_ptr(const uint8 *p, uint32 b)
  97. {
  98. uintptr_t v = (uintptr_t)p;
  99. uintptr_t m = b - 1;
  100. return (uint8 *)((v + m) & ~m);
  101. }
  102. static inline uint64
  103. GET_U64_FROM_ADDR(uint32 *addr)
  104. {
  105. union {
  106. uint64 val;
  107. uint32 parts[2];
  108. } u;
  109. u.parts[0] = addr[0];
  110. u.parts[1] = addr[1];
  111. return u.val;
  112. }
  113. #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
  114. static inline uint8
  115. GET_U8_FROM_ADDR(const uint8 *p)
  116. {
  117. uint8 res = 0;
  118. bh_assert(p);
  119. const uint8 *p_aligned = align_ptr(p, 4);
  120. p_aligned = (p_aligned > p) ? p_aligned - 4 : p_aligned;
  121. uint32 buf32 = *(const uint32 *)p_aligned;
  122. const uint8 *pbuf = (const uint8 *)&buf32;
  123. res = *(uint8 *)(pbuf + (p - p_aligned));
  124. return res;
  125. }
  126. static inline uint16
  127. GET_U16_FROM_ADDR(const uint8 *p)
  128. {
  129. uint16 res = 0;
  130. bh_assert(p);
  131. const uint8 *p_aligned = align_ptr(p, 4);
  132. p_aligned = (p_aligned > p) ? p_aligned - 4 : p_aligned;
  133. uint32 buf32 = *(const uint32 *)p_aligned;
  134. const uint8 *pbuf = (const uint8 *)&buf32;
  135. res = *(uint16 *)(pbuf + (p - p_aligned));
  136. return res;
  137. }
  138. #define TEMPLATE_READ(p, p_end, res, type) \
  139. do { \
  140. if (sizeof(type) != sizeof(uint64)) \
  141. p = (uint8 *)align_ptr(p, sizeof(type)); \
  142. else \
  143. /* align 4 bytes if type is uint64 */ \
  144. p = (uint8 *)align_ptr(p, sizeof(uint32)); \
  145. CHECK_BUF(p, p_end, sizeof(type)); \
  146. if (sizeof(type) == sizeof(uint8)) \
  147. res = GET_U8_FROM_ADDR(p); \
  148. else if (sizeof(type) == sizeof(uint16)) \
  149. res = GET_U16_FROM_ADDR(p); \
  150. else if (sizeof(type) == sizeof(uint32)) \
  151. res = *(type *)p; \
  152. else \
  153. res = (type)GET_U64_FROM_ADDR((uint32 *)p); \
  154. if (!is_little_endian()) \
  155. exchange_##type((uint8 *)&res); \
  156. p += sizeof(type); \
  157. } while (0)
  158. #define read_byte_array(p, p_end, addr, len) \
  159. do { \
  160. CHECK_BUF(p, p_end, len); \
  161. bh_memcpy_wa(addr, len, p, len); \
  162. p += len; \
  163. } while (0)
  164. #define read_string(p, p_end, str) \
  165. do { \
  166. if (!(str = load_string((uint8 **)&p, p_end, module, \
  167. is_load_from_file_buf, true, error_buf, \
  168. error_buf_size))) \
  169. goto fail; \
  170. } while (0)
  171. #else /* else of (WASM_ENABLE_WORD_ALIGN_READ != 0) */
  172. #define TEMPLATE_READ(p, p_end, res, type) \
  173. do { \
  174. if (sizeof(type) != sizeof(uint64)) \
  175. p = (uint8 *)align_ptr(p, sizeof(type)); \
  176. else \
  177. /* align 4 bytes if type is uint64 */ \
  178. p = (uint8 *)align_ptr(p, sizeof(uint32)); \
  179. CHECK_BUF(p, p_end, sizeof(type)); \
  180. if (sizeof(type) != sizeof(uint64)) \
  181. res = *(type *)p; \
  182. else \
  183. res = (type)GET_U64_FROM_ADDR((uint32 *)p); \
  184. if (!is_little_endian()) \
  185. exchange_##type((uint8 *)&res); \
  186. p += sizeof(type); \
  187. } while (0)
  188. /* NOLINTBEGIN, disable lint for this region with clang-tidy */
  189. #define read_byte_array(p, p_end, addr, len) \
  190. do { \
  191. CHECK_BUF(p, p_end, len); \
  192. bh_memcpy_s(addr, len, p, len); \
  193. p += len; \
  194. } while (0)
  195. #define read_string(p, p_end, str) \
  196. do { \
  197. if (!(str = load_string((uint8 **)&p, p_end, module, \
  198. is_load_from_file_buf, error_buf, \
  199. error_buf_size))) \
  200. goto fail; \
  201. } while (0)
  202. #endif /* end of (WASM_ENABLE_WORD_ALIGN_READ != 0) */
  203. #define read_uint8(p, p_end, res) TEMPLATE_READ(p, p_end, res, uint8)
  204. #define read_uint16(p, p_end, res) TEMPLATE_READ(p, p_end, res, uint16)
  205. #define read_uint32(p, p_end, res) TEMPLATE_READ(p, p_end, res, uint32)
  206. #define read_uint64(p, p_end, res) TEMPLATE_READ(p, p_end, res, uint64)
  207. /* NOLINTEND */
  208. /* Legal values for bin_type */
  209. #define BIN_TYPE_ELF32L 0 /* 32-bit little endian */
  210. #define BIN_TYPE_ELF32B 1 /* 32-bit big endian */
  211. #define BIN_TYPE_ELF64L 2 /* 64-bit little endian */
  212. #define BIN_TYPE_ELF64B 3 /* 64-bit big endian */
  213. #define BIN_TYPE_COFF32 4 /* 32-bit little endian */
  214. #define BIN_TYPE_COFF64 6 /* 64-bit little endian */
  215. /* Legal values for e_type (object file type). */
  216. #define E_TYPE_NONE 0 /* No file type */
  217. #define E_TYPE_REL 1 /* Relocatable file */
  218. #define E_TYPE_EXEC 2 /* Executable file */
  219. #define E_TYPE_DYN 3 /* Shared object file */
  220. #define E_TYPE_XIP 4 /* eXecute In Place file */
  221. /* Legal values for e_machine (architecture). */
  222. #define E_MACHINE_386 3 /* Intel 80386 */
  223. #define E_MACHINE_MIPS 8 /* MIPS R3000 big-endian */
  224. #define E_MACHINE_MIPS_RS3_LE 10 /* MIPS R3000 little-endian */
  225. #define E_MACHINE_ARM 40 /* ARM/Thumb */
  226. #define E_MACHINE_AARCH64 183 /* AArch64 */
  227. #define E_MACHINE_ARC 45 /* Argonaut RISC Core */
  228. #define E_MACHINE_IA_64 50 /* Intel Merced */
  229. #define E_MACHINE_MIPS_X 51 /* Stanford MIPS-X */
  230. #define E_MACHINE_X86_64 62 /* AMD x86-64 architecture */
  231. #define E_MACHINE_ARC_COMPACT 93 /* ARC International ARCompact */
  232. #define E_MACHINE_ARC_COMPACT2 195 /* Synopsys ARCompact V2 */
  233. #define E_MACHINE_XTENSA 94 /* Tensilica Xtensa Architecture */
  234. #define E_MACHINE_RISCV 243 /* RISC-V 32/64 */
  235. #define E_MACHINE_WIN_I386 0x14c /* Windows i386 architecture */
  236. #define E_MACHINE_WIN_X86_64 0x8664 /* Windows x86-64 architecture */
  237. /* Legal values for e_version */
  238. #define E_VERSION_CURRENT 1 /* Current version */
  239. static void *
  240. loader_malloc(uint64 size, char *error_buf, uint32 error_buf_size)
  241. {
  242. void *mem;
  243. if (size >= UINT32_MAX || !(mem = wasm_runtime_malloc((uint32)size))) {
  244. set_error_buf(error_buf, error_buf_size, "allocate memory failed");
  245. return NULL;
  246. }
  247. memset(mem, 0, (uint32)size);
  248. return mem;
  249. }
  250. static void *
  251. loader_mmap(uint32 size, bool prot_exec, char *error_buf, uint32 error_buf_size)
  252. {
  253. int map_prot =
  254. MMAP_PROT_READ | MMAP_PROT_WRITE | (prot_exec ? MMAP_PROT_EXEC : 0);
  255. int map_flags;
  256. void *mem;
  257. #if defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
  258. || defined(BUILD_TARGET_RISCV64_LP64D) \
  259. || defined(BUILD_TARGET_RISCV64_LP64)
  260. #if !defined(__APPLE__) && !defined(BH_PLATFORM_LINUX_SGX) \
  261. && !defined(BH_PLATFORM_NUTTX)
  262. /* The mmapped AOT data and code in 64-bit targets had better be in
  263. range 0 to 2G, or aot loader may fail to apply some relocations,
  264. e.g., R_X86_64_32/R_X86_64_32S/R_X86_64_PC32/R_RISCV_32.
  265. We try to mmap with MMAP_MAP_32BIT flag first, and if fails, mmap
  266. again without the flag. */
  267. /* sgx_tprotect_rsrv_mem() and sgx_alloc_rsrv_mem() will ignore flags */
  268. map_flags = MMAP_MAP_32BIT;
  269. if ((mem = os_mmap(NULL, size, map_prot, map_flags,
  270. os_get_invalid_handle()))) {
  271. /* Test whether the mmapped memory in the first 2 Gigabytes of the
  272. process address space */
  273. if ((uintptr_t)mem >= INT32_MAX)
  274. LOG_WARNING(
  275. "Warning: loader mmap memory address is not in the first 2 "
  276. "Gigabytes of the process address space.");
  277. return mem;
  278. }
  279. #endif
  280. #endif
  281. map_flags = MMAP_MAP_NONE;
  282. if (!(mem = os_mmap(NULL, size, map_prot, map_flags,
  283. os_get_invalid_handle()))) {
  284. set_error_buf(error_buf, error_buf_size, "allocate memory failed");
  285. return NULL;
  286. }
  287. return mem;
  288. }
  289. static char *
  290. load_string(uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  291. bool is_load_from_file_buf,
  292. #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
  293. bool is_vram_word_align,
  294. #endif
  295. char *error_buf, uint32 error_buf_size)
  296. {
  297. uint8 *p = *p_buf;
  298. const uint8 *p_end = buf_end;
  299. char *str;
  300. uint16 str_len;
  301. read_uint16(p, p_end, str_len);
  302. CHECK_BUF(p, p_end, str_len);
  303. if (str_len == 0) {
  304. str = "";
  305. }
  306. #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
  307. else if (is_vram_word_align) {
  308. if (!(str = aot_const_str_set_insert((uint8 *)p, str_len, module,
  309. is_vram_word_align, error_buf,
  310. error_buf_size))) {
  311. goto fail;
  312. }
  313. }
  314. #endif
  315. else if (is_load_from_file_buf) {
  316. /* The string is always terminated with '\0', use it directly.
  317. * In this case, the file buffer can be referred to after loading.
  318. */
  319. if (p[str_len - 1] != '\0')
  320. goto fail;
  321. str = (char *)p;
  322. }
  323. else {
  324. /* Load from sections, the file buffer cannot be referred to
  325. after loading, we must create another string and insert it
  326. into const string set */
  327. if (p[str_len - 1] != '\0')
  328. goto fail;
  329. if (!(str = aot_const_str_set_insert((uint8 *)p, str_len, module,
  330. #if (WASM_ENABLE_WORD_ALIGN_READ != 0)
  331. is_vram_word_align,
  332. #endif
  333. error_buf, error_buf_size))) {
  334. goto fail;
  335. }
  336. }
  337. p += str_len;
  338. *p_buf = p;
  339. return str;
  340. fail:
  341. return NULL;
  342. }
  343. static bool
  344. get_aot_file_target(AOTTargetInfo *target_info, char *target_buf,
  345. uint32 target_buf_size, char *error_buf,
  346. uint32 error_buf_size)
  347. {
  348. char *machine_type = NULL;
  349. switch (target_info->e_machine) {
  350. case E_MACHINE_X86_64:
  351. case E_MACHINE_WIN_X86_64:
  352. machine_type = "x86_64";
  353. break;
  354. case E_MACHINE_386:
  355. case E_MACHINE_WIN_I386:
  356. machine_type = "i386";
  357. break;
  358. case E_MACHINE_ARM:
  359. case E_MACHINE_AARCH64:
  360. /* TODO: this will make following `strncmp()` ~L392 unnecessary.
  361. * Use const strings here */
  362. machine_type = target_info->arch;
  363. break;
  364. case E_MACHINE_MIPS:
  365. machine_type = "mips";
  366. break;
  367. case E_MACHINE_XTENSA:
  368. machine_type = "xtensa";
  369. break;
  370. case E_MACHINE_RISCV:
  371. machine_type = "riscv";
  372. break;
  373. case E_MACHINE_ARC_COMPACT:
  374. case E_MACHINE_ARC_COMPACT2:
  375. machine_type = "arc";
  376. break;
  377. default:
  378. set_error_buf_v(error_buf, error_buf_size,
  379. "unknown machine type %d", target_info->e_machine);
  380. return false;
  381. }
  382. if (strncmp(target_info->arch, machine_type, strlen(machine_type))) {
  383. set_error_buf_v(
  384. error_buf, error_buf_size,
  385. "machine type (%s) isn't consistent with target type (%s)",
  386. machine_type, target_info->arch);
  387. return false;
  388. }
  389. snprintf(target_buf, target_buf_size, "%s", target_info->arch);
  390. return true;
  391. }
  392. static bool
  393. check_machine_info(AOTTargetInfo *target_info, char *error_buf,
  394. uint32 error_buf_size)
  395. {
  396. char target_expected[32], target_got[32];
  397. get_current_target(target_expected, sizeof(target_expected));
  398. if (!get_aot_file_target(target_info, target_got, sizeof(target_got),
  399. error_buf, error_buf_size))
  400. return false;
  401. if (strncmp(target_expected, target_got, strlen(target_expected))) {
  402. set_error_buf_v(error_buf, error_buf_size,
  403. "invalid target type, expected %s but got %s",
  404. target_expected, target_got);
  405. return false;
  406. }
  407. return true;
  408. }
  409. static bool
  410. check_feature_flags(char *error_buf, uint32 error_buf_size,
  411. uint64 feature_flags)
  412. {
  413. #if WASM_ENABLE_SIMD == 0
  414. if (feature_flags & WASM_FEATURE_SIMD_128BIT) {
  415. set_error_buf(error_buf, error_buf_size,
  416. "SIMD is not enabled in this build");
  417. return false;
  418. }
  419. #endif
  420. #if WASM_ENABLE_BULK_MEMORY == 0
  421. if (feature_flags & WASM_FEATURE_BULK_MEMORY) {
  422. set_error_buf(error_buf, error_buf_size,
  423. "bulk memory is not enabled in this build");
  424. return false;
  425. }
  426. #endif
  427. #if WASM_ENABLE_THREAD_MGR == 0
  428. if (feature_flags & WASM_FEATURE_MULTI_THREAD) {
  429. set_error_buf(error_buf, error_buf_size,
  430. "thread is not enabled in this build");
  431. return false;
  432. }
  433. #endif
  434. #if WASM_ENABLE_REF_TYPES == 0
  435. if (feature_flags & WASM_FEATURE_REF_TYPES) {
  436. set_error_buf(error_buf, error_buf_size,
  437. "reference types is not enabled in this build");
  438. return false;
  439. }
  440. #endif
  441. #if WASM_ENABLE_GC == 0
  442. if (feature_flags & WASM_FEATURE_GARBAGE_COLLECTION) {
  443. set_error_buf(error_buf, error_buf_size,
  444. "garbage collection is not enabled in this build");
  445. return false;
  446. }
  447. #endif
  448. return true;
  449. }
  450. #if WASM_ENABLE_GC != 0
  451. static WASMRefType *
  452. reftype_set_insert(HashMap *ref_type_set, const WASMRefType *ref_type,
  453. char *error_buf, uint32 error_buf_size)
  454. {
  455. WASMRefType *ret = wasm_reftype_set_insert(ref_type_set, ref_type);
  456. if (!ret) {
  457. set_error_buf(error_buf, error_buf_size,
  458. "insert ref type to hash set failed");
  459. }
  460. return ret;
  461. }
  462. #endif
  463. static bool
  464. load_target_info_section(const uint8 *buf, const uint8 *buf_end,
  465. AOTModule *module, char *error_buf,
  466. uint32 error_buf_size)
  467. {
  468. AOTTargetInfo target_info;
  469. const uint8 *p = buf, *p_end = buf_end;
  470. bool is_target_little_endian, is_target_64_bit;
  471. read_uint16(p, p_end, target_info.bin_type);
  472. read_uint16(p, p_end, target_info.abi_type);
  473. read_uint16(p, p_end, target_info.e_type);
  474. read_uint16(p, p_end, target_info.e_machine);
  475. read_uint32(p, p_end, target_info.e_version);
  476. read_uint32(p, p_end, target_info.e_flags);
  477. read_uint64(p, p_end, target_info.feature_flags);
  478. read_uint64(p, p_end, target_info.reserved);
  479. read_byte_array(p, p_end, target_info.arch, sizeof(target_info.arch));
  480. if (target_info.arch[sizeof(target_info.arch) - 1] != '\0') {
  481. set_error_buf(error_buf, error_buf_size, "invalid arch string");
  482. return false;
  483. }
  484. if (p != buf_end) {
  485. set_error_buf(error_buf, error_buf_size, "invalid section size");
  486. return false;
  487. }
  488. /* Check target endian type */
  489. is_target_little_endian = target_info.bin_type & 1 ? false : true;
  490. if (is_little_endian() != is_target_little_endian) {
  491. set_error_buf_v(error_buf, error_buf_size,
  492. "invalid target endian type, expected %s but got %s",
  493. is_little_endian() ? "little endian" : "big endian",
  494. is_target_little_endian ? "little endian"
  495. : "big endian");
  496. return false;
  497. }
  498. /* Check target bit width */
  499. is_target_64_bit = target_info.bin_type & 2 ? true : false;
  500. if ((sizeof(void *) == 8 ? true : false) != is_target_64_bit) {
  501. set_error_buf_v(error_buf, error_buf_size,
  502. "invalid target bit width, expected %s but got %s",
  503. sizeof(void *) == 8 ? "64-bit" : "32-bit",
  504. is_target_64_bit ? "64-bit" : "32-bit");
  505. return false;
  506. }
  507. /* Check target elf file type */
  508. if (target_info.e_type != E_TYPE_REL && target_info.e_type != E_TYPE_XIP) {
  509. set_error_buf(error_buf, error_buf_size,
  510. "invalid object file type, "
  511. "expected relocatable or XIP file type but got others");
  512. return false;
  513. }
  514. /* for backwards compatibility with previous wamrc aot files */
  515. if (!strcmp(target_info.arch, "arm64")
  516. || !strcmp(target_info.arch, "aarch64"))
  517. bh_strcpy_s(target_info.arch, sizeof(target_info.arch), "aarch64v8");
  518. /* Check machine info */
  519. if (!check_machine_info(&target_info, error_buf, error_buf_size)) {
  520. return false;
  521. }
  522. if (target_info.e_version != E_VERSION_CURRENT) {
  523. set_error_buf(error_buf, error_buf_size, "invalid elf file version");
  524. return false;
  525. }
  526. #if WASM_ENABLE_DUMP_CALL_STACK != 0
  527. module->feature_flags = target_info.feature_flags;
  528. #endif
  529. /* Finally, check feature flags */
  530. return check_feature_flags(error_buf, error_buf_size,
  531. target_info.feature_flags);
  532. fail:
  533. return false;
  534. }
  535. static void *
  536. get_native_symbol_by_name(const char *name)
  537. {
  538. void *func = NULL;
  539. uint32 symnum = 0;
  540. SymbolMap *sym = NULL;
  541. sym = get_target_symbol_map(&symnum);
  542. while (symnum && symnum--) {
  543. if (strcmp(sym->symbol_name, name) == 0) {
  544. func = sym->symbol_addr;
  545. break;
  546. }
  547. sym++;
  548. }
  549. return func;
  550. }
  551. static bool
  552. str2uint32(const char *buf, uint32 *p_res);
  553. static bool
  554. str2uint64(const char *buf, uint64 *p_res);
  555. static bool
  556. load_native_symbol_section(const uint8 *buf, const uint8 *buf_end,
  557. AOTModule *module, bool is_load_from_file_buf,
  558. char *error_buf, uint32 error_buf_size)
  559. {
  560. const uint8 *p = buf, *p_end = buf_end;
  561. uint32 cnt;
  562. int32 i;
  563. const char *symbol;
  564. if (module->native_symbol_list) {
  565. set_error_buf(error_buf, error_buf_size,
  566. "duplicated native symbol section");
  567. return false;
  568. }
  569. read_uint32(p, p_end, cnt);
  570. if (cnt > 0) {
  571. uint64 list_size = cnt * (uint64)sizeof(void *);
  572. module->native_symbol_list =
  573. loader_malloc(list_size, error_buf, error_buf_size);
  574. if (module->native_symbol_list == NULL) {
  575. goto fail;
  576. }
  577. for (i = cnt - 1; i >= 0; i--) {
  578. read_string(p, p_end, symbol);
  579. if (!strlen(symbol))
  580. continue;
  581. if (!strncmp(symbol, "f32#", 4) || !strncmp(symbol, "i32#", 4)) {
  582. uint32 u32;
  583. /* Resolve the raw int bits of f32 const */
  584. if (!str2uint32(symbol + 4, &u32)) {
  585. set_error_buf_v(error_buf, error_buf_size,
  586. "resolve symbol %s failed", symbol);
  587. goto fail;
  588. }
  589. *(uint32 *)(&module->native_symbol_list[i]) = u32;
  590. }
  591. else if (!strncmp(symbol, "f64#", 4)
  592. || !strncmp(symbol, "i64#", 4)) {
  593. uint64 u64;
  594. /* Resolve the raw int bits of f64 const */
  595. if (!str2uint64(symbol + 4, &u64)) {
  596. set_error_buf_v(error_buf, error_buf_size,
  597. "resolve symbol %s failed", symbol);
  598. goto fail;
  599. }
  600. *(uint64 *)(&module->native_symbol_list[i]) = u64;
  601. }
  602. else if (!strncmp(symbol, "__ignore", 8)) {
  603. /* Padding bytes to make f64 on 8-byte aligned address,
  604. or it is the second 32-bit slot in 32-bit system */
  605. continue;
  606. }
  607. else {
  608. module->native_symbol_list[i] =
  609. get_native_symbol_by_name(symbol);
  610. if (module->native_symbol_list[i] == NULL) {
  611. set_error_buf_v(error_buf, error_buf_size,
  612. "missing native symbol: %s", symbol);
  613. goto fail;
  614. }
  615. }
  616. }
  617. }
  618. return true;
  619. fail:
  620. return false;
  621. }
  622. static bool
  623. load_name_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
  624. bool is_load_from_file_buf, char *error_buf,
  625. uint32 error_buf_size)
  626. {
  627. #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
  628. const uint8 *p = buf, *p_end = buf_end;
  629. uint32 *aux_func_indexes;
  630. const char **aux_func_names;
  631. uint32 name_type, subsection_size;
  632. uint32 previous_name_type = 0;
  633. uint32 num_func_name;
  634. uint32 func_index;
  635. uint32 previous_func_index = ~0U;
  636. uint32 name_index;
  637. int i = 0;
  638. uint32 name_len;
  639. uint64 size;
  640. if (p >= p_end) {
  641. set_error_buf(error_buf, error_buf_size, "unexpected end");
  642. return false;
  643. }
  644. read_uint32(p, p_end, name_len);
  645. if (name_len != 4 || p + name_len > p_end) {
  646. set_error_buf(error_buf, error_buf_size, "unexpected end");
  647. return false;
  648. }
  649. if (memcmp(p, "name", 4) != 0) {
  650. set_error_buf(error_buf, error_buf_size, "invalid custom name section");
  651. return false;
  652. }
  653. p += name_len;
  654. while (p < p_end) {
  655. read_uint32(p, p_end, name_type);
  656. if (i != 0) {
  657. if (name_type == previous_name_type) {
  658. set_error_buf(error_buf, error_buf_size,
  659. "duplicate sub-section");
  660. return false;
  661. }
  662. if (name_type < previous_name_type) {
  663. set_error_buf(error_buf, error_buf_size,
  664. "out-of-order sub-section");
  665. return false;
  666. }
  667. }
  668. previous_name_type = name_type;
  669. read_uint32(p, p_end, subsection_size);
  670. CHECK_BUF(p, p_end, subsection_size);
  671. switch (name_type) {
  672. case SUB_SECTION_TYPE_FUNC:
  673. if (subsection_size) {
  674. read_uint32(p, p_end, num_func_name);
  675. if (num_func_name
  676. > module->import_func_count + module->func_count) {
  677. set_error_buf(error_buf, error_buf_size,
  678. "function name count out of bounds");
  679. return false;
  680. }
  681. module->aux_func_name_count = num_func_name;
  682. /* Allocate memory */
  683. size = sizeof(uint32) * (uint64)module->aux_func_name_count;
  684. if (!(aux_func_indexes = module->aux_func_indexes =
  685. loader_malloc(size, error_buf, error_buf_size))) {
  686. return false;
  687. }
  688. size =
  689. sizeof(char **) * (uint64)module->aux_func_name_count;
  690. if (!(aux_func_names = module->aux_func_names =
  691. loader_malloc(size, error_buf, error_buf_size))) {
  692. return false;
  693. }
  694. for (name_index = 0; name_index < num_func_name;
  695. name_index++) {
  696. read_uint32(p, p_end, func_index);
  697. if (name_index != 0
  698. && func_index == previous_func_index) {
  699. set_error_buf(error_buf, error_buf_size,
  700. "duplicate function name");
  701. return false;
  702. }
  703. if (name_index != 0
  704. && func_index < previous_func_index) {
  705. set_error_buf(error_buf, error_buf_size,
  706. "out-of-order function index ");
  707. return false;
  708. }
  709. if (func_index
  710. >= module->import_func_count + module->func_count) {
  711. set_error_buf(error_buf, error_buf_size,
  712. "function index out of bounds");
  713. return false;
  714. }
  715. previous_func_index = func_index;
  716. *(aux_func_indexes + name_index) = func_index;
  717. read_string(p, p_end, *(aux_func_names + name_index));
  718. #if 0
  719. LOG_DEBUG("func_index %u -> aux_func_name = %s\n",
  720. func_index, *(aux_func_names + name_index));
  721. #endif
  722. }
  723. }
  724. break;
  725. case SUB_SECTION_TYPE_MODULE: /* TODO: Parse for module subsection
  726. */
  727. case SUB_SECTION_TYPE_LOCAL: /* TODO: Parse for local subsection */
  728. default:
  729. p = p + subsection_size;
  730. break;
  731. }
  732. i++;
  733. }
  734. return true;
  735. fail:
  736. return false;
  737. #else
  738. return true;
  739. #endif /* WASM_ENABLE_CUSTOM_NAME_SECTION != 0 */
  740. }
  741. #if WASM_ENABLE_STRINGREF != 0
  742. static bool
  743. load_string_literal_section(const uint8 *buf, const uint8 *buf_end,
  744. AOTModule *module, bool is_load_from_file_buf,
  745. char *error_buf, uint32 error_buf_size)
  746. {
  747. const uint8 *p = buf, *p_end = buf_end;
  748. uint32 reserved = 0, string_count = 0, i;
  749. uint64 size;
  750. read_uint32(p, p_end, reserved);
  751. if (reserved != 0) {
  752. set_error_buf(error_buf, error_buf_size,
  753. "invalid reserved slot in string literal count");
  754. goto fail;
  755. }
  756. read_uint32(p, p_end, string_count);
  757. if (string_count == 0) {
  758. set_error_buf(error_buf, error_buf_size,
  759. "invalid string literal count");
  760. goto fail;
  761. }
  762. module->string_literal_count = string_count;
  763. size = (uint64)sizeof(char *) * string_count;
  764. if (!(module->string_literal_ptrs =
  765. loader_malloc(size, error_buf, error_buf_size))) {
  766. goto fail;
  767. }
  768. size = (uint64)sizeof(uint32) * string_count;
  769. if (!(module->string_literal_lengths =
  770. loader_malloc(size, error_buf, error_buf_size))) {
  771. goto fail;
  772. }
  773. for (i = 0; i < string_count; i++) {
  774. read_uint32(p, p_end, module->string_literal_lengths[i]);
  775. }
  776. for (i = 0; i < string_count; i++) {
  777. module->string_literal_ptrs[i] = p;
  778. p += module->string_literal_lengths[i];
  779. }
  780. return true;
  781. fail:
  782. return false;
  783. }
  784. #endif /* end of WASM_ENABLE_STRINGREF != 0 */
  785. static bool
  786. load_custom_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
  787. bool is_load_from_file_buf, char *error_buf,
  788. uint32 error_buf_size)
  789. {
  790. const uint8 *p = buf, *p_end = buf_end;
  791. uint32 sub_section_type;
  792. read_uint32(p, p_end, sub_section_type);
  793. buf = p;
  794. switch (sub_section_type) {
  795. case AOT_CUSTOM_SECTION_NATIVE_SYMBOL:
  796. if (!load_native_symbol_section(buf, buf_end, module,
  797. is_load_from_file_buf, error_buf,
  798. error_buf_size))
  799. goto fail;
  800. break;
  801. case AOT_CUSTOM_SECTION_NAME:
  802. if (!load_name_section(buf, buf_end, module, is_load_from_file_buf,
  803. error_buf, error_buf_size))
  804. LOG_VERBOSE("Load name section failed.");
  805. else
  806. LOG_VERBOSE("Load name section success.");
  807. break;
  808. #if WASM_ENABLE_STRINGREF != 0
  809. case AOT_CUSTOM_SECTION_STRING_LITERAL:
  810. if (!load_string_literal_section(buf, buf_end, module,
  811. is_load_from_file_buf, error_buf,
  812. error_buf_size))
  813. goto fail;
  814. break;
  815. #endif
  816. #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
  817. case AOT_CUSTOM_SECTION_RAW:
  818. {
  819. const char *section_name;
  820. WASMCustomSection *section;
  821. if (p >= p_end) {
  822. set_error_buf(error_buf, error_buf_size, "unexpected end");
  823. goto fail;
  824. }
  825. read_string(p, p_end, section_name);
  826. section = loader_malloc(sizeof(WASMCustomSection), error_buf,
  827. error_buf_size);
  828. if (!section) {
  829. goto fail;
  830. }
  831. section->name_addr = (char *)section_name;
  832. section->name_len = (uint32)strlen(section_name);
  833. section->content_addr = (uint8 *)p;
  834. section->content_len = (uint32)(p_end - p);
  835. section->next = module->custom_section_list;
  836. module->custom_section_list = section;
  837. LOG_VERBOSE("Load custom section [%s] success.", section_name);
  838. break;
  839. }
  840. #endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION != 0 */
  841. default:
  842. break;
  843. }
  844. return true;
  845. fail:
  846. return false;
  847. }
  848. #if WASM_ENABLE_GC != 0 || WASM_ENABLE_EXTENDED_CONST_EXPR != 0
  849. static void
  850. destroy_init_expr(InitializerExpression *expr)
  851. {
  852. #if WASM_ENABLE_GC != 0
  853. if (expr->init_expr_type == INIT_EXPR_TYPE_STRUCT_NEW
  854. || expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW
  855. || expr->init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) {
  856. wasm_runtime_free(expr->u.unary.v.data);
  857. }
  858. #endif
  859. #if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
  860. // free left expr and right expr for binary oprand
  861. if (!is_expr_binary_op(expr->init_expr_type)) {
  862. return;
  863. }
  864. if (expr->u.binary.l_expr) {
  865. destroy_init_expr_recursive(expr->u.binary.l_expr);
  866. }
  867. if (expr->u.binary.r_expr) {
  868. destroy_init_expr_recursive(expr->u.binary.r_expr);
  869. }
  870. expr->u.binary.l_expr = expr->u.binary.r_expr = NULL;
  871. #endif
  872. }
  873. #endif /* end of WASM_ENABLE_GC != 0 || WASM_ENABLE_EXTENDED_CONST_EXPR != 0 \
  874. */
  875. static void
  876. destroy_import_memories(AOTImportMemory *import_memories)
  877. {
  878. wasm_runtime_free(import_memories);
  879. }
  880. /**
  881. * Free memory initialization data segments.
  882. *
  883. * @param module the AOT module containing the data
  884. * @param data_list array of memory initialization data segments to free
  885. * @param count number of segments in the data_list array
  886. */
  887. static void
  888. destroy_mem_init_data_list(AOTModule *module, AOTMemInitData **data_list,
  889. uint32 count)
  890. {
  891. uint32 i;
  892. /* Free each memory initialization data segment */
  893. for (i = 0; i < count; i++)
  894. if (data_list[i]) {
  895. /* If the module owns the binary data, free the bytes buffer */
  896. if (module->is_binary_freeable && data_list[i]->bytes)
  897. wasm_runtime_free(data_list[i]->bytes);
  898. #if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
  899. destroy_init_expr(&data_list[i]->offset);
  900. #endif
  901. /* Free the data segment structure itself */
  902. wasm_runtime_free(data_list[i]);
  903. }
  904. /* Free the array of data segment pointers */
  905. wasm_runtime_free(data_list);
  906. }
  907. static bool
  908. load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  909. InitializerExpression *expr, char *error_buf,
  910. uint32 error_buf_size);
  911. /**
  912. * Load memory initialization data segments from the AOT module.
  913. *
  914. * This function reads memory initialization data segments from the buffer and
  915. * creates AOTMemInitData structures for each segment. The data can either be
  916. * cloned into new memory or referenced directly from the buffer.
  917. *
  918. * @param p_buf pointer to buffer containing memory init data
  919. * @param buf_end end of buffer
  920. * @param module the AOT module being loaded
  921. * @param error_buf buffer for error messages
  922. * @param error_buf_size size of error buffer
  923. *
  924. * @return true if successful, false if error occurred
  925. */
  926. static bool
  927. load_mem_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
  928. AOTModule *module, char *error_buf,
  929. uint32 error_buf_size)
  930. {
  931. const uint8 *buf = *p_buf;
  932. AOTMemInitData **data_list;
  933. uint64 size;
  934. uint32 i;
  935. /* Allocate memory */
  936. size = sizeof(AOTMemInitData *) * (uint64)module->mem_init_data_count;
  937. if (!(module->mem_init_data_list = data_list =
  938. loader_malloc(size, error_buf, error_buf_size))) {
  939. return false;
  940. }
  941. /* Create each memory data segment */
  942. for (i = 0; i < module->mem_init_data_count; i++) {
  943. uint32 byte_count;
  944. uint32 is_passive;
  945. uint32 memory_index;
  946. InitializerExpression offset_expr;
  947. read_uint32(buf, buf_end, is_passive);
  948. read_uint32(buf, buf_end, memory_index);
  949. if (!load_init_expr(&buf, buf_end, module, &offset_expr, error_buf,
  950. error_buf_size)) {
  951. return false;
  952. }
  953. read_uint32(buf, buf_end, byte_count);
  954. if (!(data_list[i] = loader_malloc(sizeof(AOTMemInitData), error_buf,
  955. error_buf_size))) {
  956. return false;
  957. }
  958. #if WASM_ENABLE_BULK_MEMORY != 0
  959. /* is_passive and memory_index is only used in bulk memory mode */
  960. data_list[i]->is_passive = (bool)is_passive;
  961. data_list[i]->memory_index = memory_index;
  962. #endif
  963. data_list[i]->offset = offset_expr;
  964. data_list[i]->byte_count = byte_count;
  965. data_list[i]->bytes = NULL;
  966. /* If the module owns the binary data, clone the bytes buffer */
  967. if (module->is_binary_freeable) {
  968. if (byte_count > 0) {
  969. if (!(data_list[i]->bytes = loader_malloc(byte_count, error_buf,
  970. error_buf_size))) {
  971. return false;
  972. }
  973. read_byte_array(buf, buf_end, data_list[i]->bytes,
  974. data_list[i]->byte_count);
  975. }
  976. }
  977. else {
  978. data_list[i]->bytes = (uint8 *)buf;
  979. buf += byte_count;
  980. }
  981. }
  982. *p_buf = buf;
  983. return true;
  984. fail:
  985. return false;
  986. }
  987. /**
  988. * Load memory information from the AOT module.
  989. *
  990. * This function reads memory-related data including import memory count,
  991. * memory count, memory flags, page sizes, and memory initialization data.
  992. *
  993. * @param p_buf pointer to buffer containing memory info
  994. * @param buf_end end of buffer
  995. * @param module the AOT module being loaded
  996. * @param error_buf buffer for error messages
  997. * @param error_buf_size size of error buffer
  998. *
  999. * @return true if successful, false if error occurred
  1000. */
  1001. static bool
  1002. load_memory_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  1003. char *error_buf, uint32 error_buf_size)
  1004. {
  1005. uint32 i;
  1006. uint64 total_size;
  1007. const uint8 *buf = *p_buf;
  1008. read_uint32(buf, buf_end, module->import_memory_count);
  1009. read_uint32(buf, buf_end, module->memory_count);
  1010. total_size = sizeof(AOTMemory) * (uint64)module->memory_count;
  1011. if (!(module->memories =
  1012. loader_malloc(total_size, error_buf, error_buf_size))) {
  1013. return false;
  1014. }
  1015. for (i = 0; i < module->memory_count; i++) {
  1016. read_uint32(buf, buf_end, module->memories[i].flags);
  1017. if (!wasm_memory_check_flags(module->memories[i].flags, error_buf,
  1018. error_buf_size, true)) {
  1019. return false;
  1020. }
  1021. read_uint32(buf, buf_end, module->memories[i].num_bytes_per_page);
  1022. read_uint32(buf, buf_end, module->memories[i].init_page_count);
  1023. read_uint32(buf, buf_end, module->memories[i].max_page_count);
  1024. }
  1025. read_uint32(buf, buf_end, module->mem_init_data_count);
  1026. /* load memory init data list */
  1027. if (module->mem_init_data_count > 0
  1028. && !load_mem_init_data_list(&buf, buf_end, module, error_buf,
  1029. error_buf_size))
  1030. return false;
  1031. *p_buf = buf;
  1032. return true;
  1033. fail:
  1034. return false;
  1035. }
  1036. static void
  1037. destroy_import_tables(AOTImportTable *import_tables)
  1038. {
  1039. wasm_runtime_free(import_tables);
  1040. }
  1041. static void
  1042. destroy_tables(AOTTable *tables)
  1043. {
  1044. wasm_runtime_free(tables);
  1045. }
  1046. static void
  1047. destroy_table_init_data_list(AOTTableInitData **data_list, uint32 count)
  1048. {
  1049. uint32 i;
  1050. for (i = 0; i < count; i++)
  1051. if (data_list[i]) {
  1052. #if WASM_ENABLE_GC != 0
  1053. uint32 j;
  1054. for (j = 0; j < data_list[i]->value_count; j++) {
  1055. destroy_init_expr(&data_list[i]->init_values[j]);
  1056. }
  1057. #endif
  1058. #if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
  1059. destroy_init_expr(&data_list[i]->offset);
  1060. #endif
  1061. wasm_runtime_free(data_list[i]);
  1062. }
  1063. wasm_runtime_free(data_list);
  1064. }
  1065. static bool
  1066. load_init_expr(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  1067. InitializerExpression *expr, char *error_buf,
  1068. uint32 error_buf_size)
  1069. {
  1070. const uint8 *buf = *p_buf;
  1071. uint32 init_expr_type = 0;
  1072. uint64 *i64x2 = NULL;
  1073. bool free_if_fail = false;
  1074. buf = (uint8 *)align_ptr(buf, 4);
  1075. read_uint32(buf, buf_end, init_expr_type);
  1076. switch (init_expr_type) {
  1077. case INIT_EXPR_NONE:
  1078. break;
  1079. case INIT_EXPR_TYPE_I32_CONST:
  1080. case INIT_EXPR_TYPE_F32_CONST:
  1081. read_uint32(buf, buf_end, expr->u.unary.v.i32);
  1082. break;
  1083. case INIT_EXPR_TYPE_I64_CONST:
  1084. case INIT_EXPR_TYPE_F64_CONST:
  1085. read_uint64(buf, buf_end, expr->u.unary.v.i64);
  1086. break;
  1087. case INIT_EXPR_TYPE_V128_CONST:
  1088. i64x2 = (uint64 *)expr->u.unary.v.v128.i64x2;
  1089. CHECK_BUF(buf, buf_end, sizeof(uint64) * 2);
  1090. wasm_runtime_read_v128(buf, &i64x2[0], &i64x2[1]);
  1091. buf += sizeof(uint64) * 2;
  1092. break;
  1093. case INIT_EXPR_TYPE_GET_GLOBAL:
  1094. read_uint32(buf, buf_end, expr->u.unary.v.global_index);
  1095. break;
  1096. /* INIT_EXPR_TYPE_FUNCREF_CONST can be used when
  1097. both reference types and GC are disabled */
  1098. case INIT_EXPR_TYPE_FUNCREF_CONST:
  1099. read_uint32(buf, buf_end, expr->u.unary.v.ref_index);
  1100. break;
  1101. #if WASM_ENABLE_GC != 0 || WASM_ENABLE_REF_TYPES != 0
  1102. case INIT_EXPR_TYPE_REFNULL_CONST:
  1103. read_uint32(buf, buf_end, expr->u.unary.v.ref_index);
  1104. break;
  1105. #endif /* end of WASM_ENABLE_GC != 0 || WASM_ENABLE_REF_TYPES != 0 */
  1106. #if WASM_ENABLE_GC != 0
  1107. case INIT_EXPR_TYPE_I31_NEW:
  1108. read_uint32(buf, buf_end, expr->u.unary.v.i32);
  1109. break;
  1110. case INIT_EXPR_TYPE_STRUCT_NEW:
  1111. {
  1112. uint64 size;
  1113. uint32 type_idx, field_count;
  1114. AOTStructType *struct_type = NULL;
  1115. WASMStructNewInitValues *init_values = NULL;
  1116. read_uint32(buf, buf_end, type_idx);
  1117. read_uint32(buf, buf_end, field_count);
  1118. size = offsetof(WASMStructNewInitValues, fields)
  1119. + sizeof(WASMValue) * (uint64)field_count;
  1120. if (!(init_values =
  1121. loader_malloc(size, error_buf, error_buf_size))) {
  1122. return false;
  1123. }
  1124. free_if_fail = true;
  1125. init_values->count = field_count;
  1126. init_values->type_idx = type_idx;
  1127. expr->u.unary.v.data = init_values;
  1128. if (type_idx >= module->type_count) {
  1129. set_error_buf(error_buf, error_buf_size,
  1130. "unknown struct type.");
  1131. goto fail;
  1132. }
  1133. struct_type = (AOTStructType *)module->types[type_idx];
  1134. if (struct_type->field_count != field_count) {
  1135. set_error_buf(error_buf, error_buf_size,
  1136. "invalid field count.");
  1137. goto fail;
  1138. }
  1139. if (field_count > 0) {
  1140. uint32 i;
  1141. for (i = 0; i < field_count; i++) {
  1142. uint32 field_size =
  1143. wasm_value_type_size(struct_type->fields[i].field_type);
  1144. if (field_size <= sizeof(uint32))
  1145. read_uint32(buf, buf_end, init_values->fields[i].u32);
  1146. else if (field_size == sizeof(uint64))
  1147. read_uint64(buf, buf_end, init_values->fields[i].u64);
  1148. else if (field_size == sizeof(uint64) * 2)
  1149. read_byte_array(buf, buf_end, &init_values->fields[i],
  1150. field_size);
  1151. else {
  1152. bh_assert(0);
  1153. }
  1154. }
  1155. }
  1156. break;
  1157. }
  1158. case INIT_EXPR_TYPE_STRUCT_NEW_DEFAULT:
  1159. read_uint32(buf, buf_end, expr->u.unary.v.type_index);
  1160. break;
  1161. case INIT_EXPR_TYPE_ARRAY_NEW:
  1162. case INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT:
  1163. case INIT_EXPR_TYPE_ARRAY_NEW_FIXED:
  1164. {
  1165. uint32 array_elem_type;
  1166. uint32 type_idx, length;
  1167. WASMArrayNewInitValues *init_values = NULL;
  1168. /* Note: at this time the aot types haven't been loaded */
  1169. read_uint32(buf, buf_end, array_elem_type);
  1170. read_uint32(buf, buf_end, type_idx);
  1171. read_uint32(buf, buf_end, length);
  1172. if (type_idx >= module->type_count
  1173. || !wasm_type_is_array_type(module->types[type_idx])) {
  1174. set_error_buf(error_buf, error_buf_size,
  1175. "invalid or non-array type index.");
  1176. goto fail;
  1177. }
  1178. if (init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_DEFAULT) {
  1179. expr->u.unary.v.array_new_default.type_index = type_idx;
  1180. expr->u.unary.v.array_new_default.length = length;
  1181. }
  1182. else {
  1183. uint32 i, elem_size, elem_data_count;
  1184. uint64 size = offsetof(WASMArrayNewInitValues, elem_data)
  1185. + sizeof(WASMValue) * (uint64)length;
  1186. if (!(init_values =
  1187. loader_malloc(size, error_buf, error_buf_size))) {
  1188. return false;
  1189. }
  1190. free_if_fail = true;
  1191. expr->u.unary.v.data = init_values;
  1192. init_values->type_idx = type_idx;
  1193. init_values->length = length;
  1194. elem_data_count =
  1195. (init_expr_type == INIT_EXPR_TYPE_ARRAY_NEW_FIXED) ? length
  1196. : 1;
  1197. elem_size = wasm_value_type_size((uint8)array_elem_type);
  1198. for (i = 0; i < elem_data_count; i++) {
  1199. if (elem_size <= sizeof(uint32))
  1200. read_uint32(buf, buf_end,
  1201. init_values->elem_data[i].u32);
  1202. else if (elem_size == sizeof(uint64))
  1203. read_uint64(buf, buf_end,
  1204. init_values->elem_data[i].u64);
  1205. else if (elem_size == sizeof(uint64) * 2)
  1206. read_byte_array(buf, buf_end,
  1207. &init_values->elem_data[i], elem_size);
  1208. else {
  1209. bh_assert(0);
  1210. }
  1211. }
  1212. }
  1213. break;
  1214. }
  1215. #endif /* end of WASM_ENABLE_GC != 0 */
  1216. #if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
  1217. case INIT_EXPR_TYPE_I32_ADD:
  1218. case INIT_EXPR_TYPE_I32_SUB:
  1219. case INIT_EXPR_TYPE_I32_MUL:
  1220. case INIT_EXPR_TYPE_I64_ADD:
  1221. case INIT_EXPR_TYPE_I64_SUB:
  1222. case INIT_EXPR_TYPE_I64_MUL:
  1223. {
  1224. expr->u.binary.l_expr = expr->u.binary.r_expr = NULL;
  1225. if (!(expr->u.binary.l_expr =
  1226. loader_malloc(sizeof(InitializerExpression), error_buf,
  1227. error_buf_size))) {
  1228. goto fail;
  1229. }
  1230. if (!load_init_expr(&buf, buf_end, module, expr->u.binary.l_expr,
  1231. error_buf, error_buf_size))
  1232. goto fail;
  1233. if (!(expr->u.binary.r_expr =
  1234. loader_malloc(sizeof(InitializerExpression), error_buf,
  1235. error_buf_size))) {
  1236. goto fail;
  1237. }
  1238. if (!load_init_expr(&buf, buf_end, module, expr->u.binary.r_expr,
  1239. error_buf, error_buf_size))
  1240. goto fail;
  1241. break;
  1242. }
  1243. #endif /* end of WASM_ENABLE_EXTENDED_CONST_EXPR != 0 */
  1244. default:
  1245. set_error_buf(error_buf, error_buf_size, "invalid init expr type.");
  1246. return false;
  1247. }
  1248. expr->init_expr_type = (uint8)init_expr_type;
  1249. *p_buf = buf;
  1250. return true;
  1251. fail:
  1252. #if WASM_ENABLE_GC != 0
  1253. if (free_if_fail) {
  1254. wasm_runtime_free(expr->u.unary.v.data);
  1255. }
  1256. #else
  1257. (void)free_if_fail;
  1258. #endif
  1259. #if WASM_ENABLE_EXTENDED_CONST_EXPR != 0
  1260. destroy_init_expr(expr);
  1261. #endif
  1262. return false;
  1263. }
  1264. static bool
  1265. load_import_table_list(const uint8 **p_buf, const uint8 *buf_end,
  1266. AOTModule *module, char *error_buf,
  1267. uint32 error_buf_size)
  1268. {
  1269. const uint8 *buf = *p_buf;
  1270. AOTImportTable *import_table;
  1271. #if WASM_ENABLE_GC != 0
  1272. WASMRefType ref_type;
  1273. #endif
  1274. uint64 size;
  1275. uint32 i;
  1276. /* Allocate memory */
  1277. size = sizeof(AOTImportTable) * (uint64)module->import_table_count;
  1278. if (!(module->import_tables = import_table =
  1279. loader_malloc(size, error_buf, error_buf_size))) {
  1280. return false;
  1281. }
  1282. /* keep sync with aot_emit_table_info() aot_emit_aot_file */
  1283. for (i = 0; i < module->import_table_count; i++, import_table++) {
  1284. read_uint8(buf, buf_end, import_table->table_type.elem_type);
  1285. read_uint8(buf, buf_end, import_table->table_type.flags);
  1286. read_uint8(buf, buf_end, import_table->table_type.possible_grow);
  1287. #if WASM_ENABLE_GC != 0
  1288. if (wasm_is_type_multi_byte_type(import_table->table_type.elem_type)) {
  1289. read_uint8(buf, buf_end, ref_type.ref_ht_common.nullable);
  1290. }
  1291. else
  1292. #endif
  1293. {
  1294. /* Skip 1 byte */
  1295. buf += 1;
  1296. }
  1297. read_uint32(buf, buf_end, import_table->table_type.init_size);
  1298. read_uint32(buf, buf_end, import_table->table_type.max_size);
  1299. #if WASM_ENABLE_GC != 0
  1300. if (wasm_is_type_multi_byte_type(import_table->table_type.elem_type)) {
  1301. read_uint32(buf, buf_end, ref_type.ref_ht_common.heap_type);
  1302. ref_type.ref_type = import_table->table_type.elem_type;
  1303. /* TODO: check ref_type */
  1304. if (!(import_table->table_type.elem_ref_type =
  1305. wasm_reftype_set_insert(module->ref_type_set,
  1306. &ref_type))) {
  1307. set_error_buf(error_buf, error_buf_size,
  1308. "insert ref type to hash set failed");
  1309. return false;
  1310. }
  1311. }
  1312. #endif
  1313. }
  1314. *p_buf = buf;
  1315. return true;
  1316. fail:
  1317. return false;
  1318. }
  1319. static bool
  1320. load_table_list(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  1321. char *error_buf, uint32 error_buf_size)
  1322. {
  1323. const uint8 *buf = *p_buf;
  1324. AOTTable *table;
  1325. #if WASM_ENABLE_GC != 0
  1326. WASMRefType ref_type;
  1327. #endif
  1328. uint64 size;
  1329. uint32 i;
  1330. /* Allocate memory */
  1331. size = sizeof(AOTTable) * (uint64)module->table_count;
  1332. if (!(module->tables = table =
  1333. loader_malloc(size, error_buf, error_buf_size))) {
  1334. return false;
  1335. }
  1336. /* Create each table data segment */
  1337. for (i = 0; i < module->table_count; i++, table++) {
  1338. read_uint8(buf, buf_end, table->table_type.elem_type);
  1339. read_uint8(buf, buf_end, table->table_type.flags);
  1340. if (!wasm_table_check_flags(table->table_type.flags, error_buf,
  1341. error_buf_size, true)) {
  1342. return false;
  1343. }
  1344. read_uint8(buf, buf_end, table->table_type.possible_grow);
  1345. #if WASM_ENABLE_GC != 0
  1346. if (wasm_is_type_multi_byte_type(table->table_type.elem_type)) {
  1347. read_uint8(buf, buf_end, ref_type.ref_ht_common.nullable);
  1348. }
  1349. else
  1350. #endif
  1351. {
  1352. /* Skip 1 byte */
  1353. buf += 1;
  1354. }
  1355. read_uint32(buf, buf_end, table->table_type.init_size);
  1356. read_uint32(buf, buf_end, table->table_type.max_size);
  1357. #if WASM_ENABLE_GC != 0
  1358. if (wasm_is_type_multi_byte_type(table->table_type.elem_type)) {
  1359. read_uint32(buf, buf_end, ref_type.ref_ht_common.heap_type);
  1360. ref_type.ref_type = table->table_type.elem_type;
  1361. /* TODO: check ref_type */
  1362. if (!(table->table_type.elem_ref_type = wasm_reftype_set_insert(
  1363. module->ref_type_set, &ref_type))) {
  1364. set_error_buf(error_buf, error_buf_size,
  1365. "insert ref type to hash set failed");
  1366. return false;
  1367. }
  1368. }
  1369. if (!load_init_expr(&buf, buf_end, module, &table->init_expr, error_buf,
  1370. error_buf_size))
  1371. return false;
  1372. if (table->init_expr.init_expr_type >= INIT_EXPR_TYPE_STRUCT_NEW
  1373. && table->init_expr.init_expr_type
  1374. <= INIT_EXPR_TYPE_EXTERN_CONVERT_ANY) {
  1375. set_error_buf(error_buf, error_buf_size,
  1376. "unsupported initializer expression for table");
  1377. return false;
  1378. }
  1379. #endif
  1380. }
  1381. *p_buf = buf;
  1382. return true;
  1383. fail:
  1384. return false;
  1385. }
  1386. static bool
  1387. load_table_init_data_list(const uint8 **p_buf, const uint8 *buf_end,
  1388. AOTModule *module, char *error_buf,
  1389. uint32 error_buf_size)
  1390. {
  1391. const uint8 *buf = *p_buf;
  1392. AOTTableInitData **data_list;
  1393. #if WASM_ENABLE_GC != 0
  1394. WASMRefType reftype;
  1395. #endif
  1396. uint64 size;
  1397. uint32 i, j;
  1398. /* Allocate memory */
  1399. size = sizeof(AOTTableInitData *) * (uint64)module->table_init_data_count;
  1400. if (!(module->table_init_data_list = data_list =
  1401. loader_malloc(size, error_buf, error_buf_size))) {
  1402. return false;
  1403. }
  1404. /* Create each table data segment */
  1405. for (i = 0; i < module->table_init_data_count; i++) {
  1406. uint32 mode, elem_type;
  1407. uint32 table_index, value_count;
  1408. uint64 size1;
  1409. InitializerExpression offset_expr;
  1410. read_uint32(buf, buf_end, mode);
  1411. read_uint32(buf, buf_end, elem_type);
  1412. read_uint32(buf, buf_end, table_index);
  1413. if (!load_init_expr(&buf, buf_end, module, &offset_expr, error_buf,
  1414. error_buf_size))
  1415. return false;
  1416. #if WASM_ENABLE_GC != 0
  1417. if (wasm_is_type_multi_byte_type(elem_type)) {
  1418. uint16 ref_type, nullable;
  1419. read_uint16(buf, buf_end, ref_type);
  1420. if (elem_type != ref_type) {
  1421. set_error_buf(error_buf, error_buf_size, "invalid elem type");
  1422. return false;
  1423. }
  1424. reftype.ref_ht_common.ref_type = (uint8)ref_type;
  1425. read_uint16(buf, buf_end, nullable);
  1426. if (nullable != 0 && nullable != 1) {
  1427. set_error_buf(error_buf, error_buf_size,
  1428. "invalid nullable value");
  1429. return false;
  1430. }
  1431. reftype.ref_ht_common.nullable = (uint8)nullable;
  1432. read_uint32(buf, buf_end, reftype.ref_ht_common.heap_type);
  1433. }
  1434. else
  1435. #endif
  1436. {
  1437. /* Skip 8 byte(2+2+4) for ref type info */
  1438. buf += 8;
  1439. }
  1440. read_uint32(buf, buf_end, value_count);
  1441. size1 = sizeof(InitializerExpression) * (uint64)value_count;
  1442. size = offsetof(AOTTableInitData, init_values) + size1;
  1443. if (!(data_list[i] = loader_malloc(size, error_buf, error_buf_size))) {
  1444. return false;
  1445. }
  1446. data_list[i]->mode = mode;
  1447. data_list[i]->elem_type = elem_type;
  1448. data_list[i]->table_index = table_index;
  1449. #if WASM_ENABLE_GC != 0
  1450. if (wasm_is_type_multi_byte_type(elem_type)) {
  1451. if (!(data_list[i]->elem_ref_type =
  1452. reftype_set_insert(module->ref_type_set, &reftype,
  1453. error_buf, error_buf_size))) {
  1454. goto fail;
  1455. }
  1456. }
  1457. #endif
  1458. data_list[i]->offset = offset_expr;
  1459. data_list[i]->value_count = value_count;
  1460. for (j = 0; j < data_list[i]->value_count; j++) {
  1461. if (!load_init_expr(&buf, buf_end, module,
  1462. &data_list[i]->init_values[j], error_buf,
  1463. error_buf_size))
  1464. return false;
  1465. }
  1466. }
  1467. *p_buf = buf;
  1468. return true;
  1469. fail:
  1470. return false;
  1471. }
  1472. static bool
  1473. load_table_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  1474. char *error_buf, uint32 error_buf_size)
  1475. {
  1476. const uint8 *buf = *p_buf;
  1477. read_uint32(buf, buf_end, module->import_table_count);
  1478. if (module->import_table_count > 0
  1479. && !load_import_table_list(&buf, buf_end, module, error_buf,
  1480. error_buf_size))
  1481. return false;
  1482. read_uint32(buf, buf_end, module->table_count);
  1483. if (module->table_count > 0
  1484. && !load_table_list(&buf, buf_end, module, error_buf, error_buf_size))
  1485. return false;
  1486. read_uint32(buf, buf_end, module->table_init_data_count);
  1487. /* load table init data list */
  1488. if (module->table_init_data_count > 0
  1489. && !load_table_init_data_list(&buf, buf_end, module, error_buf,
  1490. error_buf_size))
  1491. return false;
  1492. *p_buf = buf;
  1493. return true;
  1494. fail:
  1495. return false;
  1496. }
  1497. static void
  1498. destroy_type(AOTType *type)
  1499. {
  1500. #if WASM_ENABLE_GC != 0
  1501. if (type->ref_count > 1) {
  1502. /* The type is referenced by other types
  1503. of current aot module */
  1504. type->ref_count--;
  1505. return;
  1506. }
  1507. if (type->type_flag == WASM_TYPE_FUNC) {
  1508. AOTFuncType *func_type = (AOTFuncType *)type;
  1509. if (func_type->ref_type_maps != NULL) {
  1510. bh_assert(func_type->ref_type_map_count > 0);
  1511. wasm_runtime_free(func_type->ref_type_maps);
  1512. }
  1513. }
  1514. else if (type->type_flag == WASM_TYPE_STRUCT) {
  1515. AOTStructType *struct_type = (AOTStructType *)type;
  1516. if (struct_type->ref_type_maps != NULL) {
  1517. bh_assert(struct_type->ref_type_map_count > 0);
  1518. wasm_runtime_free(struct_type->ref_type_maps);
  1519. }
  1520. }
  1521. #endif
  1522. wasm_runtime_free(type);
  1523. }
  1524. static void
  1525. destroy_types(AOTType **types, uint32 count)
  1526. {
  1527. uint32 i;
  1528. for (i = 0; i < count; i++) {
  1529. if (types[i]) {
  1530. destroy_type(types[i]);
  1531. }
  1532. }
  1533. wasm_runtime_free(types);
  1534. }
  1535. #if WASM_ENABLE_GC != 0
  1536. static void
  1537. init_base_type(AOTType *base_type, uint32 type_idx, uint16 type_flag,
  1538. bool is_sub_final, uint32 parent_type_idx, uint16 rec_count,
  1539. uint16 rec_idx)
  1540. {
  1541. base_type->type_flag = type_flag;
  1542. base_type->ref_count = 1;
  1543. base_type->is_sub_final = is_sub_final;
  1544. base_type->parent_type_idx = parent_type_idx;
  1545. base_type->rec_count = rec_count;
  1546. base_type->rec_idx = rec_idx;
  1547. base_type->rec_begin_type_idx = type_idx - rec_idx;
  1548. }
  1549. static bool
  1550. load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  1551. char *error_buf, uint32 error_buf_size)
  1552. {
  1553. const uint8 *buf = *p_buf;
  1554. AOTType **types;
  1555. uint64 size;
  1556. uint32 i, j;
  1557. uint32 type_flag, param_cell_num, ret_cell_num;
  1558. uint16 param_count, result_count, ref_type_map_count, rec_count, rec_idx;
  1559. bool is_equivalence_type, is_sub_final;
  1560. uint32 parent_type_idx;
  1561. WASMRefType ref_type;
  1562. /* Allocate memory */
  1563. size = sizeof(AOTFuncType *) * (uint64)module->type_count;
  1564. if (!(types = loader_malloc(size, error_buf, error_buf_size))) {
  1565. return false;
  1566. }
  1567. module->types = types;
  1568. /* Create each type */
  1569. for (i = 0; i < module->type_count; i++) {
  1570. buf = align_ptr(buf, 4);
  1571. /* Read base type info */
  1572. read_uint16(buf, buf_end, type_flag);
  1573. read_uint8(buf, buf_end, is_equivalence_type);
  1574. /* If there is an equivalence type, reuse it */
  1575. if (is_equivalence_type) {
  1576. uint8 u8;
  1577. /* padding */
  1578. read_uint8(buf, buf_end, u8);
  1579. (void)u8;
  1580. read_uint32(buf, buf_end, j);
  1581. #if WASM_ENABLE_AOT_VALIDATOR != 0
  1582. /* an equivalence type should be before the type it refers to */
  1583. if (j >= i) {
  1584. set_error_buf(error_buf, error_buf_size, "invalid type index");
  1585. goto fail;
  1586. }
  1587. #endif
  1588. if (module->types[j]->ref_count == UINT16_MAX) {
  1589. set_error_buf(error_buf, error_buf_size,
  1590. "wasm type's ref count too large");
  1591. goto fail;
  1592. }
  1593. module->types[j]->ref_count++;
  1594. module->types[i] = module->types[j];
  1595. continue;
  1596. }
  1597. read_uint8(buf, buf_end, is_sub_final);
  1598. read_uint32(buf, buf_end, parent_type_idx);
  1599. read_uint16(buf, buf_end, rec_count);
  1600. read_uint16(buf, buf_end, rec_idx);
  1601. #if WASM_ENABLE_AOT_VALIDATOR != 0
  1602. if (rec_count > module->type_count) {
  1603. set_error_buf(error_buf, error_buf_size, "invalid rec count");
  1604. goto fail;
  1605. }
  1606. if (rec_idx > i || rec_idx >= rec_count) {
  1607. set_error_buf(error_buf, error_buf_size, "invalid rec idx");
  1608. goto fail;
  1609. }
  1610. if (parent_type_idx >= i) {
  1611. set_error_buf(
  1612. error_buf, error_buf_size,
  1613. "parent type index must be smaller than current type index");
  1614. goto fail;
  1615. }
  1616. #endif
  1617. if (type_flag == WASM_TYPE_FUNC) {
  1618. AOTFuncType *func_type;
  1619. /* Read param count */
  1620. read_uint16(buf, buf_end, param_count);
  1621. /* Read result count */
  1622. read_uint16(buf, buf_end, result_count);
  1623. /* Read ref_type_map_count */
  1624. read_uint16(buf, buf_end, ref_type_map_count);
  1625. func_type =
  1626. loader_malloc(sizeof(AOTFuncType) + param_count + result_count,
  1627. error_buf, error_buf_size);
  1628. if (!func_type) {
  1629. goto fail;
  1630. }
  1631. types[i] = (AOTType *)func_type;
  1632. init_base_type((AOTType *)func_type, i, type_flag, is_sub_final,
  1633. parent_type_idx, rec_count, rec_idx);
  1634. func_type->param_count = param_count;
  1635. func_type->result_count = result_count;
  1636. /* Read types of params */
  1637. read_byte_array(buf, buf_end, func_type->types,
  1638. func_type->param_count + func_type->result_count);
  1639. func_type->ref_type_map_count = ref_type_map_count;
  1640. if (!is_valid_func_type(func_type))
  1641. goto fail;
  1642. param_cell_num = wasm_get_cell_num(func_type->types, param_count);
  1643. ret_cell_num =
  1644. wasm_get_cell_num(func_type->types + param_count, result_count);
  1645. if (param_cell_num > UINT16_MAX || ret_cell_num > UINT16_MAX) {
  1646. set_error_buf(error_buf, error_buf_size,
  1647. "param count or result count too large");
  1648. goto fail;
  1649. }
  1650. func_type->param_cell_num = param_cell_num;
  1651. func_type->ret_cell_num = ret_cell_num;
  1652. #if WASM_ENABLE_QUICK_AOT_ENTRY != 0
  1653. func_type->quick_aot_entry =
  1654. wasm_native_lookup_quick_aot_entry(func_type);
  1655. #endif
  1656. LOG_VERBOSE("type %u: func, param count: %d, result count: %d, "
  1657. "ref type map count: %d",
  1658. i, param_count, result_count, ref_type_map_count);
  1659. /* If ref_type_map is not empty, read ref_type_map */
  1660. if (ref_type_map_count > 0) {
  1661. bh_assert(func_type->ref_type_map_count
  1662. <= func_type->param_count + func_type->result_count);
  1663. /* align to 4 since param_count + result_count may be odd */
  1664. buf = align_ptr(buf, 4);
  1665. if (!(func_type->ref_type_maps =
  1666. loader_malloc(sizeof(WASMRefTypeMap)
  1667. * func_type->ref_type_map_count,
  1668. error_buf, error_buf_size))) {
  1669. goto fail;
  1670. }
  1671. for (j = 0; j < func_type->ref_type_map_count; j++) {
  1672. read_uint16(buf, buf_end,
  1673. func_type->ref_type_maps[j].index);
  1674. read_uint8(buf, buf_end, ref_type.ref_ht_common.ref_type);
  1675. read_uint8(buf, buf_end, ref_type.ref_ht_common.nullable);
  1676. read_uint32(buf, buf_end, ref_type.ref_ht_common.heap_type);
  1677. /* TODO: check ref_type */
  1678. if (!(func_type->ref_type_maps[j].ref_type =
  1679. wasm_reftype_set_insert(module->ref_type_set,
  1680. &ref_type))) {
  1681. set_error_buf(error_buf, error_buf_size,
  1682. "insert ref type to hash set failed");
  1683. goto fail;
  1684. }
  1685. }
  1686. func_type->result_ref_type_maps = func_type->ref_type_maps;
  1687. for (j = 0; j < func_type->param_count; j++) {
  1688. if (wasm_is_type_multi_byte_type(func_type->types[j]))
  1689. func_type->result_ref_type_maps++;
  1690. }
  1691. }
  1692. }
  1693. else if (type_flag == WASM_TYPE_STRUCT) {
  1694. AOTStructType *struct_type;
  1695. const uint8 *buf_org;
  1696. uint16 *reference_table;
  1697. uint16 field_count, ref_field_count = 0;
  1698. uint32 offset;
  1699. read_uint16(buf, buf_end, field_count);
  1700. read_uint16(buf, buf_end, ref_type_map_count);
  1701. buf_org = buf;
  1702. /* Traverse first time to get ref_field_count */
  1703. for (j = 0; j < field_count; j++) {
  1704. uint8 field_flags, field_type;
  1705. read_uint8(buf, buf_end, field_flags);
  1706. read_uint8(buf, buf_end, field_type);
  1707. if (wasm_is_type_reftype(field_type))
  1708. ref_field_count++;
  1709. (void)field_flags;
  1710. }
  1711. struct_type = loader_malloc(
  1712. sizeof(AOTStructType)
  1713. + sizeof(WASMStructFieldType) * (uint64)field_count
  1714. + sizeof(uint16) * (uint64)(ref_field_count + 1),
  1715. error_buf, error_buf_size);
  1716. if (!struct_type) {
  1717. goto fail;
  1718. }
  1719. offset = (uint32)offsetof(WASMStructObject, field_data);
  1720. types[i] = (AOTType *)struct_type;
  1721. init_base_type((AOTType *)struct_type, i, type_flag, is_sub_final,
  1722. parent_type_idx, rec_count, rec_idx);
  1723. struct_type->field_count = field_count;
  1724. struct_type->ref_type_map_count = ref_type_map_count;
  1725. struct_type->reference_table = reference_table =
  1726. (uint16 *)((uint8 *)struct_type
  1727. + offsetof(AOTStructType, fields)
  1728. + sizeof(WASMStructFieldType) * field_count);
  1729. *reference_table++ = ref_field_count;
  1730. LOG_VERBOSE(
  1731. "type %u: struct, field count: %d, ref type map count: %d", i,
  1732. field_count, ref_type_map_count);
  1733. buf = buf_org;
  1734. /* Traverse again to read each field */
  1735. for (j = 0; j < field_count; j++) {
  1736. uint8 field_type, field_size;
  1737. read_uint8(buf, buf_end, struct_type->fields[j].field_flags);
  1738. read_uint8(buf, buf_end, field_type);
  1739. #if WASM_ENABLE_AOT_VALIDATOR != 0
  1740. if (!is_valid_field_type(field_type)) {
  1741. set_error_buf(error_buf, error_buf_size,
  1742. "invalid field type");
  1743. goto fail;
  1744. }
  1745. #endif
  1746. struct_type->fields[j].field_type = field_type;
  1747. struct_type->fields[j].field_size = field_size =
  1748. (uint8)wasm_reftype_size(field_type);
  1749. #if !(defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64) \
  1750. || defined(BUILD_TARGET_X86_32))
  1751. if (field_size == 2)
  1752. offset = align_uint(offset, 2);
  1753. else if (field_size >= 4) /* field size is 4 or 8 */
  1754. offset = align_uint(offset, 4);
  1755. #endif
  1756. struct_type->fields[j].field_offset = offset;
  1757. if (wasm_is_type_reftype(field_type))
  1758. *reference_table++ = offset;
  1759. offset += field_size;
  1760. LOG_VERBOSE(" field: %d, flags: %d, type: %d", j,
  1761. struct_type->fields[j].field_flags,
  1762. struct_type->fields[j].field_type);
  1763. }
  1764. struct_type->total_size = offset;
  1765. buf = align_ptr(buf, 4);
  1766. /* If ref_type_map is not empty, read ref_type_map */
  1767. if (ref_type_map_count > 0) {
  1768. bh_assert(struct_type->ref_type_map_count <= field_count);
  1769. if (!(struct_type->ref_type_maps =
  1770. loader_malloc(sizeof(WASMRefTypeMap)
  1771. * struct_type->ref_type_map_count,
  1772. error_buf, error_buf_size))) {
  1773. goto fail;
  1774. }
  1775. for (j = 0; j < struct_type->ref_type_map_count; j++) {
  1776. read_uint16(buf, buf_end,
  1777. struct_type->ref_type_maps[j].index);
  1778. read_uint8(buf, buf_end, ref_type.ref_ht_common.ref_type);
  1779. read_uint8(buf, buf_end, ref_type.ref_ht_common.nullable);
  1780. read_uint32(buf, buf_end, ref_type.ref_ht_common.heap_type);
  1781. /* TODO: check ref_type */
  1782. if (!(struct_type->ref_type_maps[j].ref_type =
  1783. wasm_reftype_set_insert(module->ref_type_set,
  1784. &ref_type))) {
  1785. set_error_buf(error_buf, error_buf_size,
  1786. "insert ref type to hash set failed");
  1787. goto fail;
  1788. }
  1789. }
  1790. }
  1791. }
  1792. else if (type_flag == WASM_TYPE_ARRAY) {
  1793. AOTArrayType *array_type;
  1794. array_type =
  1795. loader_malloc(sizeof(AOTArrayType), error_buf, error_buf_size);
  1796. if (!array_type) {
  1797. goto fail;
  1798. }
  1799. types[i] = (AOTType *)array_type;
  1800. init_base_type((AOTType *)array_type, i, type_flag, is_sub_final,
  1801. parent_type_idx, rec_count, rec_idx);
  1802. read_uint16(buf, buf_end, array_type->elem_flags);
  1803. read_uint8(buf, buf_end, array_type->elem_type);
  1804. if (wasm_is_type_multi_byte_type(array_type->elem_type)) {
  1805. read_uint8(buf, buf_end, ref_type.ref_ht_common.nullable);
  1806. read_uint32(buf, buf_end, ref_type.ref_ht_common.heap_type);
  1807. ref_type.ref_type = array_type->elem_type;
  1808. /* TODO: check ref_type */
  1809. if (!(array_type->elem_ref_type = wasm_reftype_set_insert(
  1810. module->ref_type_set, &ref_type))) {
  1811. set_error_buf(error_buf, error_buf_size,
  1812. "insert ref type to hash set failed");
  1813. goto fail;
  1814. }
  1815. }
  1816. LOG_VERBOSE("type %u: array", i);
  1817. }
  1818. else {
  1819. set_error_buf_v(error_buf, error_buf_size,
  1820. "invalid type flag: %" PRIu32, type_flag);
  1821. goto fail;
  1822. }
  1823. if ((rec_count == 0) || (rec_idx == rec_count - 1)) {
  1824. if (rec_count == 0) {
  1825. bh_assert(rec_idx == 0);
  1826. }
  1827. for (j = i - rec_idx; j <= i; j++) {
  1828. AOTType *cur_type = module->types[j];
  1829. parent_type_idx = cur_type->parent_type_idx;
  1830. if (parent_type_idx != (uint32)-1) { /* has parent */
  1831. AOTType *parent_type = module->types[parent_type_idx];
  1832. module->types[j]->parent_type = parent_type;
  1833. module->types[j]->root_type = parent_type->root_type;
  1834. if (parent_type->inherit_depth == UINT16_MAX) {
  1835. set_error_buf(error_buf, error_buf_size,
  1836. "parent type's inherit depth too large");
  1837. goto fail;
  1838. }
  1839. module->types[j]->inherit_depth =
  1840. parent_type->inherit_depth + 1;
  1841. }
  1842. else {
  1843. module->types[j]->parent_type = NULL;
  1844. module->types[j]->root_type = module->types[j];
  1845. module->types[j]->inherit_depth = 0;
  1846. }
  1847. }
  1848. for (j = i - rec_idx; j <= i; j++) {
  1849. AOTType *cur_type = module->types[j];
  1850. parent_type_idx = cur_type->parent_type_idx;
  1851. if (parent_type_idx != (uint32)-1) { /* has parent */
  1852. AOTType *parent_type = module->types[parent_type_idx];
  1853. /* subtyping has been checked during compilation */
  1854. bh_assert(wasm_type_is_subtype_of(
  1855. module->types[j], parent_type, module->types, i + 1));
  1856. (void)parent_type;
  1857. }
  1858. }
  1859. }
  1860. }
  1861. if (module->type_count) {
  1862. if (!(module->rtt_types = loader_malloc((uint64)sizeof(WASMRttType *)
  1863. * module->type_count,
  1864. error_buf, error_buf_size))) {
  1865. goto fail;
  1866. }
  1867. }
  1868. *p_buf = buf;
  1869. return true;
  1870. fail:
  1871. /* Destroy all types */
  1872. destroy_types(types, module->type_count);
  1873. module->types = NULL;
  1874. return false;
  1875. }
  1876. #else
  1877. static bool
  1878. load_types(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  1879. char *error_buf, uint32 error_buf_size)
  1880. {
  1881. const uint8 *buf = *p_buf;
  1882. AOTFuncType **func_types;
  1883. uint64 size;
  1884. uint32 i;
  1885. /* Allocate memory */
  1886. size = sizeof(AOTFuncType *) * (uint64)module->type_count;
  1887. if (!(func_types = loader_malloc(size, error_buf, error_buf_size))) {
  1888. return false;
  1889. }
  1890. module->types = (AOTType **)func_types;
  1891. /* Create each function type */
  1892. for (i = 0; i < module->type_count; i++) {
  1893. uint32 type_flag;
  1894. uint32 param_count, result_count;
  1895. uint32 param_cell_num, ret_cell_num;
  1896. uint64 size1;
  1897. buf = align_ptr(buf, 4);
  1898. read_uint16(buf, buf_end, type_flag);
  1899. read_uint16(buf, buf_end, param_count);
  1900. read_uint16(buf, buf_end, result_count);
  1901. size1 = (uint64)param_count + (uint64)result_count;
  1902. size = offsetof(AOTFuncType, types) + size1;
  1903. if (!(func_types[i] = loader_malloc(size, error_buf, error_buf_size))) {
  1904. return false;
  1905. }
  1906. func_types[i]->param_count = (uint16)param_count;
  1907. func_types[i]->result_count = (uint16)result_count;
  1908. read_byte_array(buf, buf_end, func_types[i]->types, (uint32)size1);
  1909. if (!is_valid_func_type(func_types[i]))
  1910. goto fail;
  1911. param_cell_num = wasm_get_cell_num(func_types[i]->types, param_count);
  1912. ret_cell_num =
  1913. wasm_get_cell_num(func_types[i]->types + param_count, result_count);
  1914. if (param_cell_num > UINT16_MAX || ret_cell_num > UINT16_MAX) {
  1915. set_error_buf(error_buf, error_buf_size,
  1916. "param count or result count too large");
  1917. return false;
  1918. }
  1919. func_types[i]->param_cell_num = (uint16)param_cell_num;
  1920. func_types[i]->ret_cell_num = (uint16)ret_cell_num;
  1921. #if WASM_ENABLE_QUICK_AOT_ENTRY != 0
  1922. func_types[i]->quick_aot_entry =
  1923. wasm_native_lookup_quick_aot_entry(func_types[i]);
  1924. #endif
  1925. }
  1926. *p_buf = buf;
  1927. return true;
  1928. fail:
  1929. return false;
  1930. }
  1931. #endif /* end of WASM_ENABLE_GC != 0 */
  1932. static bool
  1933. load_type_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  1934. char *error_buf, uint32 error_buf_size)
  1935. {
  1936. const uint8 *buf = *p_buf;
  1937. read_uint32(buf, buf_end, module->type_count);
  1938. /* load function type */
  1939. if (module->type_count > 0
  1940. && !load_types(&buf, buf_end, module, error_buf, error_buf_size))
  1941. return false;
  1942. *p_buf = buf;
  1943. return true;
  1944. fail:
  1945. return false;
  1946. }
  1947. static void
  1948. destroy_import_globals(AOTImportGlobal *import_globals)
  1949. {
  1950. wasm_runtime_free(import_globals);
  1951. }
  1952. static bool
  1953. load_import_globals(const uint8 **p_buf, const uint8 *buf_end,
  1954. AOTModule *module, bool is_load_from_file_buf,
  1955. char *error_buf, uint32 error_buf_size)
  1956. {
  1957. const uint8 *buf = *p_buf;
  1958. AOTImportGlobal *import_globals;
  1959. uint64 size;
  1960. uint32 i, data_offset = 0;
  1961. #if WASM_ENABLE_LIBC_BUILTIN != 0
  1962. WASMGlobalImport tmp_global;
  1963. #endif
  1964. /* Allocate memory */
  1965. size = sizeof(AOTImportGlobal) * (uint64)module->import_global_count;
  1966. if (!(module->import_globals = import_globals =
  1967. loader_malloc(size, error_buf, error_buf_size))) {
  1968. return false;
  1969. }
  1970. /* Create each import global */
  1971. for (i = 0; i < module->import_global_count; i++) {
  1972. buf = (uint8 *)align_ptr(buf, 2);
  1973. read_uint8(buf, buf_end, import_globals[i].type.val_type);
  1974. read_uint8(buf, buf_end, import_globals[i].type.is_mutable);
  1975. read_string(buf, buf_end, import_globals[i].module_name);
  1976. read_string(buf, buf_end, import_globals[i].global_name);
  1977. if (!is_valid_value_type(import_globals[i].type.val_type)) {
  1978. return false;
  1979. }
  1980. #if WASM_ENABLE_LIBC_BUILTIN != 0
  1981. if (wasm_native_lookup_libc_builtin_global(
  1982. import_globals[i].module_name, import_globals[i].global_name,
  1983. &tmp_global)) {
  1984. if (tmp_global.type.val_type != import_globals[i].type.val_type
  1985. || tmp_global.type.is_mutable
  1986. != import_globals[i].type.is_mutable) {
  1987. set_error_buf(error_buf, error_buf_size,
  1988. "incompatible import type");
  1989. return false;
  1990. }
  1991. import_globals[i].global_data_linked =
  1992. tmp_global.global_data_linked;
  1993. import_globals[i].is_linked = true;
  1994. }
  1995. #else
  1996. import_globals[i].is_linked = false;
  1997. #endif
  1998. import_globals[i].size =
  1999. wasm_value_type_size(import_globals[i].type.val_type);
  2000. import_globals[i].data_offset = data_offset;
  2001. data_offset += import_globals[i].size;
  2002. module->global_data_size += import_globals[i].size;
  2003. }
  2004. *p_buf = buf;
  2005. return true;
  2006. fail:
  2007. return false;
  2008. }
  2009. static bool
  2010. load_import_global_info(const uint8 **p_buf, const uint8 *buf_end,
  2011. AOTModule *module, bool is_load_from_file_buf,
  2012. char *error_buf, uint32 error_buf_size)
  2013. {
  2014. const uint8 *buf = *p_buf;
  2015. read_uint32(buf, buf_end, module->import_global_count);
  2016. /* load import globals */
  2017. if (module->import_global_count > 0
  2018. && !load_import_globals(&buf, buf_end, module, is_load_from_file_buf,
  2019. error_buf, error_buf_size))
  2020. return false;
  2021. *p_buf = buf;
  2022. return true;
  2023. fail:
  2024. return false;
  2025. }
  2026. static void
  2027. destroy_globals(AOTGlobal *globals)
  2028. {
  2029. wasm_runtime_free(globals);
  2030. }
  2031. static bool
  2032. load_globals(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  2033. char *error_buf, uint32 error_buf_size)
  2034. {
  2035. const uint8 *buf = *p_buf;
  2036. AOTGlobal *globals;
  2037. uint64 size;
  2038. uint32 i, data_offset = 0;
  2039. AOTImportGlobal *last_import_global;
  2040. /* Allocate memory */
  2041. size = sizeof(AOTGlobal) * (uint64)module->global_count;
  2042. if (!(module->globals = globals =
  2043. loader_malloc(size, error_buf, error_buf_size))) {
  2044. return false;
  2045. }
  2046. if (module->import_global_count > 0) {
  2047. last_import_global =
  2048. &module->import_globals[module->import_global_count - 1];
  2049. data_offset =
  2050. last_import_global->data_offset + last_import_global->size;
  2051. }
  2052. /* Create each global */
  2053. for (i = 0; i < module->global_count; i++) {
  2054. read_uint8(buf, buf_end, globals[i].type.val_type);
  2055. read_uint8(buf, buf_end, globals[i].type.is_mutable);
  2056. if (!is_valid_value_type(globals[i].type.val_type))
  2057. return false;
  2058. buf = align_ptr(buf, 4);
  2059. if (!load_init_expr(&buf, buf_end, module, &globals[i].init_expr,
  2060. error_buf, error_buf_size))
  2061. return false;
  2062. globals[i].size = wasm_value_type_size(globals[i].type.val_type);
  2063. globals[i].data_offset = data_offset;
  2064. data_offset += globals[i].size;
  2065. module->global_data_size += globals[i].size;
  2066. }
  2067. *p_buf = buf;
  2068. return true;
  2069. fail:
  2070. return false;
  2071. }
  2072. static bool
  2073. load_global_info(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  2074. char *error_buf, uint32 error_buf_size)
  2075. {
  2076. const uint8 *buf = *p_buf;
  2077. read_uint32(buf, buf_end, module->global_count);
  2078. if (is_indices_overflow(module->import_global_count, module->global_count,
  2079. error_buf, error_buf_size))
  2080. return false;
  2081. /* load globals */
  2082. if (module->global_count > 0
  2083. && !load_globals(&buf, buf_end, module, error_buf, error_buf_size))
  2084. return false;
  2085. *p_buf = buf;
  2086. return true;
  2087. fail:
  2088. return false;
  2089. }
  2090. static void
  2091. destroy_import_funcs(AOTImportFunc *import_funcs)
  2092. {
  2093. wasm_runtime_free(import_funcs);
  2094. }
  2095. static bool
  2096. load_import_funcs(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  2097. bool is_load_from_file_buf, bool no_resolve, char *error_buf,
  2098. uint32 error_buf_size)
  2099. {
  2100. const uint8 *buf = *p_buf;
  2101. AOTImportFunc *import_funcs;
  2102. uint64 size;
  2103. uint32 i;
  2104. /* Allocate memory */
  2105. size = sizeof(AOTImportFunc) * (uint64)module->import_func_count;
  2106. if (!(module->import_funcs = import_funcs =
  2107. loader_malloc(size, error_buf, error_buf_size))) {
  2108. return false;
  2109. }
  2110. /* Create each import func */
  2111. for (i = 0; i < module->import_func_count; i++) {
  2112. read_uint16(buf, buf_end, import_funcs[i].func_type_index);
  2113. if (import_funcs[i].func_type_index >= module->type_count) {
  2114. set_error_buf(error_buf, error_buf_size, "unknown type");
  2115. return false;
  2116. }
  2117. import_funcs[i].func_type =
  2118. (AOTFuncType *)module->types[import_funcs[i].func_type_index];
  2119. read_string(buf, buf_end, import_funcs[i].module_name);
  2120. read_string(buf, buf_end, import_funcs[i].func_name);
  2121. import_funcs[i].attachment = NULL;
  2122. import_funcs[i].signature = NULL;
  2123. import_funcs[i].call_conv_raw = false;
  2124. if (!no_resolve) {
  2125. aot_resolve_import_func(module, &import_funcs[i]);
  2126. }
  2127. #if WASM_ENABLE_LIBC_WASI != 0
  2128. if (!strcmp(import_funcs[i].module_name, "wasi_unstable")
  2129. || !strcmp(import_funcs[i].module_name, "wasi_snapshot_preview1"))
  2130. module->import_wasi_api = true;
  2131. #endif
  2132. }
  2133. *p_buf = buf;
  2134. return true;
  2135. fail:
  2136. return false;
  2137. }
  2138. static bool
  2139. load_import_func_info(const uint8 **p_buf, const uint8 *buf_end,
  2140. AOTModule *module, bool is_load_from_file_buf,
  2141. bool no_resolve, char *error_buf, uint32 error_buf_size)
  2142. {
  2143. const uint8 *buf = *p_buf;
  2144. read_uint32(buf, buf_end, module->import_func_count);
  2145. /* load import funcs */
  2146. if (module->import_func_count > 0
  2147. && !load_import_funcs(&buf, buf_end, module, is_load_from_file_buf,
  2148. no_resolve, error_buf, error_buf_size))
  2149. return false;
  2150. *p_buf = buf;
  2151. return true;
  2152. fail:
  2153. return false;
  2154. }
  2155. static void
  2156. destroy_object_data_sections(AOTObjectDataSection *data_sections,
  2157. uint32 data_section_count)
  2158. {
  2159. uint32 i;
  2160. AOTObjectDataSection *data_section = data_sections;
  2161. for (i = 0; i < data_section_count; i++, data_section++)
  2162. if (data_section->data) {
  2163. #if WASM_ENABLE_STATIC_PGO != 0
  2164. if (!strncmp(data_section->name, "__llvm_prf_data", 15)) {
  2165. LLVMProfileData *data = (LLVMProfileData *)data_section->data;
  2166. if (data->values) {
  2167. uint32 num_value_sites =
  2168. data->num_value_sites[0] + data->num_value_sites[1];
  2169. uint32 j;
  2170. for (j = 0; j < num_value_sites; j++) {
  2171. ValueProfNode *node = data->values[j], *node_next;
  2172. while (node) {
  2173. node_next = node->next;
  2174. wasm_runtime_free(node);
  2175. node = node_next;
  2176. }
  2177. }
  2178. wasm_runtime_free(data->values);
  2179. }
  2180. }
  2181. #endif
  2182. }
  2183. wasm_runtime_free(data_sections);
  2184. }
  2185. static bool
  2186. load_object_data_sections(const uint8 **p_buf, const uint8 *buf_end,
  2187. AOTModule *module, bool is_load_from_file_buf,
  2188. char *error_buf, uint32 error_buf_size)
  2189. {
  2190. const uint8 *buf = *p_buf;
  2191. AOTObjectDataSection *data_sections;
  2192. uint64 size;
  2193. uint32 i;
  2194. uint64 total_size = 0;
  2195. uint32 page_size = os_getpagesize();
  2196. uint8 *merged_sections = NULL;
  2197. /* Allocate memory */
  2198. size = sizeof(AOTObjectDataSection) * (uint64)module->data_section_count;
  2199. if (!(module->data_sections = data_sections =
  2200. loader_malloc(size, error_buf, error_buf_size))) {
  2201. return false;
  2202. }
  2203. /* First iteration: read data from buf, and calculate total memory needed */
  2204. for (i = 0; i < module->data_section_count; i++) {
  2205. read_string(buf, buf_end, data_sections[i].name);
  2206. read_uint32(buf, buf_end, data_sections[i].size);
  2207. CHECK_BUF(buf, buf_end, data_sections[i].size);
  2208. /* Temporary record data ptr for merge, will be replaced after the
  2209. merged_data_sections is mmapped */
  2210. if (data_sections[i].size > 0)
  2211. data_sections[i].data = (uint8 *)buf;
  2212. buf += data_sections[i].size;
  2213. total_size += align_uint64((uint64)data_sections[i].size, page_size);
  2214. }
  2215. if (total_size > UINT32_MAX) {
  2216. set_error_buf(error_buf, error_buf_size, "data sections too large");
  2217. return false;
  2218. }
  2219. if (total_size > 0) {
  2220. /* Allocate memory for data */
  2221. merged_sections = module->merged_data_sections =
  2222. loader_mmap((uint32)total_size, false, error_buf, error_buf_size);
  2223. if (!merged_sections) {
  2224. return false;
  2225. }
  2226. module->merged_data_sections_size = (uint32)total_size;
  2227. }
  2228. /* Second iteration: Create each data section */
  2229. for (i = 0; i < module->data_section_count; i++) {
  2230. if (data_sections[i].size > 0) {
  2231. bh_memcpy_s(merged_sections, data_sections[i].size,
  2232. data_sections[i].data, data_sections[i].size);
  2233. data_sections[i].data = merged_sections;
  2234. merged_sections += align_uint(data_sections[i].size, page_size);
  2235. }
  2236. }
  2237. *p_buf = buf;
  2238. return true;
  2239. fail:
  2240. return false;
  2241. }
  2242. static bool
  2243. load_object_data_sections_info(const uint8 **p_buf, const uint8 *buf_end,
  2244. AOTModule *module, bool is_load_from_file_buf,
  2245. char *error_buf, uint32 error_buf_size)
  2246. {
  2247. const uint8 *buf = *p_buf;
  2248. read_uint32(buf, buf_end, module->data_section_count);
  2249. /* load object data sections */
  2250. if (module->data_section_count > 0
  2251. && !load_object_data_sections(&buf, buf_end, module,
  2252. is_load_from_file_buf, error_buf,
  2253. error_buf_size))
  2254. return false;
  2255. *p_buf = buf;
  2256. return true;
  2257. fail:
  2258. return false;
  2259. }
  2260. static bool
  2261. load_init_data_section(const uint8 *buf, const uint8 *buf_end,
  2262. AOTModule *module, bool is_load_from_file_buf,
  2263. bool no_resolve, char *error_buf, uint32 error_buf_size)
  2264. {
  2265. const uint8 *p = buf, *p_end = buf_end;
  2266. if (!load_memory_info(&p, p_end, module, error_buf, error_buf_size)
  2267. || !load_table_info(&p, p_end, module, error_buf, error_buf_size)
  2268. || !load_type_info(&p, p_end, module, error_buf, error_buf_size)
  2269. || !load_import_global_info(&p, p_end, module, is_load_from_file_buf,
  2270. error_buf, error_buf_size)
  2271. || !load_global_info(&p, p_end, module, error_buf, error_buf_size)
  2272. || !load_import_func_info(&p, p_end, module, is_load_from_file_buf,
  2273. no_resolve, error_buf, error_buf_size))
  2274. return false;
  2275. /* load function count and start function index */
  2276. read_uint32(p, p_end, module->func_count);
  2277. if (is_indices_overflow(module->import_func_count, module->func_count,
  2278. error_buf, error_buf_size))
  2279. return false;
  2280. read_uint32(p, p_end, module->start_func_index);
  2281. /* check start function index */
  2282. if (module->start_func_index != (uint32)-1
  2283. && (module->start_func_index
  2284. >= module->import_func_count + module->func_count)) {
  2285. set_error_buf(error_buf, error_buf_size,
  2286. "invalid start function index");
  2287. return false;
  2288. }
  2289. read_uint32(p, p_end, module->aux_data_end_global_index);
  2290. read_uint64(p, p_end, module->aux_data_end);
  2291. read_uint32(p, p_end, module->aux_heap_base_global_index);
  2292. read_uint64(p, p_end, module->aux_heap_base);
  2293. read_uint32(p, p_end, module->aux_stack_top_global_index);
  2294. read_uint64(p, p_end, module->aux_stack_bottom);
  2295. read_uint32(p, p_end, module->aux_stack_size);
  2296. if (module->aux_data_end >= MAX_LINEAR_MEMORY_SIZE
  2297. || module->aux_heap_base >= MAX_LINEAR_MEMORY_SIZE
  2298. || module->aux_stack_bottom >= MAX_LINEAR_MEMORY_SIZE) {
  2299. set_error_buf(
  2300. error_buf, error_buf_size,
  2301. "invalid range of aux_date_end/aux_heap_base/aux_stack_bottom");
  2302. return false;
  2303. }
  2304. if (!load_object_data_sections_info(&p, p_end, module,
  2305. is_load_from_file_buf, error_buf,
  2306. error_buf_size))
  2307. return false;
  2308. if (p != p_end) {
  2309. set_error_buf(error_buf, error_buf_size,
  2310. "invalid init data section size");
  2311. return false;
  2312. }
  2313. return true;
  2314. fail:
  2315. return false;
  2316. }
  2317. #if !defined(BH_PLATFORM_NUTTX) && !defined(BH_PLATFORM_ESP_IDF)
  2318. static bool
  2319. try_merge_data_and_text(const uint8 **buf, const uint8 **buf_end,
  2320. AOTModule *module, char *error_buf,
  2321. uint32 error_buf_size)
  2322. {
  2323. uint8 *old_buf = (uint8 *)*buf;
  2324. uint8 *old_end = (uint8 *)*buf_end;
  2325. size_t code_size = (size_t)(old_end - old_buf);
  2326. uint32 page_size = os_getpagesize();
  2327. uint64 total_size = 0;
  2328. uint32 i;
  2329. uint8 *sections;
  2330. if (code_size == 0) {
  2331. return true;
  2332. }
  2333. /* calculate the total memory needed */
  2334. total_size += align_uint64((uint64)code_size, page_size);
  2335. for (i = 0; i < module->data_section_count; ++i) {
  2336. total_size +=
  2337. align_uint64((uint64)module->data_sections[i].size, page_size);
  2338. }
  2339. /* distance between .data and .text should not be greater than 4GB
  2340. for some targets (e.g. arm64 reloc need < 4G distance) */
  2341. if (total_size > UINT32_MAX) {
  2342. return false;
  2343. }
  2344. /* code_size was checked and must be larger than 0 here */
  2345. bh_assert(total_size > 0);
  2346. sections = loader_mmap((uint32)total_size, false, NULL, 0);
  2347. if (!sections) {
  2348. /* merge failed but may be not critical for some targets */
  2349. return false;
  2350. }
  2351. #ifdef BH_PLATFORM_WINDOWS
  2352. if (!os_mem_commit(sections, code_size,
  2353. MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC)) {
  2354. os_munmap(sections, (uint32)total_size);
  2355. return false;
  2356. }
  2357. #endif
  2358. /* change the code part to be executable */
  2359. if (os_mprotect(sections, code_size,
  2360. MMAP_PROT_READ | MMAP_PROT_WRITE | MMAP_PROT_EXEC)
  2361. != 0) {
  2362. os_munmap(sections, (uint32)total_size);
  2363. return false;
  2364. }
  2365. module->merged_data_text_sections = sections;
  2366. module->merged_data_text_sections_size = (uint32)total_size;
  2367. /* order not essential just as compiler does: .text section first */
  2368. *buf = sections;
  2369. *buf_end = sections + code_size;
  2370. bh_memcpy_s(sections, (uint32)code_size, old_buf, (uint32)code_size);
  2371. os_munmap(old_buf, code_size);
  2372. sections += align_uint((uint32)code_size, page_size);
  2373. /* then migrate .data sections */
  2374. for (i = 0; i < module->data_section_count; ++i) {
  2375. AOTObjectDataSection *data_section = module->data_sections + i;
  2376. uint8 *old_data = data_section->data;
  2377. data_section->data = sections;
  2378. bh_memcpy_s(data_section->data, data_section->size, old_data,
  2379. data_section->size);
  2380. sections += align_uint(data_section->size, page_size);
  2381. }
  2382. /* free the original data sections */
  2383. if (module->merged_data_sections) {
  2384. os_munmap(module->merged_data_sections,
  2385. module->merged_data_sections_size);
  2386. module->merged_data_sections = NULL;
  2387. module->merged_data_sections_size = 0;
  2388. }
  2389. return true;
  2390. }
  2391. #endif /* ! defined(BH_PLATFORM_NUTTX) && !defined(BH_PLATFORM_ESP_IDF) */
  2392. static bool
  2393. load_text_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
  2394. char *error_buf, uint32 error_buf_size)
  2395. {
  2396. uint8 *plt_base;
  2397. if (module->func_count > 0 && buf_end == buf) {
  2398. set_error_buf(error_buf, error_buf_size, "invalid code size");
  2399. return false;
  2400. }
  2401. /* The layout is: literal size + literal + code (with plt table) */
  2402. read_uint32(buf, buf_end, module->literal_size);
  2403. /* literal data is at beginning of the text section */
  2404. module->literal = (uint8 *)buf;
  2405. module->code = (void *)(buf + module->literal_size);
  2406. module->code_size = (uint32)(buf_end - (uint8 *)module->code);
  2407. #if WASM_ENABLE_DEBUG_AOT != 0
  2408. module->elf_size = module->code_size;
  2409. if (is_ELF(module->code)) {
  2410. /* Now code points to an ELF object, we pull it down to .text section */
  2411. uint64 offset;
  2412. uint64 size;
  2413. char *code_buf = module->code;
  2414. module->elf_hdr = code_buf;
  2415. if (!get_text_section(code_buf, &offset, &size)) {
  2416. set_error_buf(error_buf, error_buf_size,
  2417. "get text section of ELF failed");
  2418. return false;
  2419. }
  2420. module->code = code_buf + offset;
  2421. module->code_size -= (uint32)offset;
  2422. }
  2423. #endif
  2424. if ((module->code_size > 0) && !module->is_indirect_mode) {
  2425. plt_base = (uint8 *)buf_end - get_plt_table_size();
  2426. init_plt_table(plt_base);
  2427. }
  2428. return true;
  2429. fail:
  2430. return false;
  2431. }
  2432. static bool
  2433. load_function_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
  2434. char *error_buf, uint32 error_buf_size)
  2435. {
  2436. const uint8 *p = buf, *p_end = buf_end;
  2437. uint32 i;
  2438. uint64 size, text_offset;
  2439. size = sizeof(void *) * (uint64)module->func_count;
  2440. if (size > 0
  2441. && !(module->func_ptrs =
  2442. loader_malloc(size, error_buf, error_buf_size))) {
  2443. return false;
  2444. }
  2445. for (i = 0; i < module->func_count; i++) {
  2446. if (sizeof(void *) == 8) {
  2447. read_uint64(p, p_end, text_offset);
  2448. }
  2449. else {
  2450. uint32 text_offset32;
  2451. read_uint32(p, p_end, text_offset32);
  2452. text_offset = text_offset32;
  2453. }
  2454. if (text_offset >= module->code_size) {
  2455. set_error_buf(error_buf, error_buf_size,
  2456. "invalid function code offset");
  2457. return false;
  2458. }
  2459. module->func_ptrs[i] = (uint8 *)module->code + text_offset;
  2460. #if defined(BUILD_TARGET_THUMB) || defined(BUILD_TARGET_THUMB_VFP)
  2461. /* bits[0] of thumb function address must be 1 */
  2462. module->func_ptrs[i] = (void *)((uintptr_t)module->func_ptrs[i] | 1);
  2463. #endif
  2464. }
  2465. /* Set start function when function pointers are resolved */
  2466. if (module->start_func_index != (uint32)-1) {
  2467. if (module->start_func_index >= module->import_func_count)
  2468. module->start_function =
  2469. module->func_ptrs[module->start_func_index
  2470. - module->import_func_count];
  2471. else
  2472. /* TODO: fix start function can be import function issue */
  2473. module->start_function = NULL;
  2474. }
  2475. else {
  2476. module->start_function = NULL;
  2477. }
  2478. size = sizeof(uint32) * (uint64)module->func_count;
  2479. if (size > 0
  2480. && !(module->func_type_indexes =
  2481. loader_malloc(size, error_buf, error_buf_size))) {
  2482. return false;
  2483. }
  2484. for (i = 0; i < module->func_count; i++) {
  2485. read_uint32(p, p_end, module->func_type_indexes[i]);
  2486. if (module->func_type_indexes[i] >= module->type_count) {
  2487. set_error_buf(error_buf, error_buf_size, "unknown type");
  2488. return false;
  2489. }
  2490. }
  2491. size = sizeof(uint32) * (uint64)module->func_count;
  2492. if (size > 0) {
  2493. #if WASM_ENABLE_AOT_STACK_FRAME != 0
  2494. if (!(module->max_local_cell_nums =
  2495. loader_malloc(size, error_buf, error_buf_size))) {
  2496. return false;
  2497. }
  2498. for (i = 0; i < module->func_count; i++) {
  2499. read_uint32(p, p_end, module->max_local_cell_nums[i]);
  2500. }
  2501. if (!(module->max_stack_cell_nums =
  2502. loader_malloc(size, error_buf, error_buf_size))) {
  2503. return false;
  2504. }
  2505. for (i = 0; i < module->func_count; i++) {
  2506. read_uint32(p, p_end, module->max_stack_cell_nums[i]);
  2507. }
  2508. #else
  2509. /* Ignore max_local_cell_num and max_stack_cell_num of each function */
  2510. CHECK_BUF(p, p_end, ((uint32)size * 2));
  2511. p += (uint32)size * 2;
  2512. #endif
  2513. }
  2514. #if WASM_ENABLE_GC != 0
  2515. /* Local(params and locals) ref flags for all import and non-imported
  2516. * functions. The flags indicate whether each cell in the AOTFrame local
  2517. * area is a GC reference. */
  2518. size = sizeof(LocalRefFlag)
  2519. * (uint64)(module->import_func_count + module->func_count);
  2520. if (size > 0) {
  2521. if (!(module->func_local_ref_flags =
  2522. loader_malloc(size, error_buf, error_buf_size))) {
  2523. return false;
  2524. }
  2525. for (i = 0; i < module->import_func_count + module->func_count; i++) {
  2526. uint32 local_ref_flag_cell_num;
  2527. buf = (uint8 *)align_ptr(buf, sizeof(uint32));
  2528. read_uint32(
  2529. p, p_end,
  2530. module->func_local_ref_flags[i].local_ref_flag_cell_num);
  2531. local_ref_flag_cell_num =
  2532. module->func_local_ref_flags[i].local_ref_flag_cell_num;
  2533. size = sizeof(uint8) * (uint64)local_ref_flag_cell_num;
  2534. if (size > 0) {
  2535. if (!(module->func_local_ref_flags[i].local_ref_flags =
  2536. loader_malloc(size, error_buf, error_buf_size))) {
  2537. return false;
  2538. }
  2539. read_byte_array(p, p_end,
  2540. module->func_local_ref_flags[i].local_ref_flags,
  2541. local_ref_flag_cell_num);
  2542. }
  2543. }
  2544. }
  2545. #endif /* end of WASM_ENABLE_GC != 0 */
  2546. if (p != buf_end) {
  2547. set_error_buf(error_buf, error_buf_size,
  2548. "invalid function section size");
  2549. return false;
  2550. }
  2551. return true;
  2552. fail:
  2553. return false;
  2554. }
  2555. static void
  2556. destroy_exports(AOTExport *exports)
  2557. {
  2558. wasm_runtime_free(exports);
  2559. }
  2560. static int
  2561. cmp_export_name(const void *a, const void *b)
  2562. {
  2563. return strcmp(*(char **)a, *(char **)b);
  2564. }
  2565. static bool
  2566. check_duplicate_exports(AOTModule *module, char *error_buf,
  2567. uint32 error_buf_size)
  2568. {
  2569. uint32 i;
  2570. bool result = false;
  2571. char *names_buf[32], **names = names_buf;
  2572. if (module->export_count > 32) {
  2573. names = loader_malloc(module->export_count * sizeof(char *), error_buf,
  2574. error_buf_size);
  2575. if (!names) {
  2576. return result;
  2577. }
  2578. }
  2579. for (i = 0; i < module->export_count; i++) {
  2580. names[i] = module->exports[i].name;
  2581. }
  2582. qsort(names, module->export_count, sizeof(char *), cmp_export_name);
  2583. for (i = 1; i < module->export_count; i++) {
  2584. if (!strcmp(names[i], names[i - 1])) {
  2585. set_error_buf(error_buf, error_buf_size, "duplicate export name");
  2586. goto cleanup;
  2587. }
  2588. }
  2589. result = true;
  2590. cleanup:
  2591. if (module->export_count > 32) {
  2592. wasm_runtime_free(names);
  2593. }
  2594. return result;
  2595. }
  2596. static bool
  2597. load_exports(const uint8 **p_buf, const uint8 *buf_end, AOTModule *module,
  2598. bool is_load_from_file_buf, char *error_buf, uint32 error_buf_size)
  2599. {
  2600. const uint8 *buf = *p_buf;
  2601. AOTExport *exports;
  2602. uint64 size;
  2603. uint32 i;
  2604. /* Allocate memory */
  2605. size = sizeof(AOTExport) * (uint64)module->export_count;
  2606. if (!(module->exports = exports =
  2607. loader_malloc(size, error_buf, error_buf_size))) {
  2608. return false;
  2609. }
  2610. /* Create each export */
  2611. for (i = 0; i < module->export_count; i++) {
  2612. read_uint32(buf, buf_end, exports[i].index);
  2613. read_uint8(buf, buf_end, exports[i].kind);
  2614. read_string(buf, buf_end, exports[i].name);
  2615. /* Check export kind and index */
  2616. switch (exports[i].kind) {
  2617. case EXPORT_KIND_FUNC:
  2618. if (exports[i].index
  2619. >= module->import_func_count + module->func_count) {
  2620. set_error_buf(error_buf, error_buf_size,
  2621. "unknown function");
  2622. return false;
  2623. }
  2624. break;
  2625. case EXPORT_KIND_TABLE:
  2626. if (exports[i].index
  2627. >= module->import_table_count + module->table_count) {
  2628. set_error_buf(error_buf, error_buf_size, "unknown table");
  2629. return false;
  2630. }
  2631. break;
  2632. case EXPORT_KIND_MEMORY:
  2633. if (exports[i].index
  2634. >= module->import_memory_count + module->memory_count) {
  2635. set_error_buf(error_buf, error_buf_size, "unknown memory");
  2636. return false;
  2637. }
  2638. break;
  2639. case EXPORT_KIND_GLOBAL:
  2640. if (exports[i].index
  2641. >= module->import_global_count + module->global_count) {
  2642. set_error_buf(error_buf, error_buf_size, "unknown global");
  2643. return false;
  2644. }
  2645. break;
  2646. #if WASM_ENABLE_TAGS != 0
  2647. /* TODO
  2648. case EXPORT_KIND_TAG:
  2649. if (index >= module->import_tag_count + module->tag_count) {
  2650. set_error_buf(error_buf, error_buf_size, "unknown tag");
  2651. return false;
  2652. }
  2653. break;
  2654. */
  2655. #endif
  2656. default:
  2657. set_error_buf(error_buf, error_buf_size, "invalid export kind");
  2658. return false;
  2659. }
  2660. }
  2661. if (module->export_count > 0) {
  2662. if (!check_duplicate_exports(module, error_buf, error_buf_size)) {
  2663. return false;
  2664. }
  2665. }
  2666. *p_buf = buf;
  2667. return true;
  2668. fail:
  2669. return false;
  2670. }
  2671. static bool
  2672. load_export_section(const uint8 *buf, const uint8 *buf_end, AOTModule *module,
  2673. bool is_load_from_file_buf, char *error_buf,
  2674. uint32 error_buf_size)
  2675. {
  2676. const uint8 *p = buf, *p_end = buf_end;
  2677. /* load export functions */
  2678. read_uint32(p, p_end, module->export_count);
  2679. if (module->export_count > 0
  2680. && !load_exports(&p, p_end, module, is_load_from_file_buf, error_buf,
  2681. error_buf_size))
  2682. return false;
  2683. if (p != p_end) {
  2684. set_error_buf(error_buf, error_buf_size, "invalid export section size");
  2685. return false;
  2686. }
  2687. return true;
  2688. fail:
  2689. return false;
  2690. }
  2691. static void *
  2692. get_data_section_addr(AOTModule *module, const char *section_name,
  2693. uint32 *p_data_size)
  2694. {
  2695. uint32 i;
  2696. AOTObjectDataSection *data_section = module->data_sections;
  2697. for (i = 0; i < module->data_section_count; i++, data_section++) {
  2698. if (!strcmp(data_section->name, section_name)) {
  2699. if (p_data_size)
  2700. *p_data_size = data_section->size;
  2701. return data_section->data;
  2702. }
  2703. }
  2704. return NULL;
  2705. }
  2706. const void *
  2707. aot_get_data_section_addr(AOTModule *module, const char *section_name,
  2708. uint32 *p_data_size)
  2709. {
  2710. return get_data_section_addr(module, section_name, p_data_size);
  2711. }
  2712. static void *
  2713. resolve_target_sym(const char *symbol, int32 *p_index)
  2714. {
  2715. uint32 i, num = 0;
  2716. SymbolMap *target_sym_map;
  2717. if (!(target_sym_map = get_target_symbol_map(&num)))
  2718. return NULL;
  2719. for (i = 0; i < num; i++) {
  2720. if (!strcmp(target_sym_map[i].symbol_name, symbol)
  2721. #if defined(_WIN32) || defined(_WIN32_)
  2722. /* In Win32, the symbol name of function added by
  2723. LLVMAddFunction() is prefixed by '_', ignore it */
  2724. || (strlen(symbol) > 1 && symbol[0] == '_'
  2725. && !strcmp(target_sym_map[i].symbol_name, symbol + 1))
  2726. #endif
  2727. ) {
  2728. *p_index = (int32)i;
  2729. return target_sym_map[i].symbol_addr;
  2730. }
  2731. }
  2732. return NULL;
  2733. }
  2734. static bool
  2735. is_literal_relocation(const char *reloc_sec_name)
  2736. {
  2737. return !strcmp(reloc_sec_name, ".rela.literal");
  2738. }
  2739. static bool
  2740. str2uint32(const char *buf, uint32 *p_res)
  2741. {
  2742. uint32 res = 0, val;
  2743. const char *buf_end = buf + 8;
  2744. char ch;
  2745. while (buf < buf_end) {
  2746. ch = *buf++;
  2747. if (ch >= '0' && ch <= '9')
  2748. val = ch - '0';
  2749. else if (ch >= 'a' && ch <= 'f')
  2750. val = ch - 'a' + 0xA;
  2751. else if (ch >= 'A' && ch <= 'F')
  2752. val = ch - 'A' + 0xA;
  2753. else
  2754. return false;
  2755. res = (res << 4) | val;
  2756. }
  2757. *p_res = res;
  2758. return true;
  2759. }
  2760. static bool
  2761. str2uint64(const char *buf, uint64 *p_res)
  2762. {
  2763. uint64 res = 0, val;
  2764. const char *buf_end = buf + 16;
  2765. char ch;
  2766. while (buf < buf_end) {
  2767. ch = *buf++;
  2768. if (ch >= '0' && ch <= '9')
  2769. val = ch - '0';
  2770. else if (ch >= 'a' && ch <= 'f')
  2771. val = ch - 'a' + 0xA;
  2772. else if (ch >= 'A' && ch <= 'F')
  2773. val = ch - 'A' + 0xA;
  2774. else
  2775. return false;
  2776. res = (res << 4) | val;
  2777. }
  2778. *p_res = res;
  2779. return true;
  2780. }
  2781. #define R_X86_64_GOTPCREL 9 /* 32 bit signed PC relative offset to GOT */
  2782. #define R_X86_64_GOTPCRELX 41 /* relaxable GOTPCREL */
  2783. #define R_X86_64_REX_GOTPCRELX 42 /* relaxable GOTPCREL with REX prefix */
  2784. static bool
  2785. is_text_section(const char *section_name)
  2786. {
  2787. return !strcmp(section_name, ".text") || !strcmp(section_name, ".ltext");
  2788. }
  2789. static bool
  2790. do_text_relocation(AOTModule *module, AOTRelocationGroup *group,
  2791. char *error_buf, uint32 error_buf_size)
  2792. {
  2793. bool is_literal = is_literal_relocation(group->section_name);
  2794. uint8 *aot_text = is_literal ? module->literal : module->code;
  2795. uint32 aot_text_size =
  2796. is_literal ? module->literal_size : module->code_size;
  2797. uint32 i, func_index, symbol_len;
  2798. #if defined(BH_PLATFORM_WINDOWS)
  2799. uint32 ymm_plt_index = 0, xmm_plt_index = 0;
  2800. uint32 real_plt_index = 0, float_plt_index = 0, j;
  2801. #endif
  2802. char symbol_buf[128] = { 0 }, *symbol, *p;
  2803. void *symbol_addr;
  2804. AOTRelocation *relocation = group->relocations;
  2805. if (group->relocation_count > 0 && !aot_text) {
  2806. set_error_buf(error_buf, error_buf_size,
  2807. "invalid text relocation count");
  2808. return false;
  2809. }
  2810. for (i = 0; i < group->relocation_count; i++, relocation++) {
  2811. int32 symbol_index = -1;
  2812. symbol_len = (uint32)strlen(relocation->symbol_name);
  2813. if (symbol_len + 1 <= sizeof(symbol_buf))
  2814. symbol = symbol_buf;
  2815. else {
  2816. if (!(symbol = loader_malloc(symbol_len + 1, error_buf,
  2817. error_buf_size))) {
  2818. return false;
  2819. }
  2820. }
  2821. bh_memcpy_s(symbol, symbol_len, relocation->symbol_name, symbol_len);
  2822. symbol[symbol_len] = '\0';
  2823. #if WASM_ENABLE_STATIC_PGO != 0
  2824. if (!strcmp(symbol, "__llvm_profile_runtime")
  2825. || !strcmp(symbol, "__llvm_profile_register_function")
  2826. || !strcmp(symbol, "__llvm_profile_register_names_function")) {
  2827. continue;
  2828. }
  2829. #endif
  2830. if (!strncmp(symbol, AOT_FUNC_PREFIX, strlen(AOT_FUNC_PREFIX))) {
  2831. p = symbol + strlen(AOT_FUNC_PREFIX);
  2832. if (*p == '\0'
  2833. || (func_index = (uint32)atoi(p)) > module->func_count) {
  2834. set_error_buf_v(error_buf, error_buf_size,
  2835. "invalid import symbol %s", symbol);
  2836. goto check_symbol_fail;
  2837. }
  2838. #if (defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)) \
  2839. && !defined(BH_PLATFORM_WINDOWS)
  2840. if (relocation->relocation_type == R_X86_64_GOTPCREL
  2841. || relocation->relocation_type == R_X86_64_GOTPCRELX
  2842. || relocation->relocation_type == R_X86_64_REX_GOTPCRELX) {
  2843. GOTItem *got_item = module->got_item_list;
  2844. uint32 got_item_idx = 0;
  2845. while (got_item) {
  2846. if (got_item->func_idx == func_index)
  2847. break;
  2848. got_item_idx++;
  2849. got_item = got_item->next;
  2850. }
  2851. /* Calculate `GOT + G` */
  2852. symbol_addr = module->got_func_ptrs + got_item_idx;
  2853. }
  2854. else
  2855. symbol_addr = module->func_ptrs[func_index];
  2856. #else
  2857. symbol_addr = module->func_ptrs[func_index];
  2858. #endif
  2859. }
  2860. #if defined(BH_PLATFORM_WINDOWS) && defined(BUILD_TARGET_X86_32)
  2861. /* AOT function name starts with '_' in windows x86-32 */
  2862. else if (!strncmp(symbol, "_" AOT_FUNC_PREFIX,
  2863. strlen("_" AOT_FUNC_PREFIX))) {
  2864. p = symbol + strlen("_" AOT_FUNC_PREFIX);
  2865. if (*p == '\0'
  2866. || (func_index = (uint32)atoi(p)) > module->func_count) {
  2867. set_error_buf_v(error_buf, error_buf_size, "invalid symbol %s",
  2868. symbol);
  2869. goto check_symbol_fail;
  2870. }
  2871. symbol_addr = module->func_ptrs[func_index];
  2872. }
  2873. else if (!strncmp(symbol, "_" AOT_FUNC_INTERNAL_PREFIX,
  2874. strlen("_" AOT_FUNC_INTERNAL_PREFIX))) {
  2875. p = symbol + strlen("_" AOT_FUNC_INTERNAL_PREFIX);
  2876. if (*p == '\0'
  2877. || (func_index = (uint32)atoi(p)) > module->func_count) {
  2878. set_error_buf_v(error_buf, error_buf_size, "invalid symbol %s",
  2879. symbol);
  2880. goto check_symbol_fail;
  2881. }
  2882. symbol_addr = module->func_ptrs[func_index];
  2883. }
  2884. #endif
  2885. else if (is_text_section(symbol)) {
  2886. symbol_addr = module->code;
  2887. }
  2888. else if (!strcmp(symbol, ".data") || !strcmp(symbol, ".sdata")
  2889. || !strcmp(symbol, ".rdata") || !strcmp(symbol, ".rodata")
  2890. || !strcmp(symbol, ".srodata")
  2891. /* ".rodata.cst4/8/16/.." */
  2892. || !strncmp(symbol, ".rodata.cst", strlen(".rodata.cst"))
  2893. /* ".srodata.cst4/8/16/.." */
  2894. || !strncmp(symbol, ".srodata.cst", strlen(".srodata.cst"))
  2895. /* ".rodata.strn.m" */
  2896. || !strncmp(symbol, ".rodata.str", strlen(".rodata.str"))
  2897. || !strcmp(symbol, AOT_STACK_SIZES_SECTION_NAME)
  2898. #if WASM_ENABLE_STATIC_PGO != 0
  2899. || !strncmp(symbol, "__llvm_prf_cnts", 15)
  2900. || !strncmp(symbol, "__llvm_prf_data", 15)
  2901. || !strncmp(symbol, "__llvm_prf_names", 16)
  2902. #endif
  2903. ) {
  2904. symbol_addr = get_data_section_addr(module, symbol, NULL);
  2905. if (!symbol_addr) {
  2906. set_error_buf_v(error_buf, error_buf_size,
  2907. "invalid data section (%s)", symbol);
  2908. goto check_symbol_fail;
  2909. }
  2910. }
  2911. else if (!strcmp(symbol, ".literal")) {
  2912. symbol_addr = module->literal;
  2913. }
  2914. #if defined(BH_PLATFORM_WINDOWS)
  2915. /* Relocation for symbols which start with "__ymm@", "__xmm@" or
  2916. "__real@" and end with the ymm value, xmm value or real value.
  2917. In Windows PE file, the data is stored in some individual ".rdata"
  2918. sections. We simply create extra plt data, parse the values from
  2919. the symbols and stored them into the extra plt data. */
  2920. else if (!strcmp(group->section_name, ".text")
  2921. && !strncmp(symbol, YMM_PLT_PREFIX, strlen(YMM_PLT_PREFIX))
  2922. && strlen(symbol) == strlen(YMM_PLT_PREFIX) + 64) {
  2923. char ymm_buf[17] = { 0 };
  2924. symbol_addr = module->extra_plt_data + ymm_plt_index * 32;
  2925. for (j = 0; j < 4; j++) {
  2926. bh_memcpy_s(ymm_buf, sizeof(ymm_buf),
  2927. symbol + strlen(YMM_PLT_PREFIX) + 48 - 16 * j, 16);
  2928. if (!str2uint64(ymm_buf,
  2929. (uint64 *)((uint8 *)symbol_addr + 8 * j))) {
  2930. set_error_buf_v(error_buf, error_buf_size,
  2931. "resolve symbol %s failed", symbol);
  2932. goto check_symbol_fail;
  2933. }
  2934. }
  2935. ymm_plt_index++;
  2936. }
  2937. else if (!strcmp(group->section_name, ".text")
  2938. && !strncmp(symbol, XMM_PLT_PREFIX, strlen(XMM_PLT_PREFIX))
  2939. && strlen(symbol) == strlen(XMM_PLT_PREFIX) + 32) {
  2940. char xmm_buf[17] = { 0 };
  2941. symbol_addr = module->extra_plt_data + module->ymm_plt_count * 32
  2942. + xmm_plt_index * 16;
  2943. for (j = 0; j < 2; j++) {
  2944. bh_memcpy_s(xmm_buf, sizeof(xmm_buf),
  2945. symbol + strlen(XMM_PLT_PREFIX) + 16 - 16 * j, 16);
  2946. if (!str2uint64(xmm_buf,
  2947. (uint64 *)((uint8 *)symbol_addr + 8 * j))) {
  2948. set_error_buf_v(error_buf, error_buf_size,
  2949. "resolve symbol %s failed", symbol);
  2950. goto check_symbol_fail;
  2951. }
  2952. }
  2953. xmm_plt_index++;
  2954. }
  2955. else if (!strcmp(group->section_name, ".text")
  2956. && !strncmp(symbol, REAL_PLT_PREFIX, strlen(REAL_PLT_PREFIX))
  2957. && strlen(symbol) == strlen(REAL_PLT_PREFIX) + 16) {
  2958. char real_buf[17] = { 0 };
  2959. symbol_addr = module->extra_plt_data + module->ymm_plt_count * 32
  2960. + module->xmm_plt_count * 16 + real_plt_index * 8;
  2961. bh_memcpy_s(real_buf, sizeof(real_buf),
  2962. symbol + strlen(REAL_PLT_PREFIX), 16);
  2963. if (!str2uint64(real_buf, (uint64 *)symbol_addr)) {
  2964. set_error_buf_v(error_buf, error_buf_size,
  2965. "resolve symbol %s failed", symbol);
  2966. goto check_symbol_fail;
  2967. }
  2968. real_plt_index++;
  2969. }
  2970. else if (!strcmp(group->section_name, ".text")
  2971. && !strncmp(symbol, REAL_PLT_PREFIX, strlen(REAL_PLT_PREFIX))
  2972. && strlen(symbol) == strlen(REAL_PLT_PREFIX) + 8) {
  2973. char float_buf[9] = { 0 };
  2974. symbol_addr = module->extra_plt_data + module->ymm_plt_count * 32
  2975. + module->xmm_plt_count * 16
  2976. + module->real_plt_count * 8 + float_plt_index * 4;
  2977. bh_memcpy_s(float_buf, sizeof(float_buf),
  2978. symbol + strlen(REAL_PLT_PREFIX), 8);
  2979. if (!str2uint32(float_buf, (uint32 *)symbol_addr)) {
  2980. set_error_buf_v(error_buf, error_buf_size,
  2981. "resolve symbol %s failed", symbol);
  2982. goto check_symbol_fail;
  2983. }
  2984. float_plt_index++;
  2985. }
  2986. #endif /* end of defined(BH_PLATFORM_WINDOWS) */
  2987. else if (!(symbol_addr = resolve_target_sym(symbol, &symbol_index))) {
  2988. set_error_buf_v(error_buf, error_buf_size,
  2989. "resolve symbol %s failed", symbol);
  2990. goto check_symbol_fail;
  2991. }
  2992. if (symbol != symbol_buf)
  2993. wasm_runtime_free(symbol);
  2994. if (!apply_relocation(
  2995. module, aot_text, aot_text_size, relocation->relocation_offset,
  2996. relocation->relocation_addend, relocation->relocation_type,
  2997. symbol_addr, symbol_index, error_buf, error_buf_size))
  2998. return false;
  2999. }
  3000. return true;
  3001. check_symbol_fail:
  3002. if (symbol != symbol_buf)
  3003. wasm_runtime_free(symbol);
  3004. return false;
  3005. }
  3006. static bool
  3007. do_data_relocation(AOTModule *module, AOTRelocationGroup *group,
  3008. char *error_buf, uint32 error_buf_size)
  3009. {
  3010. uint8 *data_addr;
  3011. uint32 data_size = 0, i;
  3012. AOTRelocation *relocation = group->relocations;
  3013. void *symbol_addr = NULL;
  3014. char *symbol, *data_section_name;
  3015. if (!strncmp(group->section_name, ".rela.", 6)) {
  3016. data_section_name = group->section_name + strlen(".rela");
  3017. }
  3018. else if (!strncmp(group->section_name, ".rel.", 5)) {
  3019. data_section_name = group->section_name + strlen(".rel");
  3020. }
  3021. else if (!strcmp(group->section_name, ".rdata")) {
  3022. data_section_name = group->section_name;
  3023. }
  3024. #if WASM_ENABLE_STATIC_PGO != 0
  3025. else if (!strncmp(group->section_name, ".rel__llvm_prf_data", 19)) {
  3026. data_section_name = group->section_name + strlen(".rel");
  3027. }
  3028. else if (!strncmp(group->section_name, ".rela__llvm_prf_data", 20)) {
  3029. data_section_name = group->section_name + strlen(".rela");
  3030. }
  3031. #endif
  3032. else {
  3033. set_error_buf(error_buf, error_buf_size,
  3034. "invalid data relocation section name");
  3035. return false;
  3036. }
  3037. data_addr = get_data_section_addr(module, data_section_name, &data_size);
  3038. if (group->relocation_count > 0 && !data_addr) {
  3039. set_error_buf(error_buf, error_buf_size,
  3040. "invalid data relocation count");
  3041. return false;
  3042. }
  3043. for (i = 0; i < group->relocation_count; i++, relocation++) {
  3044. symbol = relocation->symbol_name;
  3045. if (is_text_section(symbol)) {
  3046. symbol_addr = module->code;
  3047. }
  3048. #if WASM_ENABLE_STATIC_PGO != 0
  3049. else if (!strncmp(symbol, AOT_FUNC_PREFIX, strlen(AOT_FUNC_PREFIX))) {
  3050. char *p = symbol + strlen(AOT_FUNC_PREFIX);
  3051. uint32 func_index;
  3052. if (*p == '\0'
  3053. || (func_index = (uint32)atoi(p)) > module->func_count) {
  3054. set_error_buf_v(error_buf, error_buf_size,
  3055. "invalid relocation symbol %s", symbol);
  3056. return false;
  3057. }
  3058. symbol_addr = module->func_ptrs[func_index];
  3059. }
  3060. else if (!strcmp(symbol, "__llvm_prf_cnts")) {
  3061. uint32 j;
  3062. for (j = 0; j < module->data_section_count; j++) {
  3063. if (!strncmp(module->data_sections[j].name, symbol, 15)) {
  3064. bh_assert(relocation->relocation_addend + sizeof(uint64)
  3065. <= module->data_sections[j].size);
  3066. symbol_addr = module->data_sections[j].data;
  3067. break;
  3068. }
  3069. }
  3070. if (j == module->data_section_count) {
  3071. set_error_buf_v(error_buf, error_buf_size,
  3072. "invalid relocation symbol %s", symbol);
  3073. return false;
  3074. }
  3075. }
  3076. else if (!strncmp(symbol, "__llvm_prf_cnts", 15)) {
  3077. uint32 j;
  3078. for (j = 0; j < module->data_section_count; j++) {
  3079. if (!strcmp(module->data_sections[j].name, symbol)) {
  3080. symbol_addr = module->data_sections[j].data;
  3081. break;
  3082. }
  3083. }
  3084. if (j == module->data_section_count) {
  3085. set_error_buf_v(error_buf, error_buf_size,
  3086. "invalid relocation symbol %s", symbol);
  3087. return false;
  3088. }
  3089. }
  3090. #endif /* end of WASM_ENABLE_STATIC_PGO != 0 */
  3091. else {
  3092. set_error_buf_v(error_buf, error_buf_size,
  3093. "invalid relocation symbol %s", symbol);
  3094. return false;
  3095. }
  3096. if (!apply_relocation(
  3097. module, data_addr, data_size, relocation->relocation_offset,
  3098. relocation->relocation_addend, relocation->relocation_type,
  3099. symbol_addr, -1, error_buf, error_buf_size))
  3100. return false;
  3101. }
  3102. return true;
  3103. }
  3104. static bool
  3105. validate_symbol_table(uint8 *buf, uint8 *buf_end, uint32 *offsets, uint32 count,
  3106. char *error_buf, uint32 error_buf_size)
  3107. {
  3108. uint32 i, str_len_addr = 0;
  3109. uint16 str_len;
  3110. for (i = 0; i < count; i++) {
  3111. if (offsets[i] != str_len_addr)
  3112. return false;
  3113. read_uint16(buf, buf_end, str_len);
  3114. str_len_addr += (uint32)sizeof(uint16) + str_len;
  3115. str_len_addr = align_uint(str_len_addr, 2);
  3116. buf += str_len;
  3117. buf = (uint8 *)align_ptr(buf, 2);
  3118. }
  3119. if (buf == buf_end)
  3120. return true;
  3121. fail:
  3122. return false;
  3123. }
  3124. static bool
  3125. load_relocation_section(const uint8 *buf, const uint8 *buf_end,
  3126. AOTModule *module, bool is_load_from_file_buf,
  3127. char *error_buf, uint32 error_buf_size)
  3128. {
  3129. AOTRelocationGroup *groups = NULL, *group;
  3130. uint32 symbol_count = 0;
  3131. uint32 group_count = 0, i, j, got_item_count = 0;
  3132. uint64 size;
  3133. uint32 *symbol_offsets, total_string_len;
  3134. uint8 *symbol_buf, *symbol_buf_end;
  3135. int map_prot, map_flags;
  3136. bool ret = false;
  3137. char **symbols = NULL;
  3138. read_uint32(buf, buf_end, symbol_count);
  3139. symbol_offsets = (uint32 *)buf;
  3140. for (i = 0; i < symbol_count; i++) {
  3141. CHECK_BUF(buf, buf_end, sizeof(uint32));
  3142. buf += sizeof(uint32);
  3143. }
  3144. read_uint32(buf, buf_end, total_string_len);
  3145. symbol_buf = (uint8 *)buf;
  3146. symbol_buf_end = symbol_buf + total_string_len;
  3147. if (!validate_symbol_table(symbol_buf, symbol_buf_end, symbol_offsets,
  3148. symbol_count, error_buf, error_buf_size)) {
  3149. set_error_buf(error_buf, error_buf_size,
  3150. "validate symbol table failed");
  3151. goto fail;
  3152. }
  3153. if (symbol_count > 0) {
  3154. symbols = loader_malloc((uint64)sizeof(*symbols) * symbol_count,
  3155. error_buf, error_buf_size);
  3156. if (symbols == NULL) {
  3157. goto fail;
  3158. }
  3159. }
  3160. #if defined(BH_PLATFORM_WINDOWS)
  3161. buf = symbol_buf_end;
  3162. read_uint32(buf, buf_end, group_count);
  3163. for (i = 0; i < group_count; i++) {
  3164. uint32 name_index, relocation_count;
  3165. uint16 group_name_len;
  3166. uint8 *group_name;
  3167. /* section name address is 4 bytes aligned. */
  3168. buf = (uint8 *)align_ptr(buf, sizeof(uint32));
  3169. read_uint32(buf, buf_end, name_index);
  3170. if (name_index >= symbol_count) {
  3171. set_error_buf(error_buf, error_buf_size,
  3172. "symbol index out of range");
  3173. goto fail;
  3174. }
  3175. group_name = symbol_buf + symbol_offsets[name_index];
  3176. group_name_len = *(uint16 *)group_name;
  3177. group_name += sizeof(uint16);
  3178. read_uint32(buf, buf_end, relocation_count);
  3179. for (j = 0; j < relocation_count; j++) {
  3180. AOTRelocation relocation = { 0 };
  3181. char group_name_buf[128] = { 0 };
  3182. char symbol_name_buf[128] = { 0 };
  3183. uint32 symbol_index, offset32;
  3184. int32 addend32;
  3185. uint16 symbol_name_len;
  3186. uint8 *symbol_name;
  3187. if (sizeof(void *) == 8) {
  3188. read_uint64(buf, buf_end, relocation.relocation_offset);
  3189. read_uint64(buf, buf_end, relocation.relocation_addend);
  3190. }
  3191. else {
  3192. read_uint32(buf, buf_end, offset32);
  3193. relocation.relocation_offset = (uint64)offset32;
  3194. read_uint32(buf, buf_end, addend32);
  3195. relocation.relocation_addend = (int64)addend32;
  3196. }
  3197. read_uint32(buf, buf_end, relocation.relocation_type);
  3198. read_uint32(buf, buf_end, symbol_index);
  3199. if (symbol_index >= symbol_count) {
  3200. set_error_buf(error_buf, error_buf_size,
  3201. "symbol index out of range");
  3202. goto fail;
  3203. }
  3204. symbol_name = symbol_buf + symbol_offsets[symbol_index];
  3205. symbol_name_len = *(uint16 *)symbol_name;
  3206. symbol_name += sizeof(uint16);
  3207. bh_memcpy_s(group_name_buf, (uint32)sizeof(group_name_buf),
  3208. group_name, group_name_len);
  3209. bh_memcpy_s(symbol_name_buf, (uint32)sizeof(symbol_name_buf),
  3210. symbol_name, symbol_name_len);
  3211. /* aot compiler emits string with '\0' since 2.0.0 */
  3212. if (group_name_len == strlen(".text") + 1
  3213. && !strncmp(group_name, ".text", strlen(".text"))) {
  3214. /* aot compiler emits string with '\0' since 2.0.0 */
  3215. if (symbol_name_len == strlen(YMM_PLT_PREFIX) + 64 + 1
  3216. && !strncmp(symbol_name, YMM_PLT_PREFIX,
  3217. strlen(YMM_PLT_PREFIX))) {
  3218. module->ymm_plt_count++;
  3219. }
  3220. else if (symbol_name_len == strlen(XMM_PLT_PREFIX) + 32 + 1
  3221. && !strncmp(symbol_name, XMM_PLT_PREFIX,
  3222. strlen(XMM_PLT_PREFIX))) {
  3223. module->xmm_plt_count++;
  3224. }
  3225. else if (symbol_name_len == strlen(REAL_PLT_PREFIX) + 16 + 1
  3226. && !strncmp(symbol_name, REAL_PLT_PREFIX,
  3227. strlen(REAL_PLT_PREFIX))) {
  3228. module->real_plt_count++;
  3229. }
  3230. else if (symbol_name_len >= strlen(REAL_PLT_PREFIX) + 8 + 1
  3231. && !strncmp(symbol_name, REAL_PLT_PREFIX,
  3232. strlen(REAL_PLT_PREFIX))) {
  3233. module->float_plt_count++;
  3234. }
  3235. }
  3236. }
  3237. }
  3238. /* Allocate memory for extra plt data */
  3239. size = sizeof(uint64) * 4 * module->ymm_plt_count
  3240. + sizeof(uint64) * 2 * module->xmm_plt_count
  3241. + sizeof(uint64) * module->real_plt_count
  3242. + sizeof(uint32) * module->float_plt_count;
  3243. if (size > 0) {
  3244. if (size > UINT32_MAX
  3245. || !(module->extra_plt_data = loader_mmap(
  3246. (uint32)size, true, error_buf, error_buf_size))) {
  3247. goto fail;
  3248. }
  3249. module->extra_plt_data_size = (uint32)size;
  3250. }
  3251. #endif /* end of defined(BH_PLATFORM_WINDOWS) */
  3252. #if (defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)) \
  3253. && !defined(BH_PLATFORM_WINDOWS)
  3254. buf = symbol_buf_end;
  3255. read_uint32(buf, buf_end, group_count);
  3256. /* Resolve the relocations of type R_X86_64_GOTPCREL */
  3257. for (i = 0; i < group_count; i++) {
  3258. uint32 name_index, relocation_count;
  3259. uint16 group_name_len;
  3260. uint8 *group_name;
  3261. /* section name address is 4 bytes aligned. */
  3262. buf = (uint8 *)align_ptr(buf, sizeof(uint32));
  3263. read_uint32(buf, buf_end, name_index);
  3264. if (name_index >= symbol_count) {
  3265. set_error_buf(error_buf, error_buf_size,
  3266. "symbol index out of range");
  3267. goto fail;
  3268. }
  3269. group_name = symbol_buf + symbol_offsets[name_index];
  3270. group_name_len = *(uint16 *)group_name;
  3271. group_name += sizeof(uint16);
  3272. read_uint32(buf, buf_end, relocation_count);
  3273. for (j = 0; j < relocation_count; j++) {
  3274. AOTRelocation relocation = { 0 };
  3275. char group_name_buf[128] = { 0 };
  3276. char symbol_name_buf[128] = { 0 };
  3277. uint32 symbol_index;
  3278. uint16 symbol_name_len;
  3279. uint8 *symbol_name;
  3280. /* relocation offset and addend */
  3281. buf += sizeof(void *) * 2;
  3282. read_uint32(buf, buf_end, relocation.relocation_type);
  3283. read_uint32(buf, buf_end, symbol_index);
  3284. if (symbol_index >= symbol_count) {
  3285. set_error_buf(error_buf, error_buf_size,
  3286. "symbol index out of range");
  3287. goto fail;
  3288. }
  3289. symbol_name = symbol_buf + symbol_offsets[symbol_index];
  3290. symbol_name_len = *(uint16 *)symbol_name;
  3291. symbol_name += sizeof(uint16);
  3292. bh_memcpy_s(group_name_buf, (uint32)sizeof(group_name_buf),
  3293. group_name, group_name_len);
  3294. bh_memcpy_s(symbol_name_buf, (uint32)sizeof(symbol_name_buf),
  3295. symbol_name, symbol_name_len);
  3296. if ((relocation.relocation_type == R_X86_64_GOTPCREL
  3297. || relocation.relocation_type == R_X86_64_GOTPCRELX
  3298. || relocation.relocation_type == R_X86_64_REX_GOTPCRELX)
  3299. && !strncmp(symbol_name_buf, AOT_FUNC_PREFIX,
  3300. strlen(AOT_FUNC_PREFIX))) {
  3301. uint32 func_idx =
  3302. atoi(symbol_name_buf + strlen(AOT_FUNC_PREFIX));
  3303. GOTItem *got_item = module->got_item_list;
  3304. if (func_idx >= module->func_count) {
  3305. set_error_buf(error_buf, error_buf_size,
  3306. "func index out of range");
  3307. goto fail;
  3308. }
  3309. while (got_item) {
  3310. if (got_item->func_idx == func_idx)
  3311. break;
  3312. got_item = got_item->next;
  3313. }
  3314. if (!got_item) {
  3315. /* Create the got item and append to the list */
  3316. got_item = wasm_runtime_malloc(sizeof(GOTItem));
  3317. if (!got_item) {
  3318. set_error_buf(error_buf, error_buf_size,
  3319. "allocate memory failed");
  3320. goto fail;
  3321. }
  3322. got_item->func_idx = func_idx;
  3323. got_item->next = NULL;
  3324. if (!module->got_item_list) {
  3325. module->got_item_list = module->got_item_list_end =
  3326. got_item;
  3327. }
  3328. else {
  3329. module->got_item_list_end->next = got_item;
  3330. module->got_item_list_end = got_item;
  3331. }
  3332. got_item_count++;
  3333. }
  3334. }
  3335. }
  3336. }
  3337. if (got_item_count) {
  3338. GOTItem *got_item = module->got_item_list;
  3339. uint32 got_item_idx = 0;
  3340. /* Create the GOT for func_ptrs, note that it is different from
  3341. the .got section of a dynamic object file */
  3342. size = (uint64)sizeof(void *) * got_item_count;
  3343. if (size > UINT32_MAX
  3344. || !(module->got_func_ptrs = loader_mmap(
  3345. (uint32)size, false, error_buf, error_buf_size))) {
  3346. goto fail;
  3347. }
  3348. while (got_item) {
  3349. module->got_func_ptrs[got_item_idx++] =
  3350. module->func_ptrs[got_item->func_idx];
  3351. got_item = got_item->next;
  3352. }
  3353. module->got_item_count = got_item_count;
  3354. }
  3355. #else
  3356. (void)got_item_count;
  3357. #endif /* (defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)) && \
  3358. !defined(BH_PLATFORM_WINDOWS) */
  3359. buf = symbol_buf_end;
  3360. read_uint32(buf, buf_end, group_count);
  3361. /* Allocate memory for relocation groups */
  3362. size = sizeof(AOTRelocationGroup) * (uint64)group_count;
  3363. if (size > 0
  3364. && !(groups = loader_malloc(size, error_buf, error_buf_size))) {
  3365. goto fail;
  3366. }
  3367. /* Load each relocation group */
  3368. for (i = 0, group = groups; i < group_count; i++, group++) {
  3369. AOTRelocation *relocation;
  3370. uint32 name_index;
  3371. /* section name address is 4 bytes aligned. */
  3372. buf = (uint8 *)align_ptr(buf, sizeof(uint32));
  3373. read_uint32(buf, buf_end, name_index);
  3374. if (name_index >= symbol_count) {
  3375. set_error_buf(error_buf, error_buf_size,
  3376. "symbol index out of range");
  3377. goto fail;
  3378. }
  3379. if (symbols[name_index] == NULL) {
  3380. uint8 *name_addr = symbol_buf + symbol_offsets[name_index];
  3381. read_string(name_addr, buf_end, symbols[name_index]);
  3382. }
  3383. group->section_name = symbols[name_index];
  3384. read_uint32(buf, buf_end, group->relocation_count);
  3385. /* Allocate memory for relocations */
  3386. size = sizeof(AOTRelocation) * (uint64)group->relocation_count;
  3387. if (!(group->relocations = relocation =
  3388. loader_malloc(size, error_buf, error_buf_size))) {
  3389. ret = false;
  3390. goto fail;
  3391. }
  3392. /* Load each relocation */
  3393. for (j = 0; j < group->relocation_count; j++, relocation++) {
  3394. uint32 symbol_index;
  3395. if (sizeof(void *) == 8) {
  3396. read_uint64(buf, buf_end, relocation->relocation_offset);
  3397. read_uint64(buf, buf_end, relocation->relocation_addend);
  3398. }
  3399. else {
  3400. uint32 offset32, addend32;
  3401. read_uint32(buf, buf_end, offset32);
  3402. relocation->relocation_offset = (uint64)offset32;
  3403. read_uint32(buf, buf_end, addend32);
  3404. relocation->relocation_addend = (uint64)addend32;
  3405. }
  3406. read_uint32(buf, buf_end, relocation->relocation_type);
  3407. read_uint32(buf, buf_end, symbol_index);
  3408. if (symbol_index >= symbol_count) {
  3409. set_error_buf(error_buf, error_buf_size,
  3410. "symbol index out of range");
  3411. goto fail;
  3412. }
  3413. if (symbols[symbol_index] == NULL) {
  3414. uint8 *symbol_addr = symbol_buf + symbol_offsets[symbol_index];
  3415. read_string(symbol_addr, buf_end, symbols[symbol_index]);
  3416. }
  3417. relocation->symbol_name = symbols[symbol_index];
  3418. }
  3419. if (!strcmp(group->section_name, ".rel.text")
  3420. || !strcmp(group->section_name, ".rela.text")
  3421. || !strcmp(group->section_name, ".rel.ltext")
  3422. || !strcmp(group->section_name, ".rela.ltext")
  3423. || !strcmp(group->section_name, ".rela.literal")
  3424. #ifdef BH_PLATFORM_WINDOWS
  3425. || !strcmp(group->section_name, ".text")
  3426. #endif
  3427. ) {
  3428. #if !defined(BH_PLATFORM_LINUX) && !defined(BH_PLATFORM_LINUX_SGX) \
  3429. && !defined(BH_PLATFORM_DARWIN) && !defined(BH_PLATFORM_WINDOWS) \
  3430. && !defined(BH_PLATFORM_ANDROID)
  3431. if (module->is_indirect_mode) {
  3432. set_error_buf(error_buf, error_buf_size,
  3433. "cannot apply relocation to text section "
  3434. "for aot file generated with "
  3435. "\"--enable-indirect-mode\" flag");
  3436. goto fail;
  3437. }
  3438. #endif
  3439. if (!do_text_relocation(module, group, error_buf, error_buf_size))
  3440. goto fail;
  3441. }
  3442. else {
  3443. if (!do_data_relocation(module, group, error_buf, error_buf_size))
  3444. goto fail;
  3445. }
  3446. }
  3447. /* Set read only for AOT code and some data sections */
  3448. map_prot = MMAP_PROT_READ | MMAP_PROT_EXEC;
  3449. if (module->code) {
  3450. /* The layout is: literal size + literal + code (with plt table) */
  3451. uint8 *mmap_addr = module->literal - sizeof(uint32);
  3452. uint32 total_size =
  3453. sizeof(uint32) + module->literal_size + module->code_size;
  3454. os_mprotect(mmap_addr, total_size, map_prot);
  3455. }
  3456. map_prot = MMAP_PROT_READ;
  3457. #if defined(BH_PLATFORM_WINDOWS)
  3458. if (module->extra_plt_data) {
  3459. os_mprotect(module->extra_plt_data, module->extra_plt_data_size,
  3460. map_prot);
  3461. }
  3462. #endif
  3463. for (i = 0; i < module->data_section_count; i++) {
  3464. AOTObjectDataSection *data_section = module->data_sections + i;
  3465. if (!strcmp(data_section->name, ".rdata")
  3466. || !strcmp(data_section->name, ".rodata")
  3467. /* ".rodata.cst4/8/16/.." */
  3468. || !strncmp(data_section->name, ".rodata.cst",
  3469. strlen(".rodata.cst"))
  3470. /* ".rodata.strn.m" */
  3471. || !strncmp(data_section->name, ".rodata.str",
  3472. strlen(".rodata.str"))) {
  3473. os_mprotect(data_section->data, data_section->size, map_prot);
  3474. }
  3475. }
  3476. ret = true;
  3477. fail:
  3478. if (symbols) {
  3479. wasm_runtime_free(symbols);
  3480. }
  3481. if (groups) {
  3482. for (i = 0, group = groups; i < group_count; i++, group++)
  3483. if (group->relocations)
  3484. wasm_runtime_free(group->relocations);
  3485. wasm_runtime_free(groups);
  3486. }
  3487. (void)map_flags;
  3488. return ret;
  3489. }
  3490. #if WASM_ENABLE_MEMORY64 != 0
  3491. static bool
  3492. has_module_memory64(AOTModule *module)
  3493. {
  3494. /* TODO: multi-memories for now assuming the memory idx type is consistent
  3495. * across multi-memories */
  3496. if (module->import_memory_count > 0)
  3497. return !!(module->import_memories[0].mem_type.flags & MEMORY64_FLAG);
  3498. else if (module->memory_count > 0)
  3499. return !!(module->memories[0].flags & MEMORY64_FLAG);
  3500. return false;
  3501. }
  3502. #endif
  3503. static bool
  3504. load_from_sections(AOTModule *module, AOTSection *sections,
  3505. bool is_load_from_file_buf, bool no_resolve, char *error_buf,
  3506. uint32 error_buf_size)
  3507. {
  3508. AOTSection *section = sections;
  3509. const uint8 *buf, *buf_end;
  3510. uint32 last_section_type = (uint32)-1, section_type;
  3511. uint32 i, func_index, func_type_index;
  3512. AOTFuncType *func_type;
  3513. AOTExport *exports;
  3514. uint8 malloc_free_io_type = VALUE_TYPE_I32;
  3515. while (section) {
  3516. buf = section->section_body;
  3517. buf_end = buf + section->section_body_size;
  3518. /* Check sections */
  3519. section_type = (uint32)section->section_type;
  3520. if ((last_section_type == (uint32)-1
  3521. && section_type != AOT_SECTION_TYPE_TARGET_INFO)
  3522. || (last_section_type != (uint32)-1
  3523. && (section_type != last_section_type + 1
  3524. && section_type != AOT_SECTION_TYPE_CUSTOM))) {
  3525. set_error_buf(error_buf, error_buf_size, "invalid section order");
  3526. return false;
  3527. }
  3528. last_section_type = section_type;
  3529. switch (section_type) {
  3530. case AOT_SECTION_TYPE_TARGET_INFO:
  3531. if (!load_target_info_section(buf, buf_end, module, error_buf,
  3532. error_buf_size))
  3533. return false;
  3534. break;
  3535. case AOT_SECTION_TYPE_INIT_DATA:
  3536. if (!load_init_data_section(buf, buf_end, module,
  3537. is_load_from_file_buf, no_resolve,
  3538. error_buf, error_buf_size))
  3539. return false;
  3540. break;
  3541. case AOT_SECTION_TYPE_TEXT:
  3542. #if !defined(BH_PLATFORM_NUTTX) && !defined(BH_PLATFORM_ESP_IDF)
  3543. /* try to merge .data and .text, with exceptions:
  3544. * 1. XIP mode
  3545. * 2. pre-mmapped module load from aot_load_from_sections()
  3546. * 3. nuttx & esp-idf: have separate region for MMAP_PROT_EXEC
  3547. */
  3548. if (!module->is_indirect_mode && is_load_from_file_buf)
  3549. if (!try_merge_data_and_text(&buf, &buf_end, module,
  3550. error_buf, error_buf_size))
  3551. LOG_WARNING("merge .data and .text sections failed");
  3552. #endif /* ! defined(BH_PLATFORM_NUTTX) && !defined(BH_PLATFORM_ESP_IDF) */
  3553. if (!load_text_section(buf, buf_end, module, error_buf,
  3554. error_buf_size))
  3555. return false;
  3556. break;
  3557. case AOT_SECTION_TYPE_FUNCTION:
  3558. if (!load_function_section(buf, buf_end, module, error_buf,
  3559. error_buf_size))
  3560. return false;
  3561. break;
  3562. case AOT_SECTION_TYPE_EXPORT:
  3563. if (!load_export_section(buf, buf_end, module,
  3564. is_load_from_file_buf, error_buf,
  3565. error_buf_size))
  3566. return false;
  3567. break;
  3568. case AOT_SECTION_TYPE_RELOCATION:
  3569. if (!load_relocation_section(buf, buf_end, module,
  3570. is_load_from_file_buf, error_buf,
  3571. error_buf_size))
  3572. return false;
  3573. break;
  3574. case AOT_SECTION_TYPE_CUSTOM:
  3575. if (!load_custom_section(buf, buf_end, module,
  3576. is_load_from_file_buf, error_buf,
  3577. error_buf_size))
  3578. return false;
  3579. break;
  3580. default:
  3581. set_error_buf(error_buf, error_buf_size,
  3582. "invalid aot section type");
  3583. return false;
  3584. }
  3585. section = section->next;
  3586. }
  3587. if (last_section_type != AOT_SECTION_TYPE_RELOCATION
  3588. && last_section_type != AOT_SECTION_TYPE_CUSTOM) {
  3589. set_error_buf(error_buf, error_buf_size, "section missing");
  3590. return false;
  3591. }
  3592. /* Resolve malloc and free function */
  3593. module->malloc_func_index = (uint32)-1;
  3594. module->free_func_index = (uint32)-1;
  3595. module->retain_func_index = (uint32)-1;
  3596. #if WASM_ENABLE_MEMORY64 != 0
  3597. if (has_module_memory64(module))
  3598. malloc_free_io_type = VALUE_TYPE_I64;
  3599. #endif
  3600. exports = module->exports;
  3601. for (i = 0; i < module->export_count; i++) {
  3602. if (exports[i].kind == EXPORT_KIND_FUNC
  3603. && exports[i].index >= module->import_func_count) {
  3604. if (!strcmp(exports[i].name, "malloc")) {
  3605. func_index = exports[i].index - module->import_func_count;
  3606. func_type_index = module->func_type_indexes[func_index];
  3607. func_type = (AOTFuncType *)module->types[func_type_index];
  3608. if (func_type->param_count == 1 && func_type->result_count == 1
  3609. && func_type->types[0] == malloc_free_io_type
  3610. && func_type->types[1] == malloc_free_io_type) {
  3611. bh_assert(module->malloc_func_index == (uint32)-1);
  3612. module->malloc_func_index = func_index;
  3613. LOG_VERBOSE("Found malloc function, name: %s, index: %u",
  3614. exports[i].name, exports[i].index);
  3615. }
  3616. }
  3617. else if (!strcmp(exports[i].name, "__new")) {
  3618. func_index = exports[i].index - module->import_func_count;
  3619. func_type_index = module->func_type_indexes[func_index];
  3620. func_type = (AOTFuncType *)module->types[func_type_index];
  3621. if (func_type->param_count == 2 && func_type->result_count == 1
  3622. && func_type->types[0] == malloc_free_io_type
  3623. && func_type->types[1] == VALUE_TYPE_I32
  3624. && func_type->types[2] == malloc_free_io_type) {
  3625. uint32 j;
  3626. WASMExport *export_tmp;
  3627. bh_assert(module->malloc_func_index == (uint32)-1);
  3628. module->malloc_func_index = func_index;
  3629. LOG_VERBOSE("Found malloc function, name: %s, index: %u",
  3630. exports[i].name, exports[i].index);
  3631. /* resolve retain function.
  3632. If not find, reset malloc function index */
  3633. export_tmp = module->exports;
  3634. for (j = 0; j < module->export_count; j++, export_tmp++) {
  3635. if ((export_tmp->kind == EXPORT_KIND_FUNC)
  3636. && (!strcmp(export_tmp->name, "__retain")
  3637. || !strcmp(export_tmp->name, "__pin"))) {
  3638. func_index =
  3639. export_tmp->index - module->import_func_count;
  3640. func_type_index =
  3641. module->func_type_indexes[func_index];
  3642. func_type =
  3643. (AOTFuncType *)module->types[func_type_index];
  3644. if (func_type->param_count == 1
  3645. && func_type->result_count == 1
  3646. && func_type->types[0] == malloc_free_io_type
  3647. && func_type->types[1] == malloc_free_io_type) {
  3648. bh_assert(module->retain_func_index
  3649. == (uint32)-1);
  3650. module->retain_func_index = export_tmp->index;
  3651. LOG_VERBOSE("Found retain function, name: %s, "
  3652. "index: %u",
  3653. export_tmp->name,
  3654. export_tmp->index);
  3655. break;
  3656. }
  3657. }
  3658. }
  3659. if (j == module->export_count) {
  3660. module->malloc_func_index = (uint32)-1;
  3661. LOG_VERBOSE("Can't find retain function,"
  3662. "reset malloc function index to -1");
  3663. }
  3664. }
  3665. }
  3666. else if ((!strcmp(exports[i].name, "free"))
  3667. || (!strcmp(exports[i].name, "__release"))
  3668. || (!strcmp(exports[i].name, "__unpin"))) {
  3669. func_index = exports[i].index - module->import_func_count;
  3670. func_type_index = module->func_type_indexes[func_index];
  3671. func_type = (AOTFuncType *)module->types[func_type_index];
  3672. if (func_type->param_count == 1 && func_type->result_count == 0
  3673. && func_type->types[0] == malloc_free_io_type) {
  3674. bh_assert(module->free_func_index == (uint32)-1);
  3675. module->free_func_index = func_index;
  3676. LOG_VERBOSE("Found free function, name: %s, index: %u",
  3677. exports[i].name, exports[i].index);
  3678. }
  3679. }
  3680. }
  3681. }
  3682. /* Flush data cache before executing AOT code,
  3683. * otherwise unpredictable behavior can occur. */
  3684. os_dcache_flush();
  3685. #if WASM_ENABLE_MEMORY_TRACING != 0
  3686. wasm_runtime_dump_module_mem_consumption((WASMModuleCommon *)module);
  3687. #endif
  3688. #if WASM_ENABLE_DEBUG_AOT != 0
  3689. if (!jit_code_entry_create(module->elf_hdr, module->elf_size)) {
  3690. set_error_buf(error_buf, error_buf_size,
  3691. "create jit code entry failed");
  3692. return false;
  3693. }
  3694. #endif
  3695. return true;
  3696. }
  3697. static AOTModule *
  3698. create_module(char *name, char *error_buf, uint32 error_buf_size)
  3699. {
  3700. AOTModule *module =
  3701. loader_malloc(sizeof(AOTModule), error_buf, error_buf_size);
  3702. bh_list_status ret;
  3703. if (!module) {
  3704. return NULL;
  3705. }
  3706. module->module_type = Wasm_Module_AoT;
  3707. module->name = name;
  3708. module->is_binary_freeable = false;
  3709. #if WASM_ENABLE_MULTI_MODULE != 0
  3710. module->import_module_list = &module->import_module_list_head;
  3711. ret = bh_list_init(module->import_module_list);
  3712. bh_assert(ret == BH_LIST_SUCCESS);
  3713. #endif
  3714. (void)ret;
  3715. #if WASM_ENABLE_GC != 0
  3716. if (!(module->ref_type_set =
  3717. wasm_reftype_set_create(GC_REFTYPE_MAP_SIZE_DEFAULT))) {
  3718. set_error_buf(error_buf, error_buf_size, "create reftype map failed");
  3719. goto fail1;
  3720. }
  3721. if (os_mutex_init(&module->rtt_type_lock)) {
  3722. set_error_buf(error_buf, error_buf_size, "init rtt type lock failed");
  3723. goto fail2;
  3724. }
  3725. #endif
  3726. #if WASM_ENABLE_LIBC_WASI != 0
  3727. wasi_args_set_defaults(&module->wasi_args);
  3728. #endif /* WASM_ENABLE_LIBC_WASI != 0 */
  3729. return module;
  3730. #if WASM_ENABLE_GC != 0
  3731. fail2:
  3732. bh_hash_map_destroy(module->ref_type_set);
  3733. fail1:
  3734. #endif
  3735. wasm_runtime_free(module);
  3736. return NULL;
  3737. }
  3738. AOTModule *
  3739. aot_load_from_sections(AOTSection *section_list, char *error_buf,
  3740. uint32 error_buf_size)
  3741. {
  3742. AOTModule *module = create_module("", error_buf, error_buf_size);
  3743. if (!module)
  3744. return NULL;
  3745. if (!load_from_sections(module, section_list, false, false, error_buf,
  3746. error_buf_size)) {
  3747. aot_unload(module);
  3748. return NULL;
  3749. }
  3750. LOG_VERBOSE("Load module from sections success.\n");
  3751. return module;
  3752. }
  3753. static void
  3754. destroy_sections(AOTSection *section_list, bool destroy_aot_text)
  3755. {
  3756. AOTSection *section = section_list, *next;
  3757. while (section) {
  3758. next = section->next;
  3759. if (destroy_aot_text && section->section_type == AOT_SECTION_TYPE_TEXT
  3760. && section->section_body)
  3761. os_munmap((uint8 *)section->section_body,
  3762. section->section_body_size);
  3763. wasm_runtime_free(section);
  3764. section = next;
  3765. }
  3766. }
  3767. static bool
  3768. resolve_execute_mode(const uint8 *buf, uint32 size, bool *p_mode,
  3769. char *error_buf, uint32 error_buf_size)
  3770. {
  3771. const uint8 *p = buf, *p_end = buf + size;
  3772. uint32 section_type;
  3773. uint32 section_size = 0;
  3774. uint16 e_type = 0;
  3775. p += 8;
  3776. while (p < p_end) {
  3777. read_uint32(p, p_end, section_type);
  3778. if (section_type <= AOT_SECTION_TYPE_SIGNATURE) {
  3779. read_uint32(p, p_end, section_size);
  3780. CHECK_BUF(p, p_end, section_size);
  3781. if (section_type == AOT_SECTION_TYPE_TARGET_INFO) {
  3782. p += 4;
  3783. read_uint16(p, p_end, e_type);
  3784. if (e_type == E_TYPE_XIP) {
  3785. *p_mode = true;
  3786. }
  3787. else {
  3788. *p_mode = false;
  3789. }
  3790. break;
  3791. }
  3792. }
  3793. else { /* section_type > AOT_SECTION_TYPE_SIGNATURE */
  3794. set_error_buf(error_buf, error_buf_size,
  3795. "resolve execute mode failed");
  3796. break;
  3797. }
  3798. p += section_size;
  3799. }
  3800. return true;
  3801. fail:
  3802. return false;
  3803. }
  3804. static bool
  3805. create_sections(AOTModule *module, const uint8 *buf, uint32 size,
  3806. AOTSection **p_section_list, char *error_buf,
  3807. uint32 error_buf_size)
  3808. {
  3809. AOTSection *section_list = NULL, *section_list_end = NULL, *section;
  3810. const uint8 *p = buf, *p_end = buf + size;
  3811. bool destroy_aot_text = false;
  3812. bool is_indirect_mode = false;
  3813. uint32 section_type;
  3814. uint32 section_size;
  3815. uint64 total_size;
  3816. uint8 *aot_text;
  3817. #if (WASM_MEM_DUAL_BUS_MIRROR != 0)
  3818. uint8 *mirrored_text;
  3819. #endif
  3820. if (!resolve_execute_mode(buf, size, &is_indirect_mode, error_buf,
  3821. error_buf_size)) {
  3822. goto fail;
  3823. }
  3824. module->is_indirect_mode = is_indirect_mode;
  3825. p += 8;
  3826. while (p < p_end) {
  3827. read_uint32(p, p_end, section_type);
  3828. if (section_type < AOT_SECTION_TYPE_SIGNATURE
  3829. || section_type == AOT_SECTION_TYPE_CUSTOM) {
  3830. read_uint32(p, p_end, section_size);
  3831. CHECK_BUF(p, p_end, section_size);
  3832. if (!(section = loader_malloc(sizeof(AOTSection), error_buf,
  3833. error_buf_size))) {
  3834. goto fail;
  3835. }
  3836. memset(section, 0, sizeof(AOTSection));
  3837. section->section_type = (int32)section_type;
  3838. section->section_body = (uint8 *)p;
  3839. section->section_body_size = section_size;
  3840. if (section_type == AOT_SECTION_TYPE_TEXT) {
  3841. if ((section_size > 0) && !module->is_indirect_mode) {
  3842. total_size =
  3843. (uint64)section_size + aot_get_plt_table_size();
  3844. total_size = (total_size + 3) & ~((uint64)3);
  3845. if (total_size >= UINT32_MAX
  3846. || !(aot_text =
  3847. loader_mmap((uint32)total_size, true,
  3848. error_buf, error_buf_size))) {
  3849. wasm_runtime_free(section);
  3850. goto fail;
  3851. }
  3852. #if (WASM_MEM_DUAL_BUS_MIRROR != 0)
  3853. mirrored_text = os_get_dbus_mirror(aot_text);
  3854. bh_assert(mirrored_text != NULL);
  3855. bh_memcpy_s(mirrored_text, (uint32)total_size,
  3856. section->section_body, (uint32)section_size);
  3857. os_dcache_flush();
  3858. #else
  3859. bh_memcpy_s(aot_text, (uint32)total_size,
  3860. section->section_body, (uint32)section_size);
  3861. #endif
  3862. section->section_body = aot_text;
  3863. destroy_aot_text = true;
  3864. if ((uint32)total_size > section->section_body_size) {
  3865. memset(aot_text + (uint32)section_size, 0,
  3866. (uint32)total_size - section_size);
  3867. section->section_body_size = (uint32)total_size;
  3868. }
  3869. }
  3870. }
  3871. if (!section_list)
  3872. section_list = section_list_end = section;
  3873. else {
  3874. section_list_end->next = section;
  3875. section_list_end = section;
  3876. }
  3877. p += section_size;
  3878. }
  3879. else {
  3880. set_error_buf(error_buf, error_buf_size, "invalid section id");
  3881. goto fail;
  3882. }
  3883. }
  3884. if (!section_list) {
  3885. set_error_buf(error_buf, error_buf_size, "create section list failed");
  3886. return false;
  3887. }
  3888. *p_section_list = section_list;
  3889. return true;
  3890. fail:
  3891. if (section_list)
  3892. destroy_sections(section_list, destroy_aot_text);
  3893. return false;
  3894. }
  3895. static bool
  3896. aot_compatible_version(uint32 version)
  3897. {
  3898. /*
  3899. * refer to "AoT-compiled module compatibility among WAMR versions" in
  3900. * ./doc/biuld_wasm_app.md
  3901. */
  3902. return version == AOT_CURRENT_VERSION;
  3903. }
  3904. static bool
  3905. load(const uint8 *buf, uint32 size, AOTModule *module,
  3906. bool wasm_binary_freeable, bool no_resolve, char *error_buf,
  3907. uint32 error_buf_size)
  3908. {
  3909. const uint8 *buf_end = buf + size;
  3910. const uint8 *p = buf, *p_end = buf_end;
  3911. uint32 magic_number, version;
  3912. AOTSection *section_list = NULL;
  3913. bool ret;
  3914. read_uint32(p, p_end, magic_number);
  3915. if (magic_number != AOT_MAGIC_NUMBER) {
  3916. set_error_buf(error_buf, error_buf_size, "magic header not detected");
  3917. return false;
  3918. }
  3919. read_uint32(p, p_end, version);
  3920. if (!aot_compatible_version(version)) {
  3921. set_error_buf(error_buf, error_buf_size, "unknown binary version");
  3922. return false;
  3923. }
  3924. module->package_version = version;
  3925. if (!create_sections(module, buf, size, &section_list, error_buf,
  3926. error_buf_size))
  3927. return false;
  3928. ret = load_from_sections(module, section_list, !wasm_binary_freeable,
  3929. no_resolve, error_buf, error_buf_size);
  3930. if (!ret) {
  3931. /* If load_from_sections() fails, then aot text is destroyed
  3932. in destroy_sections() */
  3933. destroy_sections(section_list,
  3934. module->is_indirect_mode
  3935. || module->merged_data_text_sections
  3936. ? false
  3937. : true);
  3938. /* aot_unload() won't destroy aot text again */
  3939. module->code = NULL;
  3940. }
  3941. else {
  3942. /* If load_from_sections() succeeds, then aot text is set to
  3943. module->code and will be destroyed in aot_unload() */
  3944. destroy_sections(section_list, false);
  3945. }
  3946. #if 0
  3947. {
  3948. uint32 i;
  3949. for (i = 0; i < module->func_count; i++) {
  3950. LOG_VERBOSE("AOT func %u, addr: %p\n", i, module->func_ptrs[i]);
  3951. }
  3952. }
  3953. #endif
  3954. #if WASM_ENABLE_LINUX_PERF != 0
  3955. if (wasm_runtime_get_linux_perf())
  3956. if (!aot_create_perf_map(module, error_buf, error_buf_size))
  3957. goto fail;
  3958. #endif
  3959. return ret;
  3960. fail:
  3961. return false;
  3962. }
  3963. AOTModule *
  3964. aot_load_from_aot_file(const uint8 *buf, uint32 size, const LoadArgs *args,
  3965. char *error_buf, uint32 error_buf_size)
  3966. {
  3967. AOTModule *module = create_module(args->name, error_buf, error_buf_size);
  3968. if (!module)
  3969. return NULL;
  3970. os_thread_jit_write_protect_np(false); /* Make memory writable */
  3971. if (!load(buf, size, module, args->wasm_binary_freeable, args->no_resolve,
  3972. error_buf, error_buf_size)) {
  3973. aot_unload(module);
  3974. return NULL;
  3975. }
  3976. os_thread_jit_write_protect_np(true); /* Make memory executable */
  3977. os_icache_flush(module->code, module->code_size);
  3978. #if WASM_ENABLE_AOT_VALIDATOR != 0
  3979. if (!aot_module_validate(module, error_buf, error_buf_size)) {
  3980. aot_unload(module);
  3981. return NULL;
  3982. }
  3983. #endif /* WASM_ENABLE_AOT_VALIDATOR != 0 */
  3984. LOG_VERBOSE("Load module success.\n");
  3985. return module;
  3986. }
  3987. void
  3988. aot_unload(AOTModule *module)
  3989. {
  3990. if (module->import_memories)
  3991. destroy_import_memories(module->import_memories);
  3992. if (module->memories)
  3993. wasm_runtime_free(module->memories);
  3994. if (module->mem_init_data_list)
  3995. destroy_mem_init_data_list(module, module->mem_init_data_list,
  3996. module->mem_init_data_count);
  3997. if (module->native_symbol_list)
  3998. wasm_runtime_free(module->native_symbol_list);
  3999. if (module->import_tables)
  4000. destroy_import_tables(module->import_tables);
  4001. if (module->tables) {
  4002. #if WASM_ENABLE_GC != 0
  4003. uint32 i;
  4004. for (i = 0; i < module->table_count; i++) {
  4005. destroy_init_expr(&module->tables[i].init_expr);
  4006. }
  4007. #endif
  4008. destroy_tables(module->tables);
  4009. }
  4010. if (module->table_init_data_list)
  4011. destroy_table_init_data_list(module->table_init_data_list,
  4012. module->table_init_data_count);
  4013. if (module->types)
  4014. destroy_types(module->types, module->type_count);
  4015. if (module->import_globals)
  4016. destroy_import_globals(module->import_globals);
  4017. if (module->globals) {
  4018. #if WASM_ENABLE_GC != 0 || WASM_ENABLE_EXTENDED_CONST_EXPR != 0
  4019. uint32 i;
  4020. for (i = 0; i < module->global_count; i++) {
  4021. destroy_init_expr(&module->globals[i].init_expr);
  4022. }
  4023. #endif
  4024. destroy_globals(module->globals);
  4025. }
  4026. if (module->import_funcs)
  4027. destroy_import_funcs(module->import_funcs);
  4028. if (module->exports)
  4029. destroy_exports(module->exports);
  4030. if (module->func_type_indexes)
  4031. wasm_runtime_free(module->func_type_indexes);
  4032. #if WASM_ENABLE_AOT_STACK_FRAME != 0
  4033. if (module->max_local_cell_nums)
  4034. wasm_runtime_free(module->max_local_cell_nums);
  4035. if (module->max_stack_cell_nums)
  4036. wasm_runtime_free(module->max_stack_cell_nums);
  4037. #endif
  4038. #if WASM_ENABLE_GC != 0
  4039. if (module->func_local_ref_flags) {
  4040. uint32 i;
  4041. for (i = 0; i < module->import_func_count + module->func_count; i++) {
  4042. if (module->func_local_ref_flags[i].local_ref_flags) {
  4043. wasm_runtime_free(
  4044. module->func_local_ref_flags[i].local_ref_flags);
  4045. }
  4046. }
  4047. wasm_runtime_free(module->func_local_ref_flags);
  4048. }
  4049. #endif
  4050. if (module->func_ptrs)
  4051. wasm_runtime_free(module->func_ptrs);
  4052. if (module->const_str_set)
  4053. bh_hash_map_destroy(module->const_str_set);
  4054. #if WASM_ENABLE_MULTI_MODULE != 0
  4055. /* just release the sub module list */
  4056. if (module->import_module_list) {
  4057. WASMRegisteredModule *node =
  4058. bh_list_first_elem(module->import_module_list);
  4059. while (node) {
  4060. WASMRegisteredModule *next = bh_list_elem_next(node);
  4061. bh_list_remove(module->import_module_list, node);
  4062. wasm_runtime_free(node);
  4063. node = next;
  4064. }
  4065. }
  4066. #endif
  4067. if (module->code && !module->is_indirect_mode
  4068. && !module->merged_data_text_sections) {
  4069. /* The layout is: literal size + literal + code (with plt table) */
  4070. uint8 *mmap_addr = module->literal - sizeof(uint32);
  4071. uint32 total_size =
  4072. sizeof(uint32) + module->literal_size + module->code_size;
  4073. os_munmap(mmap_addr, total_size);
  4074. }
  4075. #if defined(BH_PLATFORM_WINDOWS)
  4076. if (module->extra_plt_data) {
  4077. os_munmap(module->extra_plt_data, module->extra_plt_data_size);
  4078. }
  4079. #endif
  4080. #if (defined(BUILD_TARGET_X86_64) || defined(BUILD_TARGET_AMD_64)) \
  4081. && !defined(BH_PLATFORM_WINDOWS)
  4082. {
  4083. GOTItem *got_item = module->got_item_list, *got_item_next;
  4084. if (module->got_func_ptrs) {
  4085. os_munmap(module->got_func_ptrs,
  4086. sizeof(void *) * module->got_item_count);
  4087. }
  4088. while (got_item) {
  4089. got_item_next = got_item->next;
  4090. wasm_runtime_free(got_item);
  4091. got_item = got_item_next;
  4092. }
  4093. }
  4094. #endif
  4095. if (module->data_sections)
  4096. destroy_object_data_sections(module->data_sections,
  4097. module->data_section_count);
  4098. if (module->merged_data_sections)
  4099. os_munmap(module->merged_data_sections,
  4100. module->merged_data_sections_size);
  4101. if (module->merged_data_text_sections)
  4102. os_munmap(module->merged_data_text_sections,
  4103. module->merged_data_text_sections_size);
  4104. #if WASM_ENABLE_DEBUG_AOT != 0
  4105. jit_code_entry_destroy(module->elf_hdr);
  4106. #endif
  4107. #if WASM_ENABLE_CUSTOM_NAME_SECTION != 0
  4108. if (module->aux_func_indexes) {
  4109. wasm_runtime_free(module->aux_func_indexes);
  4110. }
  4111. if (module->aux_func_names) {
  4112. wasm_runtime_free((void *)module->aux_func_names);
  4113. }
  4114. #endif
  4115. #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
  4116. wasm_runtime_destroy_custom_sections(module->custom_section_list);
  4117. #endif
  4118. #if WASM_ENABLE_GC != 0
  4119. if (module->ref_type_set) {
  4120. bh_hash_map_destroy(module->ref_type_set);
  4121. }
  4122. os_mutex_destroy(&module->rtt_type_lock);
  4123. if (module->rtt_types) {
  4124. uint32 i;
  4125. for (i = 0; i < module->type_count; i++) {
  4126. if (module->rtt_types[i])
  4127. wasm_runtime_free(module->rtt_types[i]);
  4128. }
  4129. wasm_runtime_free(module->rtt_types);
  4130. }
  4131. #if WASM_ENABLE_STRINGREF != 0
  4132. {
  4133. uint32 i;
  4134. for (i = 0; i < WASM_TYPE_STRINGVIEWITER - WASM_TYPE_STRINGREF + 1;
  4135. i++) {
  4136. if (module->stringref_rtts[i])
  4137. wasm_runtime_free(module->stringref_rtts[i]);
  4138. }
  4139. if (module->string_literal_lengths) {
  4140. wasm_runtime_free(module->string_literal_lengths);
  4141. }
  4142. if (module->string_literal_ptrs) {
  4143. wasm_runtime_free((void *)module->string_literal_ptrs);
  4144. }
  4145. }
  4146. #endif
  4147. #endif
  4148. wasm_runtime_free(module);
  4149. }
  4150. uint32
  4151. aot_get_plt_table_size(void)
  4152. {
  4153. return get_plt_table_size();
  4154. }
  4155. #if WASM_ENABLE_LOAD_CUSTOM_SECTION != 0
  4156. const uint8 *
  4157. aot_get_custom_section(const AOTModule *module, const char *name, uint32 *len)
  4158. {
  4159. WASMCustomSection *section = module->custom_section_list;
  4160. while (section) {
  4161. if (strcmp(section->name_addr, name) == 0) {
  4162. if (len) {
  4163. *len = section->content_len;
  4164. }
  4165. return section->content_addr;
  4166. }
  4167. section = section->next;
  4168. }
  4169. return NULL;
  4170. }
  4171. #endif /* end of WASM_ENABLE_LOAD_CUSTOM_SECTION */
  4172. #if WASM_ENABLE_STATIC_PGO != 0
  4173. void
  4174. aot_exchange_uint16(uint8 *p_data)
  4175. {
  4176. return exchange_uint16(p_data);
  4177. }
  4178. void
  4179. aot_exchange_uint32(uint8 *p_data)
  4180. {
  4181. return exchange_uint32(p_data);
  4182. }
  4183. void
  4184. aot_exchange_uint64(uint8 *p_data)
  4185. {
  4186. return exchange_uint64(p_data);
  4187. }
  4188. #endif